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

test Demo #4701

Closed
wants to merge 16 commits into from
2 changes: 2 additions & 0 deletions nxdrive/data/i18n/i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@
"OTHER": "Other",
"PASSWORD": "Password",
"PERSONAL_SPACE": "Personal space",
"PENDING_DOCUMENT_REVIEWS": "Awaiting document review for \"%1\" ",
"PROXY": "Proxy",
"PROXY_APPLIED": "Proxy settings have been updated",
"PROXY_CHANGE_SETTINGS": "Proxy",
Expand Down Expand Up @@ -366,6 +367,7 @@
"SYNCHRONIZATION_IN_PROGRESS": "Synchronization in progress",
"SYNCHRONIZATION_ITEMS_LEFT": "Remaining items: %1",
"SYSTEM": "System",
"TASK_MAMNAGER_WINDOW_TITLE": "Task Manager",
"TECHNICAL_DETAILS": "Technical details:",
"TYPE": "Type",
"UNAUTHORIZED": "Incorrect credentials",
Expand Down
16 changes: 16 additions & 0 deletions nxdrive/data/qml/Main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,20 @@ QtObject {

DirectTransfer { id: directTransfer }
}

property var taskManagerWindow: CustomWindow {
id: taskManagerWindow
minimumWidth: 600
minimumHeight: 480
objectName: "taskManagerWindow"
title: qsTr("TASK_MAMNAGER_WINDOW_TITLE").arg(APP_NAME) + tl.tr
width: taskManager.width; height: taskManager.height
visible: false

signal setEngine(string uid)

onSetEngine: taskManagerWindow.setEngine(uid)

TaskManager { id: taskManager }
}
}
8 changes: 8 additions & 0 deletions nxdrive/data/qml/SystrayMenu.qml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ ShadowRectangle {
ColumnLayout {
id: menuContent
spacing: 0

SystrayMenuItem {
text: qsTr("Tasks")
onClicked: {
api.show_tasks("Tasks Manager")
control.visible = false
}
}

SystrayMenuItem {
text: qsTr("SETTINGS") + tl.tr
Expand Down
51 changes: 51 additions & 0 deletions nxdrive/data/qml/TaskManager.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.15
import "icon-font/Icon.js" as MdiFont



Rectangle {
id: taskManager
anchors.fill: parent

property string engineUid: ""
property int activeSessionsCount: 0
property int completedSessionsCount: 0
property double startTime: 0.0

signal setEngine(string uid)

onSetEngine: {
engineUid = uid
}

TabBar {
id: bar
width: parent.width
height: 50
spacing: 0

anchors.top: buttonzone.bottom

SettingsTab {
text: qsTr("Tasks") + tl.tr
barIndex: bar.currentIndex;
index: 0
anchors.top: parent.top
}

}

Text {
anchors.fill: parent
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
height: 100
/*textFormat: Text.RichText*/
text: api.get_title(engineUid)
font.pointSize: point_size * 1.2
color: primaryText
}
}
25 changes: 25 additions & 0 deletions nxdrive/engine/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
directTransferNewFolderError = pyqtSignal()
directTransferNewFolderSuccess = pyqtSignal(str)
directTransferSessionFinished = pyqtSignal(str, str, str)
displayPendingTask = pyqtSignal(str, str)

type = "NXDRIVE"
# Folder locker - LocalFolder processor can prevent
Expand Down Expand Up @@ -199,6 +200,7 @@
self.remote = self.init_remote()

self._create_queue_manager()

if Feature.synchronization:
self._create_remote_watcher()
self._create_local_watcher()
Expand Down Expand Up @@ -629,6 +631,9 @@
# And add new pairs to the queue
self.dao.queue_many_direct_transfer_items(current_max_row_id)

def fetch_pending_task_list(self, task_id: str) -> None:
self.displayPendingTask.emit(self.uid, task_id)

Check warning on line 635 in nxdrive/engine/engine.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/engine/engine.py#L635

Added line #L635 was not covered by tests

def handle_session_status(self, session: Optional[Session], /) -> None:
"""Check the session status and send a notification if finished."""
if not session or session.status is not TransferStatus.DONE:
Expand Down Expand Up @@ -747,6 +752,26 @@
}
return urls[self.force_ui or self.wui]

def get_task_url(self, remote_ref: str, /, *, edit: bool = False) -> str:
"""
Build the document's metadata URL based on the server's UI.
Default is Web-UI. In case of unknown UI, use the default value.

:param remote_ref: The document remote reference (UID) of the
document we want to show metadata.
:param edit: Show the metadata edit page instead of the document.
:return: The complete URL.
"""
# uid = remote_ref.split("#")[-1]
repo = self.remote.client.repository
page = ("view_documents", "view_drive_metadata")[edit]

Check warning on line 767 in nxdrive/engine/engine.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/engine/engine.py#L766-L767

Added lines #L766 - L767 were not covered by tests

urls = {

Check warning on line 769 in nxdrive/engine/engine.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/engine/engine.py#L769

Added line #L769 was not covered by tests
"jsf": f"{self.server_url}tasks/{repo}/{remote_ref}/{page}",
"web": f"{self.server_url}ui#!/tasks/{remote_ref}",
}
return urls[self.force_ui or self.wui]

Check warning on line 773 in nxdrive/engine/engine.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/engine/engine.py#L773

Added line #L773 was not covered by tests

def is_syncing(self) -> bool:
return self._sync_started

Expand Down
84 changes: 83 additions & 1 deletion nxdrive/gui/api.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# flake8: noqa

import json
from dataclasses import asdict
from logging import getLogger
Expand All @@ -21,6 +23,7 @@
TransferStatus,
)
from ..dao.engine import EngineDAO
from ..engine.engine import Engine
from ..exceptions import (
AddonForbiddenError,
AddonNotInstalledError,
Expand Down Expand Up @@ -305,6 +308,7 @@
engine = self._manager.engines.get(uid)
if engine:
path = engine.local.abspath(Path(ref))
self.fetch_pending_tasks(engine)

Check warning on line 311 in nxdrive/gui/api.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/api.py#L311

Added line #L311 was not covered by tests
self.application.show_metadata(path)

@pyqtSlot(str, result=list)
Expand Down Expand Up @@ -457,6 +461,43 @@
self.application.hide_systray()
log.info(f"Show settings on section {section}")
self.application.show_settings(section)

@pyqtSlot(str)
def show_tasks(self, section: str, /) -> None:
self.application.hide_systray()
log.info(f"Show Task Manager {section}")
self.application.show_tasks(section)

Check warning on line 469 in nxdrive/gui/api.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/api.py#L467-L469

Added lines #L467 - L469 were not covered by tests

@pyqtSlot()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): The new implementation introduces several areas that could be improved for better maintainability, security, and readability:

  1. Increased Code Length and Complexity: The addition of multiple new methods and direct HTTP requests within these methods significantly increases the code's complexity. Consider abstracting the HTTP request logic into a separate method to reduce repetition and improve readability.

  2. Direct HTTP Requests and Hardcoded Values: The code now directly performs HTTP requests with hardcoded URLs and credentials. This approach tightly couples your class with specific implementation details and reduces flexibility. It's also a security risk to have credentials hardcoded. Consider using environment variables or a configuration file for sensitive information and abstracting the HTTP logic to make the code more secure and adaptable.

  3. Error Handling: The broad use of try-except blocks, especially catching a general Exception, can make debugging more challenging as it may obscure the source of errors. It's usually better to catch specific exceptions. Also, consider logging the errors or providing feedback in a way that aids in diagnosing issues without making the error handling overly complex.

  4. Repetition: There's noticeable repetition, especially in constructing HTTP request headers and handling responses. Adhering to the DRY (Don't Repeat Yourself) principle can make your code less verbose and easier to maintain. A single method to handle HTTP requests could simplify these operations and centralize changes needed in the future.

