Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NXDRIVE-2942: Improve folder selection on Direct Transfer screen #5139

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/changes/5.5.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Release date: `2024-xx-xx`

### Direct Transfer

- [NXDRIVE-2](https://jira.nuxeo.com/browse/NXDRIVE-2):
- [NXDRIVE-2942](https://jira.nuxeo.com/browse/NXDRIVE-2942): Improve folder selection on Direct Transfer screen

### Task Management
- [NXDRIVE-2](https://jira.nuxeo.com/browse/NXDRIVE-2):
Expand Down
1 change: 1 addition & 0 deletions nxdrive/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
In this file we cannot use a relative import here, else Drive will not start when packaged.
See https://github.com/pyinstaller/pyinstaller/issues/2560
"""

import locale
import platform
import signal
Expand Down
1 change: 1 addition & 0 deletions nxdrive/behavior.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
Allow or disallow server deletions.

"""

from types import SimpleNamespace

Behavior = SimpleNamespace(server_deletion=True)
1 change: 1 addition & 0 deletions nxdrive/client/local/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""" API to access local resources for synchronization. """

from .base import FileInfo, get

# Get the local client related to the current OS
Expand Down
1 change: 1 addition & 0 deletions nxdrive/client/uploader/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Uploader used by the Remote client for all upload stuff.
"""

import json
from abc import abstractmethod
from logging import getLogger
Expand Down
1 change: 1 addition & 0 deletions nxdrive/client/uploader/direct_transfer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Uploader used by the Direct Transfer feature.
"""

import json
from logging import getLogger
from pathlib import Path
Expand Down
1 change: 1 addition & 0 deletions nxdrive/client/uploader/sync.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Uploader used by the synchronization engine.
"""

from pathlib import Path
from typing import Any, Dict, Optional

Expand Down
2 changes: 2 additions & 0 deletions nxdrive/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
errno.ERANGE, # Result too large
}

QUERY_ENDPOINT = "/api/v1/search/lang/NXQL/execute?query="

# OSError indicating the incapacity to do anything because of too long file name or deep tree
LONG_FILE_ERRORS = {errno.ENAMETOOLONG}
if WINDOWS:
Expand Down
1 change: 1 addition & 0 deletions nxdrive/dao/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Query formatting in this file is based on http://www.sqlstyle.guide/
"""

import sys
from contextlib import suppress
from logging import getLogger
Expand Down
1 change: 1 addition & 0 deletions nxdrive/dao/engine.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Query formatting in this file is based on http://www.sqlstyle.guide/
"""

import json
import os
import shutil
Expand Down
1 change: 1 addition & 0 deletions nxdrive/dao/manager.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Query formatting in this file is based on http://www.sqlstyle.guide/
"""

from logging import getLogger
from pathlib import Path
from sqlite3 import Cursor, IntegrityError, Row
Expand Down
4 changes: 1 addition & 3 deletions nxdrive/engine/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -838,9 +838,7 @@ def resume_transfer(
meth = (
self.dao.get_download
if nature == "download"
else self.dao.get_dt_upload
if is_direct_transfer
else self.dao.get_upload
else self.dao.get_dt_upload if is_direct_transfer else self.dao.get_upload
)
func = partial(meth, uid=uid) # type: ignore
self._resume_transfers(nature, func, is_direct_transfer=is_direct_transfer)
Expand Down
1 change: 1 addition & 0 deletions nxdrive/fatal_error.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Fatal error screen management using either Qt or OS-specific dialogs.
"""

import sys
from contextlib import suppress
from pathlib import Path
Expand Down
1 change: 1 addition & 0 deletions nxdrive/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
Enable or disable the synchronization features.

"""

from types import SimpleNamespace
from typing import List

Expand Down
1 change: 1 addition & 0 deletions nxdrive/gui/application.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""" Main Qt application handling OS events and system tray UI. """

import os
import webbrowser
from contextlib import suppress
Expand Down
29 changes: 25 additions & 4 deletions nxdrive/gui/folders_model.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from logging import getLogger
from typing import Iterator, List, Union
from typing import Any, Iterator, List, Union

from nuxeo.models import Document

Expand Down Expand Up @@ -213,10 +213,12 @@

def __init__(self, remote: Remote, /) -> None:
self.remote = remote
self.personal_space_uid = ""

def get_personal_space(self) -> "Documents":
"""Retrieve the "Personal space" special folder."""
personal_space = self.remote.personal_space()
self.personal_space_uid = personal_space.uid

Check warning on line 221 in nxdrive/gui/folders_model.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/folders_model.py#L221

Added line #L221 was not covered by tests

# Alter the title to use "Personal space" instead of "Firstname Lastname"
personal_space.title = Translator.get("PERSONAL_SPACE")
Expand Down Expand Up @@ -247,18 +249,37 @@
)
)

def get_roots(self) -> List[Any]:
from ..constants import QUERY_ENDPOINT

Check warning on line 253 in nxdrive/gui/folders_model.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/folders_model.py#L253

Added line #L253 was not covered by tests

url = (

Check warning on line 255 in nxdrive/gui/folders_model.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/folders_model.py#L255

Added line #L255 was not covered by tests
f"{QUERY_ENDPOINT}select * from Document WHERE ecm:mixinType = 'Folderish'"
)
return self.remote.client.request("GET", url).json()["entries"]

Check warning on line 258 in nxdrive/gui/folders_model.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/folders_model.py#L258

Added line #L258 was not covered by tests

def _get_root_folders(self) -> List["Documents"]:
"""Get root folders.
Use a try...except block to prevent loading error on the root,
else it will also show a loading error for the personal space.
"""
root_details = []
returned_folders = []

Check warning on line 266 in nxdrive/gui/folders_model.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/folders_model.py#L265-L266

Added lines #L265 - L266 were not covered by tests
try:
root = self.remote.documents.get(path="/")
return [Doc(doc) for doc in self._get_children(root.uid)]
roots = self.get_roots()
for root in roots:
if (

Check warning on line 270 in nxdrive/gui/folders_model.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/folders_model.py#L268-L270

Added lines #L268 - L270 were not covered by tests
root["type"] == "Workspace"
and root["uid"] != self.personal_space_uid
):
for doc in self._get_children(root["parentRef"]):
if doc.title not in returned_folders:
returned_folders.append(doc.title)
yield Doc(doc)

Check warning on line 277 in nxdrive/gui/folders_model.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/folders_model.py#L274-L277

Added lines #L274 - L277 were not covered by tests
except Exception:
log.warning("Error while retrieving documents on '/'", exc_info=True)
context = {"permissions": [], "hasFolderishChild": False}
return [Doc(Document(title="/", contextParameters=context))]
root_details.append([Doc(Document(title="/", contextParameters=context))])
return root_details

Check warning on line 282 in nxdrive/gui/folders_model.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/folders_model.py#L281-L282

Added lines #L281 - L282 were not covered by tests

def get_top_documents(self) -> Iterator["Documents"]:
"""Fetch all documents at the root."""
Expand Down
1 change: 1 addition & 0 deletions nxdrive/osi/darwin/pyNotificationCenter.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""" Python integration macOS notification center. """

from typing import TYPE_CHECKING, Dict

from CoreServices import (
Expand Down
1 change: 1 addition & 0 deletions nxdrive/qt/constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Put here all PyQt constants used across the project.
"""

from .imports import (
QAbstractSocket,
QDialogButtonBox,
Expand Down
1 change: 1 addition & 0 deletions nxdrive/qt/imports.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Put here all PyQt imports used across the project.
"""

from PyQt5.QtCore import (
QT_VERSION_STR,
QAbstractListModel,
Expand Down
1 change: 1 addition & 0 deletions nxdrive/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
This state is set at the start of the application to know if it has crashed at the previous run.

"""

from types import SimpleNamespace

State = SimpleNamespace(about_to_quit=False, crash_details="", has_crashed=False)
1 change: 1 addition & 0 deletions nxdrive/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Most of functions are pure enough to be decorated with a LRU cache.
Each *maxsize* is adjusted depending of the heavy use of the decorated function.
"""

import os
import os.path
import re
Expand Down
1 change: 1 addition & 0 deletions tests/benchmarks/test_safe_filename.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
If is not the most efficient for small ASCII-only filenames,
but it is the best when there are non-ASCII characters.
"""

import pytest

FILENAMES = [
Expand Down
1 change: 1 addition & 0 deletions tests/cleanup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Cleanup old test users and workspaces."""

import env
from nuxeo.client import Nuxeo

Expand Down
31 changes: 31 additions & 0 deletions tests/functional/test_folders_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from unittest.mock import Mock, patch

from nxdrive.gui.folders_model import FoldersOnly


def test_folders_only():
def request_(*args, **kwargs):
return {
"entries": [
{
"entity-type": "document",
"uid": "11be49d0-875e-4054-a353-eff47b7358b3",
"path": "/default-domain/workspaces/Shared_WSP",
"type": "Workspace",
"parentRef": "e537253c-c59a-411a-a96a-25f972b4c22a",
"title": "Shared_WSP",
"facets": ["Folderish", "NXTag", "SuperSpace"],
}
]
}

def request_with_error(*args, **kwargs):
return 1 / 0

folders_only = FoldersOnly(Mock())

with patch.object(folders_only.remote.client, "request", new=request_):
assert folders_only._get_root_folders()

with patch.object(folders_only.remote.client, "request", new=request_with_error):
assert folders_only._get_root_folders()
6 changes: 3 additions & 3 deletions tests/integration/windows/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,12 @@ def test_argument_log_filename(exe, tmp, file):
with exe(args=arg) as app:
assert not fatal_error_dlg(app)
share_metrics_dlg(app)

assert log.is_file()


@pytest.mark.parametrize("folder", ["azerty", "$alice", "léa", "mi Kaël", "こん ツリ ^^"])
@pytest.mark.parametrize(
"folder", ["azerty", "$alice", "léa", "mi Kaël", "こん ツリ ^^"]
)
def test_argument_nxdrive_home(exe, tmp, folder):
path = tmp()
path.mkdir(parents=True, exist_ok=True)
Expand All @@ -119,7 +120,6 @@ def test_argument_nxdrive_home(exe, tmp, folder):
with exe(args=arg) as app:
assert not fatal_error_dlg(app)
share_metrics_dlg(app)

assert home.is_dir()


Expand Down
1 change: 1 addition & 0 deletions tests/markers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Collection of pytest markers to ease test filtering."""

import os

import pytest
Expand Down
1 change: 1 addition & 0 deletions tests/old_functional/common.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""" Common test utilities. """

import os
import sys
import tempfile
Expand Down
1 change: 1 addition & 0 deletions tests/old_functional/test_behavior.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Test application Behavior.
"""

from nxdrive.behavior import Behavior

from .. import ensure_no_exception
Expand Down
1 change: 1 addition & 0 deletions tests/old_functional/test_direct_transfer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Test the Direct Transfer feature in different scenarii.
"""

import logging
import re
from pathlib import Path
Expand Down
1 change: 1 addition & 0 deletions tests/old_functional/test_local_changes_when_offline.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Test if changes made to local file system when Drive is offline sync's back
later when Drive becomes online.
"""

import pytest

from nxdrive.constants import WINDOWS
Expand Down
1 change: 1 addition & 0 deletions tests/old_functional/test_local_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

See NXDRIVE-742.
"""

import hashlib
import os
from pathlib import Path
Expand Down
1 change: 1 addition & 0 deletions tests/old_functional/test_synchronization_dedup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Test behaviors when the server allows duplicates and not the client.
"""

from pathlib import Path

import pytest
Expand Down
1 change: 1 addition & 0 deletions tests/old_functional/test_transfer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Test pause/resume transfers in different scenarii.
"""

import re
from unittest.mock import patch

Expand Down
1 change: 1 addition & 0 deletions tests/unit/test_autolock.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Test the Auto-Lock feature used heavily by Direct Edit.
"""

from pathlib import Path
from typing import List, Tuple
from unittest.mock import Mock, patch
Expand Down
1 change: 1 addition & 0 deletions tests/unit/test_pytest_random.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Tests for pytests_random: a pytest plugin to mitigate random failures.
Adapted from github.com/pytest-dev/pytest-rerunfailures
"""

import pytest

pytest_plugins = "pytester"
Expand Down
1 change: 1 addition & 0 deletions tools/cleanup_application_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Remove files from the package that are not needed and too big.
This script can be launched after PyInstaller and before installers creation.
"""

import os
import shutil
import sys
Expand Down
1 change: 1 addition & 0 deletions tools/jenkins/junit/merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
Léa Klein
Mickaël Schoentgen <[email protected]>
"""

import os
import sys
from pathlib import Path
Expand Down
1 change: 1 addition & 0 deletions tools/scripts/csv_to_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Convert a CSV "log" file to a real log file.
Such files are ones attached to NCO tickets.
"""

import csv
import sys
from pathlib import Path
Expand Down