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)
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)
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)
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
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)
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)
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
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)
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
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)
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)
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)
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)
def updater_willInstallUpdate_( self, updater: objc_id, item: objc_id ) -> None: stop_maestral_daemon_process(self.config_name)
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)
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.")
async def async_exit(sender: Any = None) -> None: if self._started: stop_maestral_daemon_process(self.config_name) super(MaestralGui, self).exit()
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)