By addressing these points, the code can become more maintainable, secure, and easier to understand. Simplifying the error handling, removing hardcoded values, and reducing repetition are key steps in improving the overall quality of the implementation.

def fetch_pending_tasks(self, engine: Engine, /) -> None:
log.info("Check for pending approval tasks")
endpoint = "/api/v1/task/"
url = "http://localhost:8080/nuxeo" + endpoint
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code-quality): Use f-string instead of string concatenation (use-fstring-for-concatenation)

Suggested change
url = "http://localhost:8080/nuxeo" + endpoint
url = f"http://localhost:8080/nuxeo{endpoint}"

headers = {

Check warning on line 476 in nxdrive/gui/api.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/api.py#L473-L476

Added lines #L473 - L476 were not covered by tests
"Accept": "application/json",
"Content-Type": "application/json",
}
try:

Check warning on line 480 in nxdrive/gui/api.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/api.py#L480

Added line #L480 was not covered by tests
# response = NuxeoClient.request(self,method="GET", path=endpoint, headers=headers, ssl_verify=Options.ssl_no_verify)
response = requests.get(

Check warning on line 482 in nxdrive/gui/api.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/api.py#L482

Added line #L482 was not covered by tests
url=url,
verify=True,
timeout=3600,
headers=headers,
auth=("Administrator", "Administrator"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 issue (security): Hard-coded credentials detected. It's highly insecure to hard-code credentials within the codebase. Consider using environment variables or a secure vault service for storing credentials.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 issue (security): Hard-coded credentials detected. It's highly insecure to hard-code credentials within the codebase. Consider using environment variables or a secure vault service for storing credentials.

)
Comment on lines +482 to +488
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (performance): The fetch_pending_tasks method uses a very long timeout value (3600 seconds). While this might be necessary in some cases, it could also lead to the application appearing unresponsive if the server takes a long time to respond. Consider allowing this value to be configurable or implementing a more dynamic timeout strategy.

log.info(f">>>>> response type: {type(response)}")
data = response.json()
log.info(f">>>> response: {data}")
if data["resultsCount"] > 0:
log.info("Send pending task notification")
for task in data["entries"]:
log.info(f">>>> task: {task}")
log.info(f">>>> taskid: {task['id']}")
engine.fetch_pending_task_list(task["id"])

Check warning on line 497 in nxdrive/gui/api.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/api.py#L489-L497

Added lines #L489 - L497 were not covered by tests
Comment on lines +492 to +497
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (edge_case_not_handled): The fetch_pending_tasks method assumes that the response will always contain a resultsCount and entries fields. It's a good practice to add error handling for cases where these fields might be missing or not in the expected format to prevent runtime errors.


except Exception:
log.exception("Unable to fetch tasks")

Check warning on line 500 in nxdrive/gui/api.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/api.py#L499-L500

Added lines #L499 - L500 were not covered by tests
Comment on lines +472 to +500
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 suggestion (security): Hardcoding the URL and credentials within the fetch_pending_tasks method could pose a security risk and limit flexibility. Consider externalizing these values to a configuration file or environment variables to enhance security and make the application more adaptable to different environments.

Comment on lines +473 to +500
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code_refinement): The use of a hardcoded URL (http://localhost:8080/nuxeo) in the fetch_pending_tasks method might not be suitable for production environments. It's recommended to use a configurable endpoint to ensure the application can be easily adapted to different server configurations without requiring code changes.


@pyqtSlot()
def quit(self) -> None:
Expand Down Expand Up @@ -576,7 +617,9 @@
def _balance_percents(self, result: Dict[str, float], /) -> Dict[str, float]:
"""Return an altered version of the dict in which no value is under a minimum threshold."""

result = {k: v for k, v in sorted(result.items(), key=lambda item: item[1])}
result = {

Check warning on line 620 in nxdrive/gui/api.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/api.py#L620

Added line #L620 was not covered by tests
k: v for k, v in sorted(result.items(), key=lambda item: item[1])
} # noqa
Comment on lines +620 to +622
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code-quality): Replace identity comprehension with call to collection constructor (identity-comprehension)

