-
Notifications
You must be signed in to change notification settings - Fork 10
Add logic to allow napari to know that plugin actions are being done #174
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
base: main
Are you sure you want to change the base?
Changes from 17 commits
ff6598b
2bc5f7a
6bf33ae
b1c3297
6f30a71
7af047b
3edb8fa
7515662
de0e9f5
eb4e191
2f1a8e7
03cbcbe
80e7932
ee41c9d
9542081
cd66266
0030bc3
26506fe
aefa67e
7d71e3a
45e3674
1286c0c
e16ae29
db7e503
927299e
0dae292
1454f1c
d2eee7f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,10 @@ | ||
| import contextlib | ||
| import importlib.metadata | ||
| import os | ||
| import uuid | ||
| import webbrowser | ||
| from collections.abc import Sequence | ||
| from collections.abc import Callable, Sequence | ||
| from enum import Enum, auto | ||
| from functools import partial | ||
| from logging import getLogger | ||
| from typing import ( | ||
|
|
@@ -61,6 +63,14 @@ | |
| log = getLogger(__name__) | ||
|
|
||
|
|
||
| class Status(Enum): | ||
| PENDING = auto() | ||
| BUSY = auto() | ||
| DONE = auto() | ||
| CANCELLED = auto() | ||
| FAILED = auto() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this "Done" but In other words, how can we identify:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would say that a status
That corresponds to a
Those cases correspond to a
? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like having these be more explicit variable names would be great. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So It would be better to have something like:
? Are there are any other statuses/names that could be preferred? Or maybe removed/added? Let me know! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was checking how Qt handles this and they have several enums:
I think our enum is merging several of these, perhaps orthogonal, states.
Are we ok with |
||
|
|
||
|
|
||
| class PackageMetadataProtocol(Protocol): | ||
| """ | ||
| Protocol class defining the minimum atributtes/properties needed for package metadata. | ||
|
|
@@ -1048,6 +1058,7 @@ def __init__(self, parent=None, prefix=None) -> None: | |
| self._plugin_data = [] # Store all plugin data | ||
| self._filter_texts = [] | ||
| self._filter_idxs_cache = set() | ||
| self._task_status_id = None | ||
| self.worker = None | ||
| self._plugin_data_map = {} | ||
| self._add_items_timer = QTimer(self) | ||
|
|
@@ -1130,13 +1141,33 @@ def _update_theme(self, event: Any) -> None: | |
| """ | ||
| raise NotImplementedError | ||
|
|
||
| def _register_task_status(self): | ||
| status, description = self.query_status() | ||
|
|
||
| if self._task_status_id is not None: | ||
| self._update_task_status(status, description=description) | ||
| return | ||
|
|
||
| self._task_status_id = self.register_task_status( | ||
| status, description, cancel_callback=self.installer.cancel_all | ||
| ) | ||
|
|
||
| def _update_task_status( | ||
| self, status: Status = Status.DONE, description: str = '' | ||
| ): | ||
| if self._task_status_id is not None: | ||
| self.update_task_status( | ||
| self._task_status_id, status, description=description | ||
| ) | ||
|
|
||
| def _on_installer_start(self): | ||
| """Updates dialog buttons and status when installing a plugin.""" | ||
| self.cancel_all_btn.setVisible(True) | ||
| self.working_indicator.show() | ||
| self.process_success_indicator.hide() | ||
| self.process_error_indicator.hide() | ||
| self.refresh_button.setDisabled(True) | ||
| self._register_task_status() | ||
|
|
||
| def _on_process_finished(self, process_finished_data: ProcessFinishedData): | ||
| action = process_finished_data['action'] | ||
|
|
@@ -1210,6 +1241,7 @@ def _on_installer_all_finished(self, exit_codes): | |
| self._trans('Plugin Manager: process completed\n') | ||
| ) | ||
|
|
||
| self._update_task_status() | ||
| self.search() | ||
|
|
||
| def _add_to_installed( | ||
|
|
@@ -1774,7 +1806,7 @@ def search(self, text: str | None = None, skip=False) -> None: | |
| if len(text.strip()) == 0: | ||
| self.installed_list.filter('') | ||
| self.available_list.hideAll() | ||
| self._plugin_queue = None | ||
| self._plugin_queue = [] | ||
| self._add_items_timer.stop() | ||
| self._plugins_found = 0 | ||
| else: | ||
|
|
@@ -1792,7 +1824,7 @@ def search(self, text: str | None = None, skip=False) -> None: | |
| self._plugins_found = len(items) | ||
| self._add_items_timer.start() | ||
| else: | ||
| self._plugin_queue = None | ||
| self._plugin_queue = [] | ||
| self._add_items_timer.stop() | ||
| self._plugins_found = 0 | ||
|
|
||
|
|
@@ -1811,6 +1843,7 @@ def refresh(self, clear_cache: bool = False): | |
| self._plugin_queue = [] | ||
| self._plugin_data = [] | ||
| self._plugin_data_map = {} | ||
| self._latest_status = None | ||
|
|
||
| self.installed_list.clear() | ||
| self.available_list.clear() | ||
|
|
@@ -1868,4 +1901,30 @@ def import_plugins(self, fpath: str) -> None: | |
| plugins = [p for p in plugins if p] | ||
| self._install_packages(plugins) | ||
|
|
||
| def register_task_status( | ||
| self, | ||
| status: Status, | ||
| description: str, | ||
| cancel_callback: Callable | None = None, | ||
| ) -> uuid.UUID: | ||
| """Register a task status for the plugin manager.""" | ||
| raise NotImplementedError | ||
|
|
||
| def update_task_status( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm this method name and There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rechecking the code I think it should be possible to only have the Edit: Or let me know if there is a naming that could be less confusing! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you have any suggestion for the naming here @TimMonko ? Or do you think that leaving only the public method could help make the logic easier to follow? Let me know! |
||
| self, task_status_id: uuid.UUID, status: Status, description: str = '' | ||
| ) -> bool: | ||
| """Update task status for the plugin manager.""" | ||
| raise NotImplementedError | ||
|
|
||
| def query_status(self) -> tuple[Status, str]: | ||
| """ | ||
| Return the current status of plugins installations. | ||
|
|
||
| Returns | ||
| ------- | ||
| A tuple containing the current status (`Status`) and a description. | ||
|
|
||
| """ | ||
| raise NotImplementedError | ||
|
|
||
| # endregion - Public methods | ||
Uh oh!
There was an error while loading. Please reload this page.