Exemple #1
0
async def http_request_handler(server,
                               request,
                               *,
                               title=None,
                               http_port=None,
                               ws_port=None):
    target = request.target.decode('ascii')
    request_body = ''
    async for part in _http_server.receive_body(server):
        request_body += part  # pylint: disable=consider-using-join
    if target == '/':
        path = trio.Path(HTML_PATH / 'index.html')
        template = Template(await path.read_text())
        body = template.substitute(title=title,
                                   ws_url_path='/ws/',
                                   http_port=http_port,
                                   ws_port=ws_port)
        await _http_server.send_simple_response(server, int(HTTPStatus.OK),
                                                'text/html; charset=utf-8',
                                                body.encode('utf-8'))
    elif target == '/js/pura.js':
        path = trio.Path(HTML_PATH / target.lstrip('/'))
        body = await path.read_text()
        await _http_server.send_simple_response(
            server, int(HTTPStatus.OK),
            'application/javascript; charset=utf-8', body.encode('utf-8'))
    else:
        raise h11.RemoteProtocolError(f'{target} not found',
                                      int(HTTPStatus.NOT_FOUND))
    def __init__(self, image_path: pathlib.Path, thumbnail_path: pathlib.Path, json_path: pathlib.Path):
        self.image_path = trio.Path(image_path)
        self.thumbnail_path = trio.Path(thumbnail_path)
        self.json_path = json_path

        with open(json_path) as fp:
            data = json.loads(fp.read())
            self.dimension = data["clipPoints"][2]
Exemple #3
0
    async def rename(self,
                     key1: datastore.Key,
                     key2: datastore.Key,
                     *,
                     replace: bool = True) -> None:
        """Moves key *key1* to *key2*
		
		Arguments
		---------
		key1
			The key to rename, must exist
		key2
			The new name of the key; if *replace* is ``False``, a key of the
			same name may not already exist
		replace
			Should an existing key at name *key2* be replaced?
		
		Raises
		------
		KeyError
			Key *key1* did not exist in this datastore
		KeyError
			Key *key2* already exists in this datastore, but *replace* was not ``True``
		"""
        # Validate that the keys are well-formed
        assert self.verify_key_valid(key1)
        assert self.verify_key_valid(key2, False)

        path1 = trio.Path(self.object_path(key1))
        path2 = trio.Path(self.object_path(key2))

        if not replace:
            # Just do the replace and fail if it didn't succeed
            #
            # No weird accounting stuff here since this operation never changes the
            # size of datastore.
            try:
                await run_blocking_nointr(rename_noreplace.rename_noreplace,
                                          path1, path2)
            except FileNotFoundError as exc:
                raise KeyError(key1) from exc
            except FileExistsError as exc:
                raise KeyError(key2) from exc
        else:
            try:
                async with self._stats_lock:  # type: ignore[union-attr]
                    await run_blocking_nointr(self._rename_replace_sync, path1,
                                              path2)
            except FileNotFoundError as exc:
                raise KeyError(key1) from exc
Exemple #4
0
async def test_idempotent_mount(base_mountpoint, alice_user_fs, event_bus,
                                manual_unmount):
    mountpoint_path = base_mountpoint / "w"

    # Populate a bit the fs first...

    wid = await alice_user_fs.workspace_create("w")
    workspace = alice_user_fs.get_workspace(wid)
    await workspace.touch("/bar.txt")

    bar_txt = trio.Path(f"{mountpoint_path}/bar.txt")

    # Now we can start fuse
    async with mountpoint_manager_factory(
        alice_user_fs, event_bus, base_mountpoint) as mountpoint_manager:

        await mountpoint_manager.mount_workspace(wid)
        assert await bar_txt.exists()

        with pytest.raises(MountpointAlreadyMounted):
            await mountpoint_manager.mount_workspace(wid)
        assert await bar_txt.exists()

        await mountpoint_manager.unmount_workspace(wid)
        assert not await bar_txt.exists()

        with pytest.raises(MountpointNotMounted):
            await mountpoint_manager.unmount_workspace(wid)
        assert not await bar_txt.exists()

        await mountpoint_manager.mount_workspace(wid)
        assert await bar_txt.exists()