Suggested change
result = {
k: v for k, v in sorted(result.items(), key=lambda item: item[1])
} # noqa
result = dict(sorted(result.items(), key=lambda item: item[1]))


ExplanationConvert list/set/tuple comprehensions that do not change the input elements into.

Before

# List comprehensions
[item for item in coll]
[item for item in friends.names()]

# Dict comprehensions
{k: v for k, v in coll}
{k: v for k, v in coll.items()}  # Only if we know coll is a `dict`

# Unneeded call to `.items()`
dict(coll.items())  # Only if we know coll is a `dict`

# Set comprehensions
{item for item in coll}

After

# List comprehensions
list(iter(coll))
list(iter(friends.names()))

# Dict comprehensions
dict(coll)
dict(coll)

# Unneeded call to `.items()`
dict(coll)

# Set comprehensions
set(coll)

All these comprehensions are just creating a copy of the original collection.
They can all be simplified by simply constructing a new collection directly. The
resulting code is easier to read and shows the intent more clearly.

keys = list(result)
min_threshold = 10
data = 0.0
Expand Down Expand Up @@ -1099,8 +1142,47 @@
except OSError:
log.exception("Remote document cannot be opened")

@pyqtSlot(str, str, str)
def display_pending_task(self, uid: str, remote_ref: str, /) -> None:
log.info(f"Should open remote document ({remote_ref!r})")

Check warning on line 1147 in nxdrive/gui/api.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/api.py#L1145-L1147

