Esempio n. 1
0
    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 parameters.get('destination'):
            dest_dir = parameters['destination']
            download_config.set_dest_dir(dest_dir)

        if 'selected_files' in parameters:
            download_config.set_selected_files(parameters['selected_files'])

        return download_config, None
Esempio n. 2
0
 async def test_remove_with_files(self):
     """
     Testing whether the API returns 200 if a download is being removed
     """
     # Create a copy of the file, so we can remove it later
     source_file = TESTS_DATA_DIR / 'video.avi'
     tmpdir = self.temporary_directory()
     copied_file = tmpdir / Path(source_file).name
     shutil.copyfile(source_file, copied_file)
     video_tdef, _ = self.create_local_torrent(copied_file)
     dcfg = DownloadConfig()
     dcfg.set_dest_dir(tmpdir)
     download = self.session.dlmgr.start_download(tdef=video_tdef,
                                                  config=dcfg)
     infohash = get_hex_infohash(video_tdef)
     while not download.handle:
         await sleep(0.1)
     await sleep(2)
     await self.do_request('downloads/%s' % infohash,
                           post_data={"remove_data": True},
                           expected_code=200,
                           request_type='DELETE',
                           expected_json={
                               u"removed":
                               True,
                               u"infohash":
                               u"c9a19e7fe5d9a6c106d6ea3c01746ac88ca3c7a5"
                           })
     while copied_file.exists():
         await sleep(0.1)
     self.assertEqual(len(self.session.dlmgr.get_downloads()), 0)
     self.assertFalse(copied_file.exists())
Esempio n. 3
0
async def channel_seeder_session(seed_config, channel_tdef):
    seeder_session = Session(seed_config)
    seeder_session.upgrader_enabled = False
    await seeder_session.start()
    dscfg_seed = DownloadConfig()
    dscfg_seed.set_dest_dir(TESTS_DATA_DIR / 'sample_channel')
    upload = seeder_session.dlmgr.start_download(tdef=channel_tdef,
                                                 config=dscfg_seed)
    await upload.wait_for_status(DLSTATUS_SEEDING)
    yield seeder_session
    await seeder_session.shutdown()
Esempio n. 4
0
    def test_user_stopped(self):
        dlcfg = DownloadConfig()
        dlcfg.set_user_stopped(False)
        self.assertFalse(dlcfg.get_user_stopped())

        dlcfg.set_user_stopped(True)
        self.assertTrue(dlcfg.get_user_stopped())
Esempio n. 5
0
    def check_watch_folder(self):
        if not self.session.config.get_watch_folder_path().is_dir():
            return

        # Make sure that we pass a str to os.walk
        watch_dir = str(self.session.config.get_watch_folder_path())

        for root, _, files in os.walk(watch_dir):
            root = path_util.Path(root)
            for name in files:
                if not name.endswith(".torrent"):
                    continue

                try:
                    tdef = TorrentDef.load(root / name)
                    if not tdef.get_metainfo():
                        self.cleanup_torrent_file(root, name)
                        continue
                except:  # torrent appears to be corrupt
                    self.cleanup_torrent_file(root, name)
                    continue

                infohash = tdef.get_infohash()

                if not self.session.dlmgr.download_exists(infohash):
                    self._logger.info("Starting download from torrent file %s", name)
                    dl_config = DownloadConfig()

                    anon_enabled = self.session.config.get_default_anonymity_enabled()
                    default_num_hops = self.session.config.get_default_number_hops()
                    dl_config.set_hops(default_num_hops if anon_enabled else 0)
                    dl_config.set_safe_seeding(self.session.config.get_default_safeseeding_enabled())
                    dl_config.set_dest_dir(self.session.config.get_default_destination_dir())
                    self.session.dlmgr.start_download(tdef=tdef, config=dl_config)