Exemple #5
0
async def test_cancel_mount_workspace(base_mountpoint, alice_user_fs,
                                      event_bus, timeout):
    """
    This function tests the race conditions between the mounting of a workspace
    and trio cancellation. In particular, it produces interesting results when trying to
    unmount a workspace while it's still initializing.

    The following timeout values are useful for more thorough testing:

        [x * 0.00001 for x in range(2000, 2500)]
    """
    wid = await alice_user_fs.workspace_create("w")

    # The timeout for `_stop_fuse_thread` is 1 second (3 seconds for macOS),
    # so let's use a slightly lower timeout to make sure a potential failure
    # doesn't go undetected.
    timeout = 3.0 if sys.platform == "darwin" else 1.0
    with trio.fail_after(timeout * 0.9):

        async with mountpoint_manager_factory(
                alice_user_fs, event_bus,
                base_mountpoint) as mountpoint_manager:

            with trio.move_on_after(timeout) as cancel_scope:
                await mountpoint_manager.mount_workspace(wid)
            if cancel_scope.cancelled_caught:
                with pytest.raises(MountpointNotMounted):
                    mountpoint_manager.get_path_in_mountpoint(wid, FsPath("/"))
            else:
                path = trio.Path(
                    mountpoint_manager.get_path_in_mountpoint(
                        wid, FsPath("/")))
                await path.exists()
                assert not await (path / "foo").exists()
Exemple #6
0
async def configure_mime_types():
    if sys.platform == "win32" or sys.platform == "darwin":
        return
    XDG_DATA_HOME = os.environ["XDG_DATA_HOME"]
    desktop_file = trio.Path(f"{XDG_DATA_HOME}/applications/parsec.desktop")
    await desktop_file.parent.mkdir(exist_ok=True, parents=True)
    await desktop_file.write_text("""\
[Desktop Entry]
Name=Parsec
Exec=parsec core gui %u
Type=Application
Terminal=false
StartupNotify=false
StartupWMClass=Parsec
MimeType=x-scheme-handler/parsec;
""")
    try:
        await trio.run_process("update-desktop-database -q".split(),
                               check=False)
    except FileNotFoundError:
        # Ignore if command is not available
        pass
    try:
        await trio.run_process(
            "xdg-mime default parsec.desktop x-scheme-handler/parsec".split())
    except FileNotFoundError:
        # Ignore if command is not available
        pass
Exemple #7
0
    async def _process_connections(
        self,
        channel: trio.abc.ReceiveChannel[ConnectionConfig],
        nursery: trio_typing.Nursery,
    ) -> None:
        """
        Long running process that establishes connections to endpoint servers
        and runs the handler for receiving events sent by the server over that
        connection.
        """
        self.logger.debug("%s: starting new connection channel", self)
        self._connection_loop_running.set()
        async for config in channel:
            # Allow some time for for the IPC socket to appear
            with trio.fail_after(constants.IPC_WAIT_SECONDS):
                await _wait_for_path(trio.Path(config.path))

            await trio.sleep(0.001)
            # Establish the socket connection
            connection = await TrioConnection.connect_to(config.path)

            # Create the remote
            remote = TrioRemoteEndpoint(
                self.name,
                connection,
                self._remote_subscriptions_changed,
                self._inbound_send_channel.send,
            )
            nursery.start_soon(self._run_remote_endpoint, remote)
Exemple #8
0
 def _get_robots_analyzer(self) -> RobotsAnalyzer:
     logger.debug('getting a default robots analyzer')
     return RobotsAnalyzer(
         http_client=self._http_client,
         robots_cache=trio.Path(self.config.robots_cache_folder),
         user_agent=self.config.user_agent
     )