Added lines #L1145 - L1147 were not covered by tests
try:
engine = self._manager.engines.get(uid)
if engine:
Comment on lines +1149 to +1150
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code-quality): Use named expression to simplify assignment and conditional (use-named-expression)

Suggested change
engine = self._manager.engines.get(uid)
if engine:
if engine := self._manager.engines.get(uid):

url = engine.get_task_url(remote_ref)
log.info(f">>>> doc url: {url}")
engine.open_remote(url=url)
except OSError:
log.exception("Remote document cannot be opened")

Check warning on line 1156 in nxdrive/gui/api.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/api.py#L1151-L1156

Added lines #L1151 - L1156 were not covered by tests
@pyqtSlot(str, str, result=str)
def get_remote_document_url(self, uid: str, remote_ref: str, /) -> str:
"""Return the URL to a remote document based on its reference."""
engine = self._manager.engines.get(uid)
return engine.get_metadata_url(remote_ref) if engine else ""

@pyqtSlot(str, result=str)
def get_title(self, uid: str, /) -> str:
endpoint = "/api/v1/task/"

Check warning on line 1165 in nxdrive/gui/api.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/api.py#L1164-L1165

Added lines #L1164 - L1165 were not covered by tests
url = "http://localhost:8080/nuxeo" + endpoint
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code-quality): Use f-string instead of string concatenation (use-fstring-for-concatenation)

Suggested change
url = "http://localhost:8080/nuxeo" + endpoint
url = f"http://localhost:8080/nuxeo{endpoint}"

headers = {
"Accept": "application/json",
"Content-Type": "application/json",
}
try:

Check warning on line 1171 in nxdrive/gui/api.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/api.py#L1169-L1171

Added lines #L1169 - L1171 were not covered by tests
response = requests.get(
url=url,
verify=True,
timeout=3600,
headers=headers,

Check warning on line 1176 in nxdrive/gui/api.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/api.py#L1175-L1176

Added lines #L1175 - L1176 were not covered by tests
auth=("Administrator", "Administrator"),
)
data = response.json()
html = data["entries"][0]
html = html["variables"]
html = html["review_result"]
return html if html else "No Results To Show"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code-quality): Replace if-expression with or (or-if-exp-identity)

Suggested change
return html if html else "No Results To Show"
return html or "No Results To Show"


ExplanationHere we find ourselves setting a value if it evaluates to True, and otherwise
using a default.

The 'After' case is a bit easier to read and avoids the duplication of
input_currency.

It works because the left-hand side is evaluated first. If it evaluates to
true then currency will be set to this and the right-hand side will not be
evaluated. If it evaluates to false the right-hand side will be evaluated and
currency will be set to DEFAULT_CURRENCY.


except Exception:
log.exception("Unable to fetch tasks")
return "No Results Found"

Check warning on line 1187 in nxdrive/gui/api.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/api.py#L1183-L1187

Added lines #L1183 - L1187 were not covered by tests
Comment on lines +1164 to +1187
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code_refinement): The get_title method duplicates the logic for making a GET request to the Nuxeo server, which is already present in the fetch_pending_tasks method. Consider refactoring this into a separate utility function or service to avoid code duplication and simplify maintenance.


23 changes: 23 additions & 0 deletions nxdrive/gui/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@
# Setup notification center for macOS
if MAC:
self._setup_notification_center()
current_uid = self.engine_model.engines_uid[0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): The addition of the task manager window and the direct fetching of pending tasks in the initialization and GUI setup methods introduces additional complexity to the codebase. This approach mixes UI management with the application's core logic and lacks abstraction for these new functionalities. To maintain code readability and ease future maintenance, consider encapsulating the task manager setup and task fetching logic into separate methods or classes. For instance, creating a setup_task_manager method for the task manager window setup and a fetch_pending_tasks method for fetching tasks can help isolate these functionalities, making the code more modular and easier to manage. This separation of concerns not only simplifies the current implementation but also enhances the flexibility and maintainability of the code for future changes.

engine = self.manager.engines[current_uid]
self.api.fetch_pending_tasks(engine)

Check warning on line 220 in nxdrive/gui/application.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/application.py#L218-L220

Added lines #L218 - L220 were not covered by tests

# Application update
self.manager.updater.appUpdated.connect(self.quit)
Expand Down Expand Up @@ -259,6 +262,7 @@
del self.settings_window
del self.systray_window
del self.direct_transfer_window
del self.task_manager_window

Check warning on line 265 in nxdrive/gui/application.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/application.py#L265

Added line #L265 was not covered by tests
else:
del self.app_engine