Esempio n. 6
0
async def test_set_rate_settings(enable_api, mock_dlmgr, session):
    """
    Testing whether libtorrent rate limits works for large number without overflow error.
    """

    dcfg = DownloadConfig()
    download = Mock()
    download.config = dcfg
    session.dlmgr.get_downloads = lambda: [download]

    extra_rate = 1024 * 1024 * 1024  # 1GB/s
    post_data = {
        'libtorrent': {
            'max_download_rate': MAX_LIBTORRENT_RATE_LIMIT + extra_rate,
            'max_upload_rate': MAX_LIBTORRENT_RATE_LIMIT + extra_rate
        }
    }
    await do_request(session,
                     'settings',
                     expected_code=200,
                     request_type='POST',
                     post_data=post_data)

    assert session.config.get_libtorrent_max_download_rate(
    ) == MAX_LIBTORRENT_RATE_LIMIT
    assert session.config.get_libtorrent_max_upload_rate(
    ) == MAX_LIBTORRENT_RATE_LIMIT
Esempio n. 7
0
def convert_config_to_tribler75(state_dir):
    """
    Convert the download config files from Tribler 7.4 to 7.5 format.
    """
    for filename in (state_dir / STATEDIR_CHECKPOINT_DIR).glob('*.conf'):
        try:
            config = DownloadConfig.load(filename)

            # Convert resume data
            resumedata = config.get_engineresumedata()
            if b'mapped_files' in resumedata:
                resumedata.pop(b'mapped_files')
                config.set_engineresumedata(resumedata)
                config.write(str(filename))

            # Convert metainfo
            metainfo = config.get_metainfo()
            if not config.config['download_defaults'].get(
                    'selected_files') or not metainfo:
                continue  # no conversion needed/possible, selected files will be reset to their default (i.e., all files)
            tdef = TorrentDef.load_from_dict(metainfo)
            config.set_selected_files([
                tdef.get_index_of_file_in_files(fn) for fn in
                config.config['download_defaults'].pop('selected_files')
            ])
            config.write(str(filename))
        except ConfigObjParseError:
            logger.error("Could not parse %s file so removing it", filename)
            os.remove(filename)
Esempio n. 8
0
    async def setUp(self):
        await TriblerCoreTest.setUp(self)
        self.download = Download(Mock(), None)
        mock_handle = MockObject()
        mock_status = MockObject()
        mock_status.pieces = [True, False, True, True, False]
        torrent_info = MockObject()
        file_info = MockObject()
        file_info.size = 1234
        torrent_info.file_at = lambda _: file_info
        map_file_result = MockObject()
        map_file_result.piece = 123
        torrent_info.map_file = lambda _dummy1, _dummy2, _dummy3: map_file_result
        torrent_info.num_pieces = lambda: 5

        mock_handle.is_valid = lambda: True
        mock_handle.status = lambda: mock_status
        mock_handle.get_torrent_info = lambda: torrent_info
        mock_handle.set_sequential_download = lambda _: None
        mock_handle.set_priority = lambda _: None
        mock_handle.prioritize_pieces = lambda _: None
        mock_handle.save_resume_data = lambda: None

        self.download.handle = mock_handle

        # Create a fake tdef
        self.download.tdef = MockObject()
        self.download.tdef.get_name = lambda: "ubuntu.iso"
        self.download.tdef.get_name_as_unicode = lambda: "ubuntu.iso"
        self.download.tdef.get_infohash = lambda: b'a' * 20
        self.download.tdef.is_multifile_torrent = lambda: False

        self.download.config = DownloadConfig()
Esempio n. 9
0
async def test_seeding(enable_libtorrent, video_seeder_session, video_tdef,
                       session, tmpdir):
    """
    Test whether a torrent is correctly seeded
    """
    dscfg = DownloadConfig()
    dscfg.set_dest_dir(tmpdir)
    download = session.dlmgr.start_download(tdef=video_tdef, config=dscfg)
    download.add_peer(
        ("127.0.0.1", video_seeder_session.config.get_libtorrent_port()))
    await download.wait_for_status(DLSTATUS_SEEDING)

    with open(tmpdir / "video.avi", "rb") as f:
        realdata = f.read()
    with open(TESTS_DATA_DIR / 'video.avi', "rb") as f:
        expdata = f.read()

    assert realdata == expdata
