diff --git a/docs/changes/5.2.5.md b/docs/changes/5.2.5.md index 370b5eb11f..28dc4e7461 100644 --- a/docs/changes/5.2.5.md +++ b/docs/changes/5.2.5.md @@ -46,6 +46,7 @@ Release date: `2021-xx-xx` ## Technical Changes +- Added `EngineDAO.get_local_roots_names()` - Added `Options.sync_root_max_level` - Added `Remote.expand_sync_root_name()` - Added `Remote.is_sync_root()` diff --git a/nxdrive/client/remote_client.py b/nxdrive/client/remote_client.py index bafd63eed4..d6500e0dc8 100644 --- a/nxdrive/client/remote_client.py +++ b/nxdrive/client/remote_client.py @@ -567,7 +567,7 @@ def expand_sync_root_name(self, sync_root: RemoteFileInfo) -> RemoteFileInfo: """ glue = " - " level = 0 - limit = 50 - len(glue) + limit = 49 - len(glue) uid = sync_root.uid.split("#")[-1] # Be sure the current name is shortened @@ -594,6 +594,14 @@ def expand_sync_root_name(self, sync_root: RemoteFileInfo) -> RemoteFileInfo: sync_root.name = f"{name}{glue}{sync_root.name}" level += 1 + local_roots = self.dao.get_local_roots_names() + if sync_root.name not in local_roots: + return sync_root + for n in range(1, 100): + if f"{sync_root.name}_{n}" not in local_roots: + sync_root.name = f"{sync_root.name}_{n}" + return sync_root + sync_root.name = f"{sync_root.name}_{n}" return sync_root def get_fs_info( diff --git a/nxdrive/dao/engine.py b/nxdrive/dao/engine.py index 9e2b3364bf..acb3965a28 100644 --- a/nxdrive/dao/engine.py +++ b/nxdrive/dao/engine.py @@ -25,7 +25,7 @@ from nuxeo.utils import get_digest_algorithm from ..client.local import FileInfo -from ..constants import ROOT, UNACCESSIBLE_HASH, WINDOWS, TransferStatus +from ..constants import ROOT, SYNC_ROOT, UNACCESSIBLE_HASH, WINDOWS, TransferStatus from ..exceptions import UnknownPairState from ..objects import ( DocPair, @@ -1176,6 +1176,13 @@ def get_local_children(self, path: Path, /) -> DocPairs: "SELECT * FROM States WHERE local_parent_path = ?", (path,) ).fetchall() + def get_local_roots_names(self) -> List[str]: + c = self._get_read_connection().cursor() + root_list = c.execute( + f"SELECT local_name FROM States WHERE remote_parent_path = '{SYNC_ROOT}'" + ).fetchall() + return [item[0] for item in root_list] + def get_states_from_partial_local( self, path: Path, /, *, strict: bool = True ) -> DocPairs: diff --git a/nxdrive/engine/watcher/remote_watcher.py b/nxdrive/engine/watcher/remote_watcher.py index 0561b6042b..b01d496423 100644 --- a/nxdrive/engine/watcher/remote_watcher.py +++ b/nxdrive/engine/watcher/remote_watcher.py @@ -22,6 +22,7 @@ DOCUMENT_LOCKED, DOCUMENT_MOVED, DOCUMENT_UNLOCKED, + ROOT_REGISTERED, SECURITY_UPDATED_EVENT, ) @@ -908,10 +909,6 @@ def _update_remote_states(self) -> None: # Perform a regular document update on a document # that has been updated, renamed or moved - # Keep the sync root name format as expected - if self.engine.remote.is_sync_root(new_info): - self.engine.remote.expand_sync_root_name(new_info) - if doc_pair.remote_state != "created" and any( ( new_info.digest != doc_pair.remote_digest, @@ -1009,6 +1006,14 @@ def _update_remote_states(self) -> None: if new_info and not updated: # Handle new document creations created = False + + # Keep the sync root name format as expected + if ( + self.engine.remote.is_sync_root(new_info) + and event_id == ROOT_REGISTERED + ): + self.engine.remote.expand_sync_root_name(new_info) + parent_pairs = self.dao.get_states_from_remote(new_info.parent_uid) for parent_pair in parent_pairs: match_pair = self._find_remote_child_match_or_create( diff --git a/tests/functional/test_remote_client.py b/tests/functional/test_remote_client.py index 9c46617781..4c8cdd3898 100644 --- a/tests/functional/test_remote_client.py +++ b/tests/functional/test_remote_client.py @@ -132,7 +132,7 @@ def test_expand_sync_root_name_length(option, manager_factory, obj_factory): potential_names = [] for num in range(option + 1): title = "folder" + "r" * 50 + f" {num}" # > 50 chars - potential_names.append(shortify(title, limit=47)) + potential_names.append(shortify(title, limit=46)) doc = obj_factory(title=title, parent=parent, user=remote.user_id) parent = doc.path