Beispiel #1
0
def test_remote_exceptions(config_name):

    # start daemon process
    start_maestral_daemon_process(config_name, timeout=20)

    # create proxy and call a remote method which raises an error
    with MaestralProxy(config_name) as m:
        with pytest.raises(NotLinkedError):
            m.get_account_info()

    # stop daemon
    stop_maestral_daemon_process(config_name)
Beispiel #2
0
    def test_remote_exceptions(self):

        # start daemon process
        start_maestral_daemon_process(self.config_name)

        # create proxy and call a remote method which raises an error
        with MaestralProxy(self.config_name) as m:
            with self.assertRaises(NotLinkedError):
                m.get_account_info()

        # stop daemon
        stop_maestral_daemon_process(self.config_name)

        # clean up config
        remove_configuration(self.config_name)
Beispiel #3
0
    def get_or_start_maestral_daemon(self) -> MaestralProxy:

        res = start_maestral_daemon_process(self.config_name)

        if res == Start.Failed:
            title = "Could not start Maestral"
            message = (
                "Could not start or connect to sync daemon. Please try again "
                "and contact the developer if this issue persists.")
            self.alert(title, message, level="error")
            stop_maestral_daemon_process(self.config_name)
            super().exit()
        elif res == Start.AlreadyRunning:
            self._started = False
        elif res == Start.Ok:
            self._started = True

        return MaestralProxy(self.config_name)
Beispiel #4
0
def test_lifecycle_attached(config_name):

    # start daemon process
    res = start_maestral_daemon_process(config_name, detach=False)
    assert res is Start.Ok

    # check that we have attached process
    ctx = mp.get_context("spawn" if IS_MACOS else "fork")
    daemon = ctx.active_children()[0]
    assert daemon.name == "maestral-daemon"

    # stop daemon
    res = stop_maestral_daemon_process(config_name)
    assert res is Stop.Ok

    # retry stop daemon
    res = stop_maestral_daemon_process(config_name)
    assert res is Stop.NotRunning
Beispiel #5
0
    def test_lifecycle_attached(self):

        # start daemon process
        res = start_maestral_daemon_process(self.config_name, detach=False)
        self.assertEqual(res, Start.Ok)

        # check that we have attached process
        ctx = mp.get_context("spawn" if IS_MACOS else "fork")
        daemon = ctx.active_children()[0]
        self.assertEqual(daemon.name, "maestral-daemon")

        # stop daemon
        res = stop_maestral_daemon_process(self.config_name)
        self.assertEqual(res, Stop.Ok)

        # retry stop daemon
        res = stop_maestral_daemon_process(self.config_name)
        self.assertEqual(res, Stop.NotRunning)

        # clean up config
        remove_configuration(self.config_name)
Beispiel #6
0
def stop_daemon_with_cli_feedback(config_name: str) -> None:
    """Wrapper around :meth:`daemon.stop_maestral_daemon_process`
    with command line feedback."""

    click.echo("Stopping Maestral...", nl=False)
    res = stop_maestral_daemon_process(config_name)
    if res == Stop.Ok:
        click.echo("\rStopping Maestral...        " + OK)
    elif res == Stop.NotRunning:
        click.echo("Maestral daemon is not running.")
    elif res == Stop.Killed:
        click.echo("\rStopping Maestral...        " + KILLED)
Beispiel #7
0
def test_lifecycle(config_name):

    # start daemon process
    res = start_maestral_daemon_process(config_name, timeout=20)
    assert res is Start.Ok

    # retry start daemon process
    res = start_maestral_daemon_process(config_name, timeout=20)
    assert res is Start.AlreadyRunning

    # retry start daemon in-process
    with pytest.raises(RuntimeError):
        start_maestral_daemon(config_name)

    # stop daemon
    res = stop_maestral_daemon_process(config_name)
    assert res is Stop.Ok

    # retry stop daemon
    res = stop_maestral_daemon_process(config_name)
    assert res is Stop.NotRunning
Beispiel #8
0
def stop_daemon_with_cli_feedback(config_name):
    """Wrapper around `daemon.stop_maestral_daemon_process`
    with command line feedback."""

    from maestral.daemon import stop_maestral_daemon_process, Exit

    click.echo('Stopping Maestral...', nl=False)
    res = stop_maestral_daemon_process(config_name)
    if res == Exit.Ok:
        click.echo('\rStopping Maestral...        ' + OK)
    elif res == Exit.NotRunning:
        click.echo('Maestral daemon is not running.')
    elif res == Exit.Killed:
        click.echo('\rStopping Maestral...        ' + KILLED)
Beispiel #9
0
def test_connection(config_name):

    # start daemon process
    res = start_maestral_daemon_process(config_name, timeout=20)
    assert res is Start.Ok

    # create proxy
    with MaestralProxy(config_name) as m:
        assert m.config_name == config_name
        assert not m._is_fallback
        assert isinstance(m._m, Proxy)

    # stop daemon
    res = stop_maestral_daemon_process(config_name)
    assert res is Stop.Ok
Beispiel #10
0
    def test_lifecycle_detached(self):

        # start daemon process
        res = start_maestral_daemon_process(self.config_name)
        self.assertEqual(res, Start.Ok)

        # retry start daemon process
        res = start_maestral_daemon_process(self.config_name)
        self.assertEqual(res, Start.AlreadyRunning)

        # retry start daemon in-process
        with self.assertRaises(RuntimeError):
            start_maestral_daemon(self.config_name)

        # stop daemon
        res = stop_maestral_daemon_process(self.config_name)
        self.assertEqual(res, Stop.Ok)

        # retry stop daemon
        res = stop_maestral_daemon_process(self.config_name)
        self.assertEqual(res, Stop.NotRunning)

        # clean up config
        remove_configuration(self.config_name)