Esempio n. 10
0
    def start_download(self,
                       torrent_file=None,
                       tdef=None,
                       config=None,
                       checkpoint_disabled=False,
                       hidden=False):
        self._logger.debug("Starting download: filename: %s, torrent def: %s",
                           torrent_file, tdef)

        # the priority of the parameters is: (1) tdef, (2) torrent_file.
        # so if we have tdef, and torrent_file will be ignored, and so on.
        if tdef is None:
            if torrent_file is None:
                raise ValueError(
                    "Torrent file must be provided if tdef is not given")
            # try to get the torrent from the given torrent file
            tdef = TorrentDef.load(torrent_file)

        assert tdef is not None, "tdef MUST not be None after loading torrent"

        config = config or DownloadConfig()
        infohash = tdef.get_infohash()
        download = self.get_download(infohash)

        if download and infohash not in self.metainfo_requests:
            new_trackers = list(
                set(tdef.get_trackers_as_single_tuple()) -
                set(download.get_def().get_trackers_as_single_tuple()))
            if new_trackers:
                self.update_trackers(tdef.get_infohash(), new_trackers)
            return download

        # Create the destination directory if it does not exist yet
        try:
            if not config.get_dest_dir().is_dir():
                os.makedirs(config.get_dest_dir())
        except OSError:
            self._logger.error(
                "Unable to create the download destination directory.")

        if config.get_time_added() == 0:
            config.set_time_added(int(timemod.time()))

        # Create the download
        download = Download(self.tribler_session, tdef, dummy=self.dummy_mode)
        atp = download.setup(config,
                             checkpoint_disabled=checkpoint_disabled,
                             hidden=hidden or config.get_bootstrap_download())
        # Keep metainfo downloads in self.downloads for now because we will need to remove it later,
        # and removing the download at this point will stop us from receiving any further alerts.
        if infohash not in self.metainfo_requests or self.metainfo_requests[
                infohash][0] == download:
            self.downloads[infohash] = download
        if not self.dummy_mode:
            self.start_handle(download, atp)
        return download
Esempio n. 11
0
    async def add_torrent(self, piece_length=1024):
        [srchandle, sourcefn] = mkstemp(dir=TESTS_DIR)
        data = b''.join([i.to_bytes(2, byteorder='big') for i in range(1000)])
        os.write(srchandle, data)
        os.close(srchandle)

        tdef = TorrentDef()
        tdef.add_content(sourcefn)
        tdef.set_piece_length(piece_length)
        torrentfn = self.session.config.get_state_dir() / "gen.torrent"
        tdef.save(torrentfn)

        dscfg = DownloadConfig()
        destdir = Path(sourcefn).parent
        dscfg.set_dest_dir(destdir)

        download = self.session.dlmgr.start_download(tdef=tdef, config=dscfg)
        await download.wait_for_status(DLSTATUS_SEEDING)
        return tdef.get_infohash(), data
Esempio n. 12
0
    def load_checkpoint(self, filename):
        try:
            config = DownloadConfig.load(filename)
        except Exception:
            self._logger.exception("Could not open checkpoint file %s",
                                   filename)
            return

        metainfo = config.get_metainfo()
        if not metainfo:
            self._logger.error(
                "Could not resume checkpoint %s; metainfo not found", filename)
            return
        if not isinstance(metainfo, dict):
            self._logger.error(
                "Could not resume checkpoint %s; metainfo is not dict %s %s",
                filename, type(metainfo), repr(metainfo))
            return

        try:
            url = metainfo.get(b'url', None)
            url = url.decode('utf-8') if url else url
            tdef = (TorrentDefNoMetainfo(metainfo[b'infohash'],
                                         metainfo[b'name'], url) if b'infohash'
                    in metainfo else TorrentDef.load_from_dict(metainfo))
        except (KeyError, ValueError) as e:
            self._logger.exception(
                "Could not restore tdef from metainfo dict: %s %s ", e,
                metainfo)
            return

        if config.get_bootstrap_download():
            if hexlify(tdef.get_infohash(
            )) != self.tribler_session.config.get_bootstrap_infohash():
                self.remove_config(tdef.get_infohash())
                return

        config.state_dir = self.tribler_session.config.get_state_dir()
        if config.get_dest_dir() == '':  # removed torrent ignoring
            self._logger.info("Removing checkpoint %s destdir is %s", filename,
                              config.get_dest_dir())
            os.remove(filename)
            return

        try:
            if self.download_exists(tdef.get_infohash()):
                self._logger.info(
                    "Not resuming checkpoint because download has already been added"
                )
            else:
                self.start_download(tdef=tdef, config=config)
        except Exception:
            self._logger.exception(
                "Not resume checkpoint due to exception while adding download")