Exemple #9
0
    async def _init_stats(self) -> None:
        # Start fresh
        self._stats = Stats()

        # Try to read existing stats file
        path = trio.Path(self.object_path(self.stats_key))
        try:
            async with await path.open() as stats_file:
                self._stats = Stats.from_json(
                    json.loads(await stats_file.read()))
                self._stats.mtime_ns = (await run_blocking_intr(
                    os.fstat, stats_file.fileno())).st_mtime_ns
        except FileNotFoundError:
            # At least set an appropriate accuracy value if there are no files yet
            is_empty = await run_blocking_intr(check_dir_empty_sync,
                                               self.root_path)
            if is_empty:
                self._stats.disk_usage = 0
                self._stats.accuracy = "initial-exact"
            else:
                pass  #XXX: We could call `os.walk` here to get the initial size estimate…

        self._stats_prev = self._stats.copy()

        # This will synchronize our current state with the one on the disk
        await self._flush_stats(expect_file=False)
Exemple #10
0
 async def _mocked_bootstrap_mountpoint(*args):
     trio_mountpoint_path = trio.Path(f"{mountpoint_path}")
     await trio_mountpoint_path.mkdir(parents=True)
     file_path = trio_mountpoint_path / "bar.txt"
     await file_path.touch()
     st_dev = (await trio_mountpoint_path.stat()).st_dev
     return mountpoint_path, st_dev
Exemple #11
0
    def __init__(self, path, vacuum_threshold=None):
        self._conn = None
        self._lock = trio.Lock()
        self._run_in_thread = None

        self.path = trio.Path(path)
        self.vacuum_threshold = vacuum_threshold
Exemple #12
0
async def test_file_save_no_defaults(qtbot: pytestqt.qtbot.QtBot,
                                     tmp_path: pathlib.Path) -> None:
    path_to_select = trio.Path(tmp_path) / "another.thing"

    dialog = qtrio.dialogs.create_file_save_dialog()

    async def user(task_status):
        async with qtrio._core.wait_signal_context(dialog.shown):
            task_status.started()

        # allow cancellation to occur even if the signal was received before the
        # cancellation was requested.
        await trio.sleep(0)

        assert dialog.dialog is not None

        dialog.dialog.setDirectory(os.fspath(path_to_select.parent))
        [text_edit] = dialog.dialog.findChildren(QtWidgets.QLineEdit)
        text_edit.setText(path_to_select.name)
        dialog.dialog.accept()

    async with trio.open_nursery() as nursery:
        await nursery.start(user)
        with qtrio._qt.connection(signal=dialog.shown, slot=qtbot.addWidget):
            selected_path = await dialog.wait()

    assert selected_path == path_to_select
Exemple #13
0
async def test_get_dialog_canceled(
    chunked_data: typing.List[bytes],
    http_application: quart_trio.QuartTrio,
    url: hyperlink.URL,
    tmp_path: pathlib.Path,
) -> None:
    temporary_directory = trio.Path(tmp_path)

    destination = temporary_directory.joinpath("file")

    with pytest.raises(qtrio.UserCancelledError):
        async with trio.open_nursery() as nursery:
            start = functools.partial(
                qtrio.examples.download.start_get_dialog,
                url=url,
                destination=destination,
                fps=0.1,
                http_application=http_application,
            )
            widget: qtrio.examples.download.GetDialog = await nursery.start(start)

            await widget.progress_dialog_shown_event.wait()
            assert widget.progress_dialog is not None

            assert widget.progress_dialog.dialog is not None
            assert widget.progress_dialog.dialog.isVisible()
            assert widget.message_box is None

            assert widget.progress_dialog.cancel_button is not None
            widget.progress_dialog.cancel_button.click()
