mirror of
https://github.com/samschott/maestral.git
synced 2024-09-22 03:18:33 +03:00
provide dependencies in constructor
This commit is contained in:
parent
4eda5d3dfe
commit
a04005f8d4
@ -133,13 +133,14 @@ class DropboxClient:
|
||||
def __init__(
|
||||
self,
|
||||
config_name: str,
|
||||
cred_storage: CredentialStorage,
|
||||
timeout: float = 100,
|
||||
session: requests.Session | None = None,
|
||||
) -> None:
|
||||
|
||||
self.config_name = config_name
|
||||
self._auth_flow: DropboxOAuth2FlowNoRedirect | None = None
|
||||
self.cred_storage = CredentialStorage(config_name)
|
||||
self._cred_storage = cred_storage
|
||||
|
||||
self._state = MaestralState(config_name)
|
||||
self._logger = scoped_logger(__name__, self.config_name)
|
||||
@ -184,7 +185,7 @@ class DropboxClient:
|
||||
|
||||
:raises KeyringAccessError: if keyring access fails.
|
||||
"""
|
||||
return self.cred_storage.token is not None
|
||||
return self._cred_storage.token is not None
|
||||
|
||||
def get_auth_url(self) -> str:
|
||||
"""
|
||||
@ -204,7 +205,7 @@ class DropboxClient:
|
||||
def link(self, token: str) -> int:
|
||||
"""
|
||||
Links Maestral with a Dropbox account using the given access token. The token
|
||||
will be stored for future usage as documented in the :mod:`oauth` module.
|
||||
will be stored for future usage in the provided credential store.
|
||||
|
||||
:param token: OAuth token for Dropbox access.
|
||||
:returns: 0 on success, 1 for an invalid token and 2 for connection errors.
|
||||
@ -227,7 +228,7 @@ class DropboxClient:
|
||||
except CONNECTION_ERRORS:
|
||||
return 2
|
||||
|
||||
self.cred_storage.save_creds(
|
||||
self._cred_storage.save_creds(
|
||||
res.account_id, res.refresh_token, TokenType.Offline
|
||||
)
|
||||
self._auth_flow = None
|
||||
@ -236,7 +237,8 @@ class DropboxClient:
|
||||
|
||||
def unlink(self) -> None:
|
||||
"""
|
||||
Unlinks the Dropbox account.
|
||||
Unlinks the Dropbox account. The password will be deleted from the provided
|
||||
credential storage.
|
||||
|
||||
:raises KeyringAccessError: if keyring access fails.
|
||||
:raises DropboxAuthError: if we cannot authenticate with Dropbox.
|
||||
@ -248,7 +250,7 @@ class DropboxClient:
|
||||
|
||||
with convert_api_errors():
|
||||
self.dbx_base.auth_token_revoke()
|
||||
self.cred_storage.delete_creds()
|
||||
self._cred_storage.delete_creds()
|
||||
|
||||
def _init_sdk(
|
||||
self, token: str | None = None, token_type: TokenType | None = None
|
||||
@ -268,13 +270,13 @@ class DropboxClient:
|
||||
if self._dbx:
|
||||
return
|
||||
|
||||
if not (token or self.cred_storage.token):
|
||||
if not (token or self._cred_storage.token):
|
||||
raise NotLinkedError(
|
||||
"No auth token set", "Please link a Dropbox account first."
|
||||
)
|
||||
|
||||
token = token or self.cred_storage.token
|
||||
token_type = token_type or self.cred_storage.token_type
|
||||
token = token or self._cred_storage.token
|
||||
token_type = token_type or self._cred_storage.token_type
|
||||
|
||||
if token_type is TokenType.Offline:
|
||||
|
||||
@ -349,6 +351,7 @@ class DropboxClient:
|
||||
def clone(
|
||||
self,
|
||||
config_name: str | None = None,
|
||||
cred_storage: CredentialStorage | None = None,
|
||||
timeout: float | None = None,
|
||||
session: requests.Session | None = None,
|
||||
) -> DropboxClient:
|
||||
@ -365,8 +368,9 @@ class DropboxClient:
|
||||
config_name = config_name or self.config_name
|
||||
timeout = timeout or self._timeout
|
||||
session = session or self._session
|
||||
cred_storage = cred_storage or self._cred_storage
|
||||
|
||||
client = self.__class__(config_name, timeout, session)
|
||||
client = self.__class__(config_name, cred_storage, timeout, session)
|
||||
|
||||
if self._dbx:
|
||||
client._dbx = self._dbx.clone(session=session)
|
||||
|
@ -28,6 +28,7 @@ from datetime import datetime, timezone
|
||||
# local imports
|
||||
from . import __version__
|
||||
from .client import DropboxClient
|
||||
from .keyring import CredentialStorage
|
||||
from .core import (
|
||||
SharedLinkMetadata,
|
||||
FullAccount,
|
||||
@ -38,7 +39,7 @@ from .core import (
|
||||
LinkAccessLevel,
|
||||
UpdateCheckResult,
|
||||
)
|
||||
from .sync import SyncDirection
|
||||
from .sync import SyncDirection, SyncEngine
|
||||
from .manager import SyncManager
|
||||
from .models import SyncEvent, SyncErrorEntry
|
||||
from .exceptions import (
|
||||
@ -130,13 +131,13 @@ class Maestral:
|
||||
def __init__(
|
||||
self, config_name: str = "maestral", log_to_stderr: bool = False
|
||||
) -> None:
|
||||
|
||||
self._config_name = validate_config_name(config_name)
|
||||
self._conf = MaestralConfig(self._config_name)
|
||||
self._state = MaestralState(self._config_name)
|
||||
self._conf = MaestralConfig(self.config_name)
|
||||
self._state = MaestralState(self.config_name)
|
||||
self.cred_storage = CredentialStorage(self.config_name)
|
||||
|
||||
# Set up logging.
|
||||
self._logger = scoped_logger(__name__, config_name)
|
||||
self._logger = scoped_logger(__name__, self.config_name)
|
||||
self._log_to_stderr = log_to_stderr
|
||||
self._setup_logging()
|
||||
|
||||
@ -144,9 +145,9 @@ class Maestral:
|
||||
self._check_and_run_post_update_scripts()
|
||||
|
||||
# Set up sync infrastructure.
|
||||
self.client = DropboxClient(config_name=self.config_name)
|
||||
self.manager = SyncManager(self.client)
|
||||
self.sync = self.manager.sync
|
||||
self.client = DropboxClient(self.config_name, self.cred_storage)
|
||||
self.sync = SyncEngine(self.client)
|
||||
self.manager = SyncManager(self.sync)
|
||||
|
||||
# Schedule background tasks.
|
||||
self._loop = asyncio.get_event_loop_policy().get_event_loop()
|
||||
@ -217,7 +218,7 @@ class Maestral:
|
||||
self._logger.debug("Could not remove token from keyring", exc_info=True)
|
||||
|
||||
try:
|
||||
self.client.cred_storage.delete_creds()
|
||||
self.cred_storage.delete_creds()
|
||||
except KeyringAccessError:
|
||||
self._logger.debug("Could not remove token from keyring", exc_info=True)
|
||||
|
||||
@ -231,8 +232,8 @@ class Maestral:
|
||||
|
||||
def _setup_logging(self) -> None:
|
||||
"""
|
||||
Sets up logging to log files, status and error properties, desktop notifications,
|
||||
the systemd journal if available, and to stderr if requested.
|
||||
Sets up logging to log files, status and error properties, desktop
|
||||
notifications, the systemd journal if available, and to stderr if requested.
|
||||
"""
|
||||
self._root_logger = scoped_logger("maestral", self.config_name)
|
||||
(
|
||||
@ -1537,7 +1538,7 @@ class Maestral:
|
||||
|
||||
while True:
|
||||
|
||||
if self.client.cred_storage.loaded:
|
||||
if self.cred_storage.loaded:
|
||||
|
||||
# Only run if we have loaded the access token, we don't
|
||||
# want to trigger any keyring access from here.
|
||||
|
@ -15,10 +15,13 @@ from threading import Event, RLock, Thread
|
||||
from tempfile import TemporaryDirectory
|
||||
from typing import Iterator, cast, TypeVar, Callable, Any, Generic
|
||||
|
||||
# external imports
|
||||
from watchdog.observers import Observer
|
||||
|
||||
# local imports
|
||||
from . import __url__
|
||||
from . import notify
|
||||
from .client import DropboxClient, API_HOST
|
||||
from .client import API_HOST
|
||||
from .core import TeamRootInfo, UserRootInfo
|
||||
from .config import MaestralConfig, MaestralState, PersistentMutableSet
|
||||
from .config.user import UserConfig
|
||||
@ -41,7 +44,6 @@ from .exceptions import (
|
||||
DropboxServerError,
|
||||
)
|
||||
from .sync import SyncEngine
|
||||
from .fsevents import Observer
|
||||
from .logging import scoped_logger
|
||||
from .utils import removeprefix
|
||||
from .utils.integration import check_connection, get_inotify_limits
|
||||
@ -119,13 +121,11 @@ class SyncManager:
|
||||
download_queue: PersistentQueue[str]
|
||||
"""Queue of remote paths which have been newly included in syncing."""
|
||||
|
||||
def __init__(self, client: DropboxClient):
|
||||
|
||||
self.client = client
|
||||
self.config_name = self.client.config_name
|
||||
self._conf = MaestralConfig(self.config_name)
|
||||
self._state = MaestralState(self.config_name)
|
||||
self._logger = scoped_logger(__name__, self.config_name)
|
||||
def __init__(self, sync: SyncEngine):
|
||||
self.sync = sync
|
||||
self._conf = MaestralConfig(self.sync.config_name)
|
||||
self._state = MaestralState(self.sync.config_name)
|
||||
self._logger = scoped_logger(__name__, self.sync.config_name)
|
||||
|
||||
self._lock = RLock()
|
||||
|
||||
@ -135,8 +135,6 @@ class SyncManager:
|
||||
|
||||
self.download_queue = PersistentQueue(self._state, "sync", "pending_downloads")
|
||||
|
||||
self.sync = SyncEngine(self.client)
|
||||
|
||||
self._startup_time = -1.0
|
||||
|
||||
self.connection_check_interval = 10
|
||||
@ -449,8 +447,8 @@ class SyncManager:
|
||||
|
||||
self._logger.debug("Checking path root...")
|
||||
|
||||
account_info = self.client.get_account_info()
|
||||
return self.client.namespace_id != account_info.root_info.root_namespace_id
|
||||
account_info = self.sync.client.get_account_info()
|
||||
return self.sync.client.namespace_id != account_info.root_info.root_namespace_id
|
||||
|
||||
def _update_path_root(self) -> None:
|
||||
"""
|
||||
@ -468,8 +466,8 @@ class SyncManager:
|
||||
"Inconsistent namespace information found.",
|
||||
)
|
||||
|
||||
root_info = self.client.account_info.root_info
|
||||
team = self.client.account_info.team
|
||||
root_info = self.sync.client.account_info.root_info
|
||||
team = self.sync.client.account_info.team
|
||||
|
||||
team_name = team.name if team else "team"
|
||||
|
||||
@ -615,7 +613,7 @@ class SyncManager:
|
||||
self.sync.excluded_items = new_excluded
|
||||
|
||||
# Update path root of client.
|
||||
self.client.update_path_root(root_info)
|
||||
self.sync.client.update_path_root(root_info)
|
||||
|
||||
# Trigger reindex.
|
||||
self.sync.reset_sync_state()
|
||||
@ -786,7 +784,7 @@ class SyncManager:
|
||||
# Reload mignore rules.
|
||||
self.sync.load_mignore_file()
|
||||
|
||||
self.client.get_space_usage()
|
||||
self.sync.client.get_space_usage()
|
||||
|
||||
# Update path root and migrate local folders. This is required when a user
|
||||
# joins or leaves a team and their root namespace changes.
|
||||
|
@ -62,7 +62,7 @@ def m(pytestconfig):
|
||||
refresh_token = os.environ.get("DROPBOX_REFRESH_TOKEN")
|
||||
token = access_token or refresh_token
|
||||
token_type = TokenType.Legacy if access_token else TokenType.Offline
|
||||
m.client.cred_storage.save_creds("1234", token, token_type)
|
||||
m.cred_storage.save_creds("1234", token, token_type)
|
||||
m.client.update_path_root()
|
||||
|
||||
# set local Dropbox directory
|
||||
@ -116,7 +116,7 @@ def m(pytestconfig):
|
||||
lock.release()
|
||||
|
||||
# remove creds from system keyring
|
||||
m.client.cred_storage.delete_creds()
|
||||
m.cred_storage.delete_creds()
|
||||
|
||||
|
||||
# helper functions
|
||||
|
@ -11,8 +11,8 @@ from maestral.keyring import TokenType
|
||||
|
||||
|
||||
def fake_linked(m: Maestral, account_info: FullAccount) -> None:
|
||||
m.sync.client.get_account_info = mock.Mock(return_value=account_info) # type: ignore
|
||||
m.sync.client.cred_storage.save_creds("account_id", "1234", TokenType.Offline)
|
||||
m.client.get_account_info = mock.Mock(return_value=account_info) # type: ignore
|
||||
m.cred_storage.save_creds("account_id", "1234", TokenType.Offline)
|
||||
|
||||
|
||||
def verify_folder_structure(root: str, structure: dict) -> None:
|
||||
|
Loading…
Reference in New Issue
Block a user