Esempio n. 13
0
    async def add_torrent(self):
        [srchandle, sourcefn] = mkstemp(dir=TESTS_DIR)
        self.data = b'\xFF' * self.size  # pylint: disable=attribute-defined-outside-init
        os.write(srchandle, self.data)
        os.close(srchandle)

        tdef = TorrentDef()
        tdef.add_content(sourcefn)
        tdef.set_piece_length(self.piece_len)
        torrentfn = self.session.config.get_state_dir() / "gen.torrent"
        tdef.save(torrentfn)

        dscfg = DownloadConfig()
        destdir = Path(sourcefn).parent
        dscfg.set_dest_dir(destdir)

        self.download = self.session.dlmgr.start_download(tdef=tdef,
                                                          config=dscfg)  # pylint: disable=attribute-defined-outside-init
        await self.download.wait_for_status(DLSTATUS_SEEDING)
        self.infohash = tdef.get_infohash()  # pylint: disable=attribute-defined-outside-init
Esempio n. 14
0
    def setup(self, config=None, hidden=False, checkpoint_disabled=False):
        """
        Create a Download object. Used internally by Session.
        @param config DownloadConfig or None (in which case a new DownloadConfig() is created
        :returns a Deferred to which a callback can be added which returns the result of network_create_engine_wrapper.
        """
        self.hidden = hidden
        self.checkpoint_disabled = checkpoint_disabled or self.dummy
        self.config = config or DownloadConfig(
            state_dir=self.session.config.get_state_dir())

        self._logger.debug("Setup: %s", hexlify(self.tdef.get_infohash()))

        self.checkpoint()

        atp = {
            "save_path":
            path_util.normpath(get_default_dest_dir() /
                               self.config.get_dest_dir()),
            "storage_mode":
            lt.storage_mode_t.storage_mode_sparse,
            "flags":
            lt.add_torrent_params_flags_t.flag_paused
            | lt.add_torrent_params_flags_t.flag_duplicate_is_error
            | lt.add_torrent_params_flags_t.flag_update_subscribe
        }

        if self.config.get_share_mode():
            atp["flags"] = atp[
                "flags"] | lt.add_torrent_params_flags_t.flag_share_mode
        if self.config.get_upload_mode():
            atp["flags"] = atp[
                "flags"] | lt.add_torrent_params_flags_t.flag_upload_mode

        resume_data = self.config.get_engineresumedata()
        if not isinstance(self.tdef, TorrentDefNoMetainfo):
            metainfo = self.tdef.get_metainfo()
            torrentinfo = lt.torrent_info(metainfo)

            atp["ti"] = torrentinfo
            if resume_data and isinstance(resume_data, dict):
                # Rewrite save_path as a global path, if it is given as a relative path
                if b"save_path" in resume_data and not path_util.isabs(
                        ensure_unicode(resume_data[b"save_path"], 'utf8')):
                    resume_data[
                        b"save_path"] = self.state_dir / ensure_unicode(
                            resume_data[b"save_path"], 'utf8')
                atp["resume_data"] = lt.bencode(resume_data)
        else:
            atp["url"] = self.tdef.get_url(
            ) or "magnet:?xt=urn:btih:" + hexlify(self.tdef.get_infohash())
            atp["name"] = self.tdef.get_name_as_unicode()

        return atp
Esempio n. 15
0
    async def setup_tunnel_seeder(self, hops):
        """
        Setup the seeder.
        """
        from tribler_core.session import Session
        self.seed_config = self.config.copy()
        self.seed_config._state_dir = self.getRootStateDir(2)
        self.seed_config.set_libtorrent_enabled(hops == 0)
        self.seed_config.set_tunnel_community_socks5_listen_ports(
            self.get_ports(5))
        if self.session2 is None:
            self.session2 = Session(self.seed_config)
            self.session2.upgrader_enabled = False
            await self.session2.start()

        tdef = TorrentDef()
        tdef.add_content(TESTS_DATA_DIR / "video.avi")
        tdef.set_tracker("http://localhost/announce")
        torrentfn = 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 = await self.load_tunnel_community_in_session(
                self.session2, start_lt=True)
            self.tunnel_community_seeder.build_tunnels(hops)
        else:
            await self.sanitize_network(self.session2)

        dscfg = DownloadConfig()
        dscfg.set_dest_dir(
            TESTS_DATA_DIR)  # basedir of the file we are seeding
        dscfg.set_hops(hops)
        d = self.session2.dlmgr.start_download(tdef=tdef, config=dscfg)
        d.set_state_callback(self.seeder_state_callback)
