Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def load_maestral(self):
pending_link = not _is_linked()
pending_dbx_folder = not os.path.isdir(CONF.get("main", "path"))
if pending_link or pending_dbx_folder:
from maestral.gui.setup_dialog import SetupDialog
logger.info("Setting up Maestral...")
done = SetupDialog.configureMaestral(pending_link)
if done:
logger.info("Successfully set up Maestral")
self.restart()
else:
logger.info("Setup aborted.")
self.quit()
else:
self.mdbx = self._get_or_start_maestral_daemon()
self.setup_ui_linked()
has_changes = sync.wait_for_remote_changes(sync.last_cursor, timeout=30)
if not running.is_set(): # if stopped, return
return
syncing.wait() # if paused, wait until resumed
# apply remote changes
if has_changes:
logger.info(SYNCING)
with sync.lock:
# get changes
changes = sync.list_remote_changes(sync.last_cursor)
# notify user about changes
if CONF.get("app", "notifications"):
sync.notify_user(changes)
# apply remote changes to local Dropbox folder
sync.apply_remote_changes(changes)
logger.info(IDLE)
except ConnectionError:
syncing.clear()
connected.clear()
disconnected_signal.send()
logger.debug(DISCONNECTED, exc_info=True)
logger.info(DISCONNECTED)
except MaestralApiError as e:
syncing.clear() # stop syncing
running.clear() # shutdown threads
def _read_pid(config_name):
"""
Reads and returns the PID of the current maestral daemon process from the appropriate
file for the given config name.
"""
from maestral.sync.utils.appdirs import get_runtime_path
pid_file = get_runtime_path("maestral", config_name + ".pid")
with open(pid_file, "r") as f:
pid = f.read().split("\n")[0] # ignore all new lines
pid = int(pid)
logger.debug(f"PID {pid} read from '{pid_file}'.")
return pid
def _get_or_start_maestral_daemon(self):
pid = get_maestral_pid(CONFIG_NAME)
if pid:
self._started = False
else:
if IS_MACOS_BUNDLE:
res = start_maestral_daemon_thread(CONFIG_NAME)
else:
res = start_maestral_daemon_process(CONFIG_NAME)
if res is False:
error_dialog = UserDialog(
"Could not start Maestral",
"Could not start or connect to sync daemon. Please try again and " +
"contact the developer if this issue persists."
)
error_dialog.exec_()
self.quit()
else:
self._started = True
return get_maestral_daemon_proxy(CONFIG_NAME)
def __init__(self, sync_err, parent=None):
super(self.__class__, self).__init__(parent=parent)
uic.loadUi(SYNC_ISSUE_WIDGET_PATH, self)
self.sync_err = sync_err
self.errorLabel.setFont(get_scaled_font(scaling=0.85))
self.update_dark_mode() # set appropriate item icon and colors in style sheet
self.pathLabel.setText(self.to_display_path(self.sync_err["local_path"]))
self.errorLabel.setText(self.sync_err["title"] + ":\n" + self.sync_err["message"])
def request_context_menu():
self.actionButton.customContextMenuRequested.emit(self.actionButton.pos())
self.actionButton.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.actionButton.pressed.connect(request_context_menu)
self.actionButton.customContextMenuRequested.connect(self.showContextMenu)
"Rebuilding the index may take several minutes, depending on the size of "
"your Dropbox. Please do not modify any items in your local Dropbox folder "
"during this process. Any changes to local files while rebuilding may be "
"lost.",
width=width
)
click.echo("\n".join(message1) + "\n")
click.echo("\n".join(message2) + "\n")
click.confirm("Do you want to continue?", abort=True)
import time
from concurrent.futures import ThreadPoolExecutor
from maestral.sync.daemon import MaestralProxy
with MaestralProxy(config_name, fallback=True) as m0:
with ThreadPoolExecutor(max_workers=1) as executor:
future = executor.submit(m0.rebuild_index)
with MaestralProxy(config_name, fallback=True) as m1:
while future.running():
msg = ("\r" + m1.status).ljust(width)
click.echo(msg, nl=False)
time.sleep(1.0)
click.echo("\rRebuilding complete.".ljust(width))
else:
click.echo("Maestral does not appear to be linked.")
: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...")
if stop_daemon is None:
stop_daemon = self._started
# stop update timer to stop communication with daemon
self.update_ui_timer.stop()
# stop sync daemon if we started it or ``stop_daemon==True``
if stop_daemon and self.mdbx and not IS_MACOS_BUNDLE:
self.mdbx._pyroRelease()
stop_maestral_daemon_process(CONFIG_NAME)
# quit
self.deleteLater()
QtCore.QCoreApplication.quit()
sys.exit(0)
def _save_to_history(dbx_path):
# add new file to recent_changes
recent_changes = CONF.get("internal", "recent_changes")
recent_changes.append(dbx_path)
# eliminate duplicates
recent_changes = list(OrderedDict.fromkeys(recent_changes))
# save last 30 changes
CONF.set("internal", "recent_changes", recent_changes[-30:])
def _is_linked():
"""
Checks if auth key has been saved.
:raises: ``KeyringLocked`` if the system keyring cannot be accessed.
"""
account_id = CONF.get("account", "account_id")
try:
if account_id == "":
access_token = None
else:
access_token = keyring.get_password("Maestral", account_id)
return access_token
except KeyringLocked:
info = "Please make sure that your keyring is unlocked and restart Maestral."
raise KeyringLocked(info)
def __init__(self, client, local_file_event_queue, queue_uploading, queue_downloading):
self.client = client
self.local_file_event_queue = local_file_event_queue
self.queue_uploading = queue_uploading
self.queue_downloading = queue_downloading
# load cached properties
self._dropbox_path = CONF.get("main", "path")
self._excluded_files = CONF.get("main", "excluded_files")
self._excluded_folders = CONF.get("main", "excluded_folders")
self._rev_dict_cache = self._load_rev_dict_from_file()