Exemple #14
0
async def test_get(
    chunked_data: typing.List[bytes],
    content_length: typing.Optional[int],
    http_application: quart_trio.QuartTrio,
    url: hyperlink.URL,
    tmp_path: pathlib.Path,
) -> None:
    temporary_directory = trio.Path(tmp_path)

    data = b"".join(chunked_data)
    destination = temporary_directory.joinpath("file")

    progresses = []

    async for progress in qtrio.examples.download.get(
        url=url,
        destination=destination,
        update_period=0,
        http_application=http_application,
    ):
        progresses.append(progress)

    async with await destination.open("rb") as written_file:
        written = await written_file.read()  # type: ignore[attr-defined]

    assert written == data
    assert all(progress.total == content_length for progress in progresses)
    assert [progresses[0].downloaded, progresses[-1].downloaded] == [0, len(data)]
async def test_stats_restore(temp_path):
    async with FileSystemDatastore.create(temp_path, stats=True) as fs:
        assert fs.datastore_stats().size == 0
        assert fs.datastore_stats().size_accuracy == "exact"

        await fs.put(datastore.Key("/a"), b"1234")

        assert fs.datastore_stats().size == 4

    # Re-open datastore and check that the stats are still there
    async with FileSystemDatastore.create(temp_path, stats=True) as fs:
        assert fs.datastore_stats().size == 4
        assert fs.datastore_stats().size_accuracy == "exact"

    # Replace content with stuff written by a non-cooperating datastore user
    await (trio.Path(temp_path) / "diskUsage.data").write_text(
        json.dumps({
            "diskUsage": 3,
            "accuracy": "initial-exact"
        }),
        encoding="utf-8")

    # Re-open datastore and check that the non-cooperating stats data is
    # properly merged
    async with FileSystemDatastore.create(temp_path, stats=True) as fs:
        assert fs.datastore_stats().size == 7
        assert fs.datastore_stats().size_accuracy == "exact"
    async def get_all(self, key: datastore.Key) -> bytes:
        """Returns all the data named by `key` at once or raises `KeyError`
		   otherwise
		
		This is an optimization over :meth:`get` for smaller files as it entails
		only one context switch to open, read and close the file, rather then
		several.
		
		Arguments
		---------
		key
			Key naming the data to retrieve

		Raises
		------
		KeyError
			The given object was not present in this datastore
		RuntimeError
			The given ``key`` names a subtree, not a value
		"""
        path = trio.Path(self.object_path(key))
        try:
            return await path.read_bytes()
        except FileNotFoundError as exc:
            raise KeyError(key) from exc
        except IsADirectoryError as exc:
            # Should hopefully only happen if `object_extension` is `""`
            raise RuntimeError(
                f"Key '{key}' names a subtree, not a value") from exc
Exemple #17
0
async def _bootstrap_mountpoint(base_mountpoint_path: PurePath,
                                workspace_fs) -> PurePath:
    # Find a suitable path where to mount the workspace. The check we are doing
    # here are not atomic (and the mount operation is not itself atomic anyway),
    # hence there is still edgecases where the mount can crash due to concurrent
    # changes on the mountpoint path
    workspace_name = workspace_fs.get_workspace_name()
    for tentative in count(1):
        if tentative == 1:
            dirname = workspace_name
        else:
            dirname = f"{workspace_name} ({tentative})"
        mountpoint_path = base_mountpoint_path / dirname

        try:
            # On POSIX systems, mounting target must exists
            trio_mountpoint_path = trio.Path(mountpoint_path)
            await trio_mountpoint_path.mkdir(exist_ok=True, parents=True)
            base_st_dev = (await trio.Path(base_mountpoint_path).stat()).st_dev
            initial_st_dev = (await trio_mountpoint_path.stat()).st_dev
            if initial_st_dev != base_st_dev:
                # mountpoint_path seems to already have a mountpoint on it,
                # hence find another place to setup our own mountpoint
                continue
            if list(await trio_mountpoint_path.iterdir()):
                # mountpoint_path not empty, cannot mount there
                continue
            return mountpoint_path, initial_st_dev

        except OSError:
            # In case of hard crash, it's possible the FUSE mountpoint is still
            # mounted (but points to nothing). In such case just mount in
            # another place
            continue