Esempio n. 16
0
async def hidden_seeder_session(seed_config, video_tdef):
    seed_config.set_libtorrent_enabled(False)
    seeder_session = Session(seed_config)
    seeder_session.upgrader_enabled = False
    await seeder_session.start()

    # Also load the tunnel community in the seeder session
    await load_tunnel_community_in_session(seeder_session, start_lt=True)
    seeder_session.tunnel_community.build_tunnels(1)

    dscfg_seed = DownloadConfig()
    dscfg_seed.set_dest_dir(TESTS_DATA_DIR)
    dscfg_seed.set_hops(1)
    upload = seeder_session.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.
        """
        seeder_session.tunnel_community.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)
    yield seeder_session
    await seeder_session.shutdown()
Esempio n. 17
0
    def __init__(self, config_dir, dht=None):
        super(Bootstrap, self).__init__()

        self._logger = logging.getLogger(self.__class__.__name__)
        self.dcfg = DownloadConfig(state_dir=config_dir)
        self.dcfg.set_bootstrap_download(True)
        self.bootstrap_dir = config_dir / 'bootstrap'
        if not self.bootstrap_dir.exists():
            os.mkdir(self.bootstrap_dir)
        self.dcfg.set_dest_dir(self.bootstrap_dir)
        self.dcfg.set_safe_seeding(True)
        self.bootstrap_file = self.bootstrap_dir / "bootstrap.blocks"
        self.dht = dht

        self.bootstrap_finished = False
        self.infohash = None
        self.download = None
        self.bootstrap_nodes = {}

        self.register_task('fetch_bootstrap_peers',
                           self.fetch_bootstrap_peers,
                           interval=5)
Esempio n. 18
0
    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(self.tribler_session.config.get_default_number_hops() if hops is None else 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)

        return metainfo
Esempio n. 19
0
    async def test_multifile_torrent(self):
        # Achtung! This test is completely and utterly broken, as is the whole libtorrent wrapper!
        # Don't try to understand it, it is a legacy thing!

        tdef = TorrentDef()

        tdef.add_content(TESTS_DATA_DIR / "video.avi")
        tdef.set_tracker("http://tribler.org/announce")
        tdef.save()

        fake_handler = MockObject()
        fake_handler.is_valid = lambda: True
        fake_handler.status = lambda: fake_status
        fake_handler.set_share_mode = lambda _: None
        fake_handler.set_priority = lambda _: None
        fake_handler.set_sequential_download = lambda _: None
        fake_handler.resume = lambda: None
        fake_handler.set_max_connections = lambda _: None
        fake_handler.apply_ip_filter = lambda _: None
        fake_handler.save_resume_data = lambda: None
        fake_status = MockObject()
        fake_status.share_mode = False
        dl = Download(self.session, tdef)
        dl.set_selected_files = lambda: None
        dl.future_added = succeed(fake_handler)
        # Create a dummy download config
        dl.config = DownloadConfig()
        dl.config.set_engineresumedata({
            b"save_path":
            path_util.abspath(self.state_dir),
            b"info-hash":
            b'\x00' * 20
        })
        dl.setup()

        dl.config.set_engineresumedata({
            b"save_path":
            path_util.abspath(self.state_dir),
            b"info-hash":
            b'\x00' * 20
        })
        dl.setup()

        dl.config.set_engineresumedata({
            b"save_path": "some_local_dir",
            b"info-hash": b'\x00' * 20
        })
        dl.setup()
        await dl.shutdown()
Esempio n. 20
0
def start_anon_download(session, seed_session, tdef, hops=1):
    """
    Start an anonymous download in the main Tribler session.
    """
    session.config.set_libtorrent_dht_readiness_timeout(0)
    dscfg = DownloadConfig()
    dscfg.set_dest_dir(session.config.get_state_dir())
    dscfg.set_hops(hops)
    download = session.dlmgr.start_download(tdef=tdef, config=dscfg)
    session.tunnel_community.bittorrent_peers[download] = [
        ("127.0.0.1", seed_session.config.get_libtorrent_port())
    ]
    return download
Esempio n. 21
0
async def test_save_resume(mock_handle, test_download, test_tdef):
    """
    testing call resume data alert
    """
    mock_handle.is_valid = lambda: True
    mock_handle.save_resume_data = lambda: test_download.register_task(
        'post_alert',
        test_download.process_alert,
        alert,
        'save_resume_data_alert',
        delay=0.1)

    alert = Mock(resume_data={b'info-hash': test_tdef.get_infohash()})
    await test_download.save_resume_data()
    basename = hexlify(test_tdef.get_infohash()) + '.conf'
    filename = test_download.dlmgr.get_checkpoint_dir() / basename
    dcfg = DownloadConfig.load(str(filename))
    assert test_tdef.get_infohash(), dcfg.get_engineresumedata().get(
        b'info-hash')
Esempio n. 22
0
 def updated_my_channel(self, tdef):
     """
     Notify the core that we updated our channel.
     """
     with db_session:
         my_channel = self.session.mds.ChannelMetadata.get(
             infohash=database_blob(tdef.get_infohash()))
     if (my_channel and my_channel.status == COMMITTED
             and not self.session.dlmgr.download_exists(
                 bytes(my_channel.infohash))):
         dcfg = DownloadConfig(
             state_dir=self.session.config.get_state_dir())
         dcfg.set_dest_dir(self.session.mds.channels_dir)
         dcfg.set_channel_download(True)
         return self.session.dlmgr.start_download(tdef=tdef, config=dcfg)
Esempio n. 23
0
 async def test_save_resume(self):
     """
     testing call resume data alert
     """
     tdef = self.create_tdef()
     alert = Mock(resume_data={b'info-hash': tdef.get_infohash()})
     dl = Download(self.session, tdef)
     dl.setup()
     dl.handle = MockObject()
     dl.handle.is_valid = lambda: True
     dl.handle.save_resume_data = lambda: dl.register_task(
         'post_alert',
         dl.process_alert,
         alert,
         'save_resume_data_alert',
         delay=0.1)
     await dl.save_resume_data()
     basename = hexlify(tdef.get_infohash()) + '.conf'
     filename = self.session.dlmgr.get_checkpoint_dir() / basename
     dcfg = DownloadConfig.load(filename)
     self.assertEqual(tdef.get_infohash(),
                      dcfg.get_engineresumedata().get(b'info-hash'))
     await dl.shutdown()
Esempio n. 24
0
    async def test_set_settings(self):
        """
        Testing whether settings in the API can be successfully set
        """

        dcfg = DownloadConfig()
        download = MockObject()
        download.config = dcfg
        self.session.dlmgr.get_downloads = lambda: [download]

        post_data = {
            'download_defaults': {
                'seeding_mode': 'ratio',
                'seeding_ratio': 3,
                'seeding_time': 123
            }
        }
        await self.do_request('settings',
                              expected_code=200,
                              request_type='POST',
                              post_data=post_data)
        self.assertEqual(self.session.config.get_seeding_mode(), 'ratio')
        self.assertEqual(self.session.config.get_seeding_ratio(), 3)
        self.assertEqual(self.session.config.get_seeding_time(), 123)
Esempio n. 25
0
async def test_set_settings(enable_api, mock_dlmgr, session):
    """
    Testing whether settings in the API can be successfully set
    """
    dcfg = DownloadConfig()
    download = Mock()
    download.config = dcfg
    session.dlmgr.get_downloads = lambda: [download]

    post_data = {
        'download_defaults': {
            'seeding_mode': 'ratio',
            'seeding_ratio': 3,
            'seeding_time': 123
        }
    }
    await do_request(session,
                     'settings',
                     expected_code=200,
                     request_type='POST',
                     post_data=post_data)
    assert session.config.get_seeding_mode() == 'ratio'
    assert session.config.get_seeding_ratio() == 3
    assert session.config.get_seeding_time() == 123
Esempio n. 26
0
    async def download_channel(self, channel):
        """
        Download a channel with a given infohash and title.
        :param channel: The channel metadata ORM object.
        """

        metainfo = await self.session.dlmgr.get_metainfo(bytes(
            channel.infohash),
                                                         timeout=60,
                                                         hops=0)
        if metainfo is None:
            # Timeout looking for the channel metainfo. Probably, there are no seeds.
            # TODO: count the number of tries we had with the channel, so we can stop trying eventually
            return
        try:
            if metainfo[b'info'][b'name'].decode('utf-8') != channel.dirname:
                # Malformed channel
                # TODO: stop trying to download this channel until it is updated with a new infohash
                return
        except (KeyError, TypeError):
            return

        dcfg = DownloadConfig(state_dir=self.session.config.get_state_dir())
        dcfg.set_dest_dir(self.session.mds.channels_dir)
        dcfg.set_channel_download(True)
        tdef = TorrentDef(metainfo=metainfo)

        download = self.session.dlmgr.start_download(tdef=tdef,
                                                     config=dcfg,
                                                     hidden=True)
        try:
            await download.future_finished
        except CancelledError:
            pass
        else:
            self.channels_processing_queue[channel.infohash] = (
                PROCESS_CHANNEL_DIR, channel)
        return download
Esempio n. 27
0
class Bootstrap(TaskManager):
    """
    A class to create a bootstrap downloads for inital file aka bootstrap file.
    Bootstrap class will be initialized at the start of Tribler by downloading/seeding bootstrap file.
    """
    def __init__(self, config_dir, dht=None):
        super(Bootstrap, self).__init__()

        self._logger = logging.getLogger(self.__class__.__name__)
        self.dcfg = DownloadConfig(state_dir=config_dir)
        self.dcfg.set_bootstrap_download(True)
        self.bootstrap_dir = config_dir / 'bootstrap'
        if not self.bootstrap_dir.exists():
            os.mkdir(self.bootstrap_dir)
        self.dcfg.set_dest_dir(self.bootstrap_dir)
        self.dcfg.set_safe_seeding(True)
        self.bootstrap_file = self.bootstrap_dir / "bootstrap.blocks"
        self.dht = dht

        self.bootstrap_finished = False
        self.infohash = None
        self.download = None
        self.bootstrap_nodes = {}

        self.register_task('fetch_bootstrap_peers',
                           self.fetch_bootstrap_peers,
                           interval=5)

    def start_by_infohash(self, download_function, infohash):
        """
        Download bootstrap file from current seeders
        :param download_function: function to download via tdef
        :return: download on bootstrap file
        """
        self._logger.debug("Starting bootstrap downloading %s", infohash)
        tdef = TorrentDefNoMetainfo(unhexlify(infohash),
                                    name='bootstrap.blocks')
        self.download = download_function(tdef=tdef,
                                          config=self.dcfg,
                                          hidden=True)
        self.infohash = infohash

    async def fetch_bootstrap_peers(self):
        if not self.download:
            return {}

        for peer in self.download.get_peerlist():
            mid = peer['id']
            if (mid not in self.bootstrap_nodes
                    or not self.bootstrap_nodes[mid]) and mid != "0" * 40:
                if self.dht:
                    try:
                        nodes = await self.dht.connect_peer(
                            bytes(unhexlify(mid)))
                    except DHTError as e:
                        self._logger.error("Failed to get DHT response:%s", e)
                        continue

                    if not nodes:
                        return
                    for node in nodes:
                        self.bootstrap_nodes[hexlify(node.mid)] = hexlify(
                            node.public_key.key_to_bin())
        return self.bootstrap_nodes

    async def shutdown(self):
        await self.shutdown_task_manager()
Esempio n. 28
0
def test_default_download_config_load(tmpdir):
    with open(tmpdir / "dlconfig.conf", 'wb') as conf_file:
        conf_file.write(b"[Tribler]\nabc=def")

    dcfg = DownloadConfig.load(tmpdir / "dlconfig.conf")
    assert dcfg.config['Tribler']['abc'] == 'def'
Esempio n. 29
0
def download_config():
    return DownloadConfig()
Esempio n. 30
0
async def test_download(session, mock_dlmgr, test_tdef):
    download = Download(session, test_tdef)
    download.config = DownloadConfig(state_dir=session.config.get_state_dir())
    download.infohash = hexlify(test_tdef.get_infohash())
    yield download
    await download.shutdown()