Skip to content

Commit

Permalink
NXDRIVE-2800: Do not rename locally when the document is updated (#3870)
Browse files Browse the repository at this point in the history
* NXDRIVE-2800: Do not rename locally when the document is updated
  • Loading branch information
gitofanindya committed Apr 20, 2023
1 parent c97847d commit 0c5ab6f
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 55 deletions.
1 change: 1 addition & 0 deletions docs/changes/5.3.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Release date: `2023-xx-xx`

- [NXDRIVE-2772](https://jira.nuxeo.com/browse/NXDRIVE-2772): Sync icons disappear after restart
- [NXDRIVE-2801](https://jira.nuxeo.com/browse/NXDRIVE-2801): Do not prefix synchronized folder name with ancestors when there is no duplicated root
- [NXDRIVE-2800](https://jira.nuxeo.com/browse/NXDRIVE-2800): Do not rename locally when the document is updated
- [NXDRIVE-2764](https://jira.nuxeo.com/browse/NXDRIVE-2764): Fix handling of special and non-English characters in document names

### Direct Edit
Expand Down
8 changes: 0 additions & 8 deletions nxdrive/client/remote_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -632,14 +632,6 @@ 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(
Expand Down
2 changes: 2 additions & 0 deletions nxdrive/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@

SYNC_ROOT = "/org.nuxeo.drive.service.impl.DefaultTopLevelFolderItemFactory#"

WORKSPACE_ROOT = "defaultSyncRootFolderItemFactory"

# Document's UID and token regexp
DOC_UID_REG = "[0-f]{8}-[0-f]{4}-[0-f]{4}-[0-f]{4}-[0-f]{12}"

Expand Down
9 changes: 1 addition & 8 deletions nxdrive/dao/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

from .. import __version__
from ..client.local import FileInfo
from ..constants import ROOT, SYNC_ROOT, UNACCESSIBLE_HASH, WINDOWS, TransferStatus
from ..constants import ROOT, UNACCESSIBLE_HASH, WINDOWS, TransferStatus
from ..exceptions import UnknownPairState
from ..objects import (
DocPair,
Expand Down Expand Up @@ -1192,13 +1192,6 @@ 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:
Expand Down
7 changes: 0 additions & 7 deletions nxdrive/engine/processor.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import errno
import os
import shutil
import sqlite3
import sys
Expand Down Expand Up @@ -1464,12 +1463,6 @@ def _create_remotely(
self._unlock_readonly(local_parent_path)
try:
if doc_pair.folderish:
if "Workspaces - " in name and "defaultSyncRoot" in doc_pair.remote_ref:
partitioned_name = name.partition("Workspaces - ")
new_name = partitioned_name[2]
folder_path = os.path.join(local_parent_path, new_name)
if not self.local.exists(folder_path):
name = new_name
log.info(
f"Creating local folder {name!r} "
f"in {self.local.abspath(local_parent_path)!r}"
Expand Down
17 changes: 8 additions & 9 deletions nxdrive/engine/watcher/remote_watcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from nuxeo.exceptions import BadQuery, HTTPError, Unauthorized

from ...client.local import FileInfo
from ...constants import BATCH_SIZE, CONNECTION_ERROR, ROOT, WINDOWS
from ...constants import BATCH_SIZE, CONNECTION_ERROR, ROOT, WINDOWS, WORKSPACE_ROOT
from ...exceptions import NotFound, ScrollDescendantsError, ThreadInterrupt
from ...feature import Feature
from ...objects import DocPair, DocPairs, Metrics, RemoteFileInfo
Expand Down Expand Up @@ -795,6 +795,13 @@ def _update_remote_states(self) -> None:
continue

new_info = RemoteFileInfo.from_dict(fs_item) if fs_item else None
if new_info and (
self.engine.remote.is_sync_root(new_info)
or WORKSPACE_ROOT in new_info.uid
or event_id == ROOT_REGISTERED
):
new_info = self.engine.remote.expand_sync_root_name(new_info)

if self.filtered(new_info):
log.info(f"Ignoring banned file: {new_info!r}")
continue
Expand Down Expand Up @@ -1006,14 +1013,6 @@ 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(
Expand Down
23 changes: 0 additions & 23 deletions tests/functional/test_create_sync_folder.py

This file was deleted.

102 changes: 102 additions & 0 deletions tests/functional/test_remote_watcher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
from collections import namedtuple
from unittest.mock import patch

from nxdrive.engine.watcher.remote_watcher import RemoteWatcher


def test_sync_root_name(manager_factory):
manager, engine = manager_factory()
dao = engine.dao

docpair = namedtuple(
"DocPair",
"local_path, local_parent_path, remote_ref, local_state, \
remote_state, pair_state, last_error, remote_parent_path",
defaults=(
".",
".",
"org.nuxeo.drive.service.impl.DefaultTopLevelFolderItemFactory#",
"synchronized",
"synchronized",
"synchronized",
None,
"",
),
)
test_watcher = RemoteWatcher(engine, dao)

def get_changes():
return eval(
'{ "type": "test", "fileSystemChanges": [ { "repositoryId": "default", \
"eventId": "securityUpdated", "eventDate": 1681875648592, "docUuid": \
"a7e4ce2a-e4a7-432a-b5e1-62b354606929", "fileSystemItem": {"id": \
"defaultSyncRootFolderItemFactory#default#a7e4ce2a-e4a7-432a-\
b5e1-62b354606929-test", "parentId": "org.nuxeo.drive.service.\
impl.DefaultTopLevelFolderItemFactory#", "name": "ROY", \
"folder": True, "creator": "Administrator", \
"lastContributor": "Administrator", \
"creationDate": 1681875486061, \
"lastModificationDate": 1681875528408, \
"canRename": True, "canDelete": True, \
"lockInfo": None, "path": "/org.nuxeo.\
drive.service.impl.DefaultTopLevelFolder\
ItemFactory#/defaultSyncRootFolderItemFactory\
#default#a7e4ce2a-e4a7-432a-b5e1-62b354606929-test",\
"userName": "Administrator", "canCreateChild": True,\
"canScrollDescendants": True }, "fileSystemItemId": \
"defaultSyncRootFolderItemFactory#default#a7e4ce2a-\
e4a7-432a-b5e1-62b354606929-test", \
"fileSystemItemName": "ROY" } ]\
, "syncDate": 1681875652000, "upp\
erBound": 7834,\
"hasTooManyChanges": True, \
"activeSynchronizationRootDe\
finitions": "default:ffed6ec7-\
b6d3-41a7-ba10-801b7678a5\
84-test,default:a7e4ce2a-e4a7-432a-b5e1-62b35460692\
9-test,default:db4e8005-c7aa-4f26-937b-23476e85\
2223-test,default:47176834-992d-4d81-9ce1-a\
51b7841d648-test" }'
)

def get_states_from_remote_(path):
return [docpair]

def update_remote_state_(*args, **kwargs):
return False

def unset_unsychronised_(*args):
return

def _force_remote_scan_(*args, **kwargs):
return

def get_state_from_id_(*args):
return None

def _find_remote_child_match_or_create_(parent_pair, new_info):
assert "test" in new_info.id
return None

update_remote_states = test_watcher._update_remote_states

with patch.object(test_watcher, "_get_changes", new=get_changes):
with patch.object(test_watcher, "_force_remote_scan", new=_force_remote_scan_):
with patch.object(
test_watcher,
"_find_remote_child_match_or_create",
new=_find_remote_child_match_or_create_,
):
with patch.object(
dao, "get_states_from_remote", new=get_states_from_remote_
):
with patch.object(
dao, "update_remote_state", new=update_remote_state_
):
with patch.object(
dao, "unset_unsychronised", new=unset_unsychronised_
):
with patch.object(
dao, "get_state_from_id", new=get_state_from_id_
):
update_remote_states

0 comments on commit 0c5ab6f

Please sign in to comment.