async def main(i):
    # Open connection
    async with open_cdp_connection(uri_pwa) as conn:
        logger.info('Connecting')
        targets = await conn.execute(target.get_targets())
        # Filter the targets to find the PWA one
        targets = list(filter(findPWA, targets))
        logger.info(targets[0])
        target_id = targets[0].target_id

        logger.info('Attaching to target id=%s', target_id)
        session = await conn.open_session(target_id)

        final_data = []

        def addData(data):
            final_data += data

        outfile_path = trio.Path(name + '_' + str(i) + '.json')
        async with await outfile_path.open('a+') as outfile:
            logger.info('Tracing...')
            # write things to file to be readable as a json
            await outfile.write('[')
            # data = '['
            await generateTrace(session, outfile, final_data)
            logger.info('Tracing n° {} ended'.format(i))
            await outfile.write(',\n'.join(final_data))
            await outfile.write("]")
Exemple #19
0
async def cleanup_macos_mountpoint_folder(base_mountpoint_path):
    # In case of a crash on macOS, workspaces don't unmount correctly and leave empty
    # mountpoints or directories in the default mount folder. This function is used to
    # unmount and/or delete these anytime a login occurs. In some rare and so far unknown
    # conditions, the unmount call can fail, raising a CalledProcessError, hence the
    # exception below. In such cases, the issue stops occurring after a system reboot,
    # making the exception catching a temporary solution.
    base_mountpoint_path = trio.Path(base_mountpoint_path)
    try:
        mountpoint_names = await base_mountpoint_path.iterdir()
    except FileNotFoundError:
        # Unlike with `pathlib.Path.iterdir` which returns a lazy itertor,
        # `trio.Path.iterdir` does FS access and may raise FileNotFoundError
        return
    for mountpoint_name in mountpoint_names:
        mountpoint_path = base_mountpoint_path / mountpoint_name
        stats = await trio.Path(mountpoint_path).stat()
        if (stats.st_size == 0 and stats.st_blocks == 0 and stats.st_atime == 0
                and stats.st_mtime == 0 and stats.st_ctime == 0):
            try:
                await trio.run_process(
                    ["diskutil", "unmount", "force", mountpoint_path])
            except CalledProcessError as exc:
                logger.warning(
                    "Error during mountpoint cleanup: diskutil unmount failed",
                    exc_info=exc,
                    mountpoint_path=mountpoint_path,
                )
            try:
                await trio.Path(mountpoint_path).rmdir()
            except FileNotFoundError:
                pass
Exemple #20
0
async def test_file_save(qtbot: pytestqt.qtbot.QtBot,
                         tmp_path: pathlib.Path) -> None:
    path_to_select = trio.Path(tmp_path) / "something.new"

    dialog = qtrio.dialogs.create_file_save_dialog(
        default_directory=path_to_select.parent,
        default_file=path_to_select,
    )

    async def user(task_status):
        async with qtrio._core.wait_signal_context(dialog.shown):
            task_status.started()

        # allow cancellation to occur even if the signal was received before the
        # cancellation was requested.
        await trio.sleep(0)

        assert dialog.dialog is not None

        dialog.dialog.accept()

    async with trio.open_nursery() as nursery:
        await nursery.start(user)
        with qtrio._qt.connection(signal=dialog.shown, slot=qtbot.addWidget):
            selected_path = await dialog.wait()

    assert selected_path == path_to_select
Exemple #21
0
async def test_remote_error_event(tmpdir, monkeypatch, running_backend,
                                  alice_user_fs, bob_user_fs, monitor):
    wid = await create_shared_workspace("w1", bob_user_fs, alice_user_fs)

    base_mountpoint = Path(tmpdir / "alice_mountpoint")
    async with mountpoint_manager_factory(alice_user_fs,
                                          alice_user_fs.event_bus,
                                          base_mountpoint,
                                          debug=False) as mountpoint_manager:

        await mountpoint_manager.mount_workspace(wid)

        # Create shared data
        bob_w = bob_user_fs.get_workspace(wid)
        await bob_w.touch("/foo.txt")
        await bob_w.write_bytes("/foo.txt", b"hello")
        await bob_w.sync()
        alice_w = alice_user_fs.get_workspace(wid)
        await alice_w.sync()
        # Force manifest cache
        await alice_w.path_id("/")
        await alice_w.path_id("/foo.txt")

        trio_w = trio.Path(
            mountpoint_manager.get_path_in_mountpoint(wid, FsPath("/")))

        # Switch the mountpoint in maintenance...
        await bob_user_fs.workspace_start_reencryption(wid)

        def _testbed():
            # ...accessing workspace data in the backend should endup in remote error
            with alice_user_fs.event_bus.listen() as spy:
                fd = os.open(str(trio_w / "foo.txt"), os.O_RDONLY)
                with pytest.raises(OSError):
                    os.read(fd, 10)
            spy.assert_event_occured("mountpoint.remote_error")

            # But should still be able to do local stuff though without remote errors
            with alice_user_fs.event_bus.listen() as spy:
                os.open(str(trio_w / "bar.txt"), os.O_RDWR | os.O_CREAT)
            assert os.listdir(str(trio_w)) == ["bar.txt", "foo.txt"]
            assert "mountpoint.remote_error" not in [
                e.event for e in spy.events
            ]

            # Finally test unhandled error
            def _crash(*args, **kwargs):
                raise RuntimeError("D'Oh !")

            monkeypatch.setattr(
                "parsec.core.fs.workspacefs.entry_transactions.EntryTransactions.folder_create",
                _crash,
            )
            with alice_user_fs.event_bus.listen() as spy:
                with pytest.raises(OSError):
                    os.mkdir(str(trio_w / "dummy"))
            spy.assert_event_occured("mountpoint.unhandled_error")

        await trio.to_thread.run_sync(_testbed)
Exemple #22
0
    async def test_should_return_python_objects_when_reading_file_without_custom_decoder(
            self, tmp_path, create_msgpack_file):
        given_data = [[1, 2], 'hello', {'fruit': 'apple'}]
        mp_file = tmp_path / 'data.mp'
        create_msgpack_file(mp_file, given_data)

        for file in [f'{mp_file}', trio.Path(mp_file)]:
            assert [item async for item in read_mp(file)] == given_data
async def generate_gui_config():
    config_dir = None
    if os.name == "nt":
        config_dir = trio.Path(os.environ["APPDATA"]) / "parsec/config"
    else:
        config_dir = trio.Path(os.environ["XDG_CONFIG_HOME"]) / "parsec"
    await config_dir.mkdir(parents=True, exist_ok=True)

    config_file = config_dir / "config.json"

    config = {
        "gui_first_launch": False,
        "gui_check_version_at_startup": False,
        "gui_tray_enabled": False,
        "gui_last_version": PARSEC_VERSION,
    }
    await config_file.write_text(json.dumps(config, indent=4))
Exemple #24
0
 def __init__(self, path):
     path = trio.Path(path)
     super().__init__(path)
     self._file_image_names.add("Demo")
     self._default_heightmap_names = ("Demo", )
     self.scansize = 100
     self.k = 1
     self.defl_sens = 1
     self.scandown = True
Exemple #25
0
 async def _fetch_pkg(self, url):
   whl_resp = await asks.get(url, stream=True)
   fname = url.split("/")[-1]
   output_name = trio.Path(self.target_dir / fname)
   async with await output_name.open("wb") as wheel:
     async with whl_resp.body:
       async for chunk in whl_resp.body:
         await wheel.write(chunk)
   return output_name
Exemple #26
0
async def convert_ardf(ardf_path, conv_path="ARDFtoHDF5.exe", pbar=None):
    """Turn an ARDF into a corresponding ARH5, returning the path.

    Requires converter executable available from Asylum Research"""
    ardf_path = trio.Path(ardf_path)
    h5file_path = ardf_path.with_suffix(".h5")

    if pbar is None:
        pipe = None
    else:
        pbar.set_description_str("Converting " + ardf_path.name)
        pipe = PIPE

    async def reading_stdout():
        stdout = bytearray()
        async for bytes_ in proc.stdout:
            stdout.extend(bytes_)
        stdout = stdout.decode()
        if "Failed" in stdout:
            raise RuntimeError(stdout)
        else:
            print(stdout)

    async def reading_stderr():
        async for bytes_ in proc.stderr:
            i = bytes_.rfind(
                b"\x08") + 1  # first thing on right not a backspace
            most_recent_numeric_output = bytes_[i:-1]  # crop % sign
            if most_recent_numeric_output:
                pbar.update(
                    float(most_recent_numeric_output.decode()) - pbar.n)

    try:
        async with await trio.open_process(
            [str(conv_path), str(ardf_path),
             str(h5file_path)],
                stderr=pipe,
                stdout=pipe,
                startupinfo=STARTUPINFO(dwFlags=STARTF_USESHOWWINDOW),
        ) as proc:
            if pbar is not None:
                async with trio.open_nursery() as nursery:
                    nursery.start_soon(reading_stdout)
                    nursery.start_soon(reading_stderr)
    except FileNotFoundError:
        raise FileNotFoundError(
            "Please acquire ARDFtoHDF5.exe and place it in the application's root folder."
        )
    except:
        with trio.CancelScope(shield=True):
            await h5file_path.unlink(missing_ok=True)
        raise
    finally:
        if pbar is not None:
            pbar.close()

    return h5file_path
Exemple #27
0
 async def serve(cls,
                 config: ConnectionConfig) -> AsyncIterator["TrioEndpoint"]:
     endpoint = cls(config.name)
     async with endpoint.run():
         async with trio.open_nursery() as nursery:
             await endpoint._start_serving(nursery, trio.Path(config.path))
             try:
                 yield endpoint
             finally:
                 await endpoint._stop_serving()
Exemple #28
0
async def generate_gui_config(backend_address):
    config_dir = None
    if sys.platform == "win32":
        config_dir = trio.Path(os.environ["APPDATA"]) / "parsec/config"
    else:
        config_dir = trio.Path(os.environ["XDG_CONFIG_HOME"]) / "parsec"
    await config_dir.mkdir(parents=True, exist_ok=True)

    config_file = config_dir / "config.json"

    config = {
        "gui_first_launch": False,
        "gui_check_version_at_startup": False,
        "gui_tray_enabled": False,
        "gui_last_version": PARSEC_VERSION,
        "preferred_org_creation_backend_addr": backend_address.to_url(),
        "gui_show_confined": True,
    }
    await config_file.write_text(json.dumps(config, indent=4))
Exemple #29
0
    async def test_should_return_python_objects_when_reading_file_with_custom_decoder(
            self, tmp_path, decode_datetime, create_msgpack_file):
        given_data = ['hello', datetime.now()]
        mp_file = tmp_path / 'data.mp'
        create_msgpack_file(mp_file, given_data)

        for file in [str(mp_file), trio.Path(mp_file)]:
            assert [
                item async for item in read_mp(file, decoder=decode_datetime)
            ] == given_data
Exemple #30
0
    def __init__(self,
                 path: Union[str, Path, trio.Path],
                 vacuum_threshold: Optional[int] = None):
        # Make sure only a single task access the connection object at a time
        self._lock = trio.Lock()

        # Those attributes are set by the `run` async context manager
        self._conn: Connection

        self.path = trio.Path(path)
        self.vacuum_threshold = vacuum_threshold