Beispiel #11
0
    def quit(self, *args, stop_daemon=None):
        """Quits Maestral.

        :param bool stop_daemon: If ``True``, the sync daemon will be stopped when
            quitting the GUI, if ``False``, it will be kept alive. If ``None``, the daemon
            will only be stopped if it was started by the GUI (default).
        """
        logger.info('Quitting...')

        # stop update timer to stop communication with daemon
        self.update_ui_timer.stop()

        threaded = os.getpid() == get_maestral_pid(self.config_name)

        # stop sync daemon if we started it or ``stop_daemon`` is ``True``
        # never stop the daemon if it runs in a thread of the current process
        if threaded:
            stop_maestral_daemon_thread(self.config_name)
        elif stop_daemon or self._started:
            stop_maestral_daemon_process(self.config_name)

        # quit
        QtCore.QCoreApplication.quit()
        sys.exit(0)
Beispiel #12
0
def config_name(prefix: str = "test-config"):

    i = 0
    config_name = f"{prefix}-{i}"

    while config_name in list_configs():
        i += 1
        config_name = f"{prefix}-{i}"

    yield config_name

    res = stop_maestral_daemon_process(config_name)

    if res is Stop.Failed:
        raise RuntimeError("Could not stop test daemon")

    remove_configuration(config_name)
Beispiel #13
0
    def test_connection(self):

        # start daemon process
        res = start_maestral_daemon_process(self.config_name)
        self.assertEqual(Start.Ok, res)

        # create proxy
        with MaestralProxy(self.config_name) as m:
            self.assertEqual(m.config_name, self.config_name)
            self.assertFalse(m._is_fallback)
            self.assertIsInstance(m._m, Proxy)

        # stop daemon
        res = stop_maestral_daemon_process(self.config_name)
        self.assertEqual(res, Stop.Ok)

        # clean up config
        remove_configuration(self.config_name)
Beispiel #14
0
 def updater_willInstallUpdate_(
     self, updater: objc_id, item: objc_id
 ) -> None:
     stop_maestral_daemon_process(self.config_name)
Beispiel #15
0
def proxy(m):
    m.stop_sync()
    start_maestral_daemon_process(m.config_name, timeout=20)
    yield MaestralProxy(m.config_name)

    stop_maestral_daemon_process(m.config_name)
Beispiel #16
0
def start(foreground: bool, verbose: bool, config_name: str) -> None:

    # ---- run setup if necessary ------------------------------------------------------

    # We run the setup in the current process. This avoids starting a subprocess despite
    # running with the --foreground flag, prevents leaving a zombie process if the setup
    # fails with an exception and does not confuse systemd.

    from maestral.main import Maestral

    m = Maestral(config_name, log_to_stdout=verbose)

    if m.pending_link:  # this may raise KeyringAccessError
        link_dialog(m)

    if m.pending_dropbox_folder:
        path = select_dbx_path_dialog(config_name, allow_merge=True)

        while True:
            try:
                m.create_dropbox_directory(path)
                break
            except OSError:
                click.echo(
                    "Could not create folder. Please make sure that you have "
                    "permissions to write to the selected location or choose a "
                    "different location."
                )

        exclude_folders_q = click.confirm(
            "Would you like to exclude any folders from syncing?",
        )

        if exclude_folders_q:
            click.echo(
                "Please choose which top-level folders to exclude. You can exclude\n"
                'individual files or subfolders later with "maestral excluded add".\n'
            )

            click.echo("Loading...", nl=False)

            # get all top-level Dropbox folders
            entries = m.list_folder("/", recursive=False)
            excluded_items: List[str] = []

            click.echo("\rLoading...   Done")

            # paginate through top-level folders, ask to exclude
            for e in entries:
                if e["type"] == "FolderMetadata":
                    yes = click.confirm(
                        'Exclude "{path_display}" from sync?'.format(**e)
                    )
                    if yes:
                        path_lower = cast(str, e["path_lower"])
                        excluded_items.append(path_lower)

            m.set_excluded_items(excluded_items)

    # free resources
    del m

    if foreground:
        # stop daemon process after setup and restart in our current process
        stop_maestral_daemon_process(config_name)
        start_maestral_daemon(config_name, log_to_stdout=verbose, start_sync=True)
    else:

        # start daemon process
        click.echo("Starting Maestral...", nl=False)

        res = start_maestral_daemon_process(
            config_name, log_to_stdout=verbose, start_sync=True
        )

        if res == Start.Ok:
            click.echo("\rStarting Maestral...        " + OK)
        elif res == Start.AlreadyRunning:
            click.echo("\rStarting Maestral...        Already running.")
        else:
            click.echo("\rStarting Maestral...        " + FAILED)
            click.echo("Please check logs for more information.")
Beispiel #17
0
 async def async_exit(sender: Any = None) -> None:
     if self._started:
         stop_maestral_daemon_process(self.config_name)
     super(MaestralGui, self).exit()
Beispiel #18
0
 def cleanUp(self):
     stop_maestral_daemon_process(self.config_name)
 def on_quit_clicked(self):
     self._deactivate_buttons()
     self.spinner.startAnimation()
     stop_maestral_daemon_process(self.mdbx.config_name)
 def on_unlink_done(self):
     self.spinner.stopAnimation()
     stop_maestral_daemon_process(self.mdbx.config_name)