Expand Down Expand Up @@ -327,6 +331,15 @@
self.direct_transfer_window.setSource(
QUrl.fromLocalFile(str(find_resource("qml", file="DirectTransfer.qml")))
)

# Task Manager
self.task_manager_window = CustomWindow()
self.task_manager_window.setMinimumWidth(300)
self.task_manager_window.setMinimumHeight(240)
self._fill_qml_context(self.task_manager_window.rootContext())
self.task_manager_window.setSource(

Check warning on line 340 in nxdrive/gui/application.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/application.py#L336-L340

Added lines #L336 - L340 were not covered by tests
QUrl.fromLocalFile(str(find_resource("qml", file="TaskManager.qml")))
)

flags |= qt.Popup
else:
Expand All @@ -342,6 +355,7 @@
self.direct_transfer_window = root.findChild(
CustomWindow, "directTransferWindow"
)
self.task_manager_window = root.findChild(CustomWindow, "taskManagerWindow")

Check warning on line 358 in nxdrive/gui/application.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/application.py#L358

Added line #L358 was not covered by tests

if LINUX:
flags |= qt.Drawer
Expand All @@ -360,6 +374,7 @@
if self.manager.engines:
current_uid = self.engine_model.engines_uid[0]
engine = self.manager.engines[current_uid]
# self.api.fetch_pending_tasks(engine)
self.get_last_files(current_uid)
self.refresh_transfers(engine.dao)
self.update_status(engine)
Expand Down Expand Up @@ -886,6 +901,14 @@
}
self._window_root(self.settings_window).setSection.emit(sections[section])
self._center_on_screen(self.settings_window)

@pyqtSlot(str)
def show_tasks(self, section: str, /) -> None:

Check warning on line 906 in nxdrive/gui/application.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/application.py#L905-L906

Added lines #L905 - L906 were not covered by tests
# Note: Keep synced with the TaskManager.qml file
sections = {

Check warning on line 908 in nxdrive/gui/application.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/application.py#L908

Added line #L908 was not covered by tests
}
self._window_root(self.task_manager_window) # .setSection.emit(sections[section])
self._center_on_screen(self.task_manager_window)

Check warning on line 911 in nxdrive/gui/application.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/application.py#L910-L911

Added lines #L910 - L911 were not covered by tests

@pyqtSlot()
def show_systray(self) -> None:
Expand Down
30 changes: 30 additions & 0 deletions nxdrive/notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@
return
notification = self._notifications[uid]
if notification.is_actionable():
log.info(">>>>> sending actionable notification")

Check warning on line 192 in nxdrive/notification.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/notification.py#L192

Added line #L192 was not covered by tests
self.triggerNotification.emit(notification.action, notification.action_args)
if notification.is_discard_on_trigger():
self.discard_notification(uid)
Expand Down Expand Up @@ -520,6 +521,31 @@
)


class DisplayPendingTask(Notification):
"""Display a notification for pending tasks"""

def __init__(self, engine_uid: str, remote_ref: str, /) -> None:
values = [remote_ref]
super().__init__(

Check warning on line 529 in nxdrive/notification.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/notification.py#L528-L529

Added lines #L528 - L529 were not covered by tests
uid="PENDING_DOCUMENT_REVIEWS",
title="Display Pending Task",
description=Translator.get("PENDING_DOCUMENT_REVIEWS", values=values),
level=Notification.LEVEL_INFO,
flags=(
Notification.FLAG_PERSISTENT
| Notification.FLAG_BUBBLE
| Notification.FLAG_ACTIONABLE
| Notification.FLAG_DISCARD_ON_TRIGGER
| Notification.FLAG_REMOVE_ON_DISCARD
),
action="display_pending_task",
action_args=(
engine_uid,
remote_ref,
),
)


class DefaultNotificationService(NotificationService):
def init_signals(self) -> None:
self._manager.initEngine.connect(self._connect_engine)
Expand All @@ -539,6 +565,10 @@
engine.directTransferSessionFinished.connect(
self._direct_transfer_session_finshed
)
engine.displayPendingTask.connect(self._display_pending_task)

def _display_pending_task(self, engine_uid: str, remote_ref: str, /) -> None:
self.send_notification(DisplayPendingTask(engine_uid, remote_ref))

Check warning on line 571 in nxdrive/notification.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/notification.py#L571

Added line #L571 was not covered by tests

def _direct_transfer_error(self, file: Path, /) -> None:
"""Display a notification when a Direct Transfer is in error."""
Expand Down
Loading