From dcfc6c44524833a48ea8994055d85ea72b5ab51b Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 3 Nov 2021 11:15:09 +0100 Subject: [PATCH 1/8] OP-1906 - fix potential issue when no Site Sync --- openpype/tools/libraryloader/app.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/tools/libraryloader/app.py b/openpype/tools/libraryloader/app.py index d7c6c162e64..d9fdf338f03 100644 --- a/openpype/tools/libraryloader/app.py +++ b/openpype/tools/libraryloader/app.py @@ -405,7 +405,8 @@ def _assetschanged(self): self.data["state"]["assetIds"] = asset_ids # reset repre list - self._repres_widget.set_version_ids([]) + if self._repres_widget: + self._repres_widget.set_version_ids([]) def _subsetschanged(self): asset_ids = self.data["state"]["assetIds"] @@ -495,7 +496,8 @@ def _versionschanged(self): self._thumbnail_widget.set_thumbnail(thumbnail_docs) version_ids = [doc["_id"] for doc in version_docs or []] - self._repres_widget.set_version_ids(version_ids) + if self._repres_widget: + self._repres_widget.set_version_ids(version_ids) def _set_context(self, context, refresh=True): """Set the selection in the interface using a context. From 08393cc0963f6e6d36d3d25250efc549e7d28907 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 3 Nov 2021 11:15:49 +0100 Subject: [PATCH 2/8] OP-1906 - wip of AvailabilityDelegate --- openpype/tools/loader/widgets.py | 55 ++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 4c075382aca..4bab37449b9 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -197,6 +197,10 @@ def __init__( column = model.Columns.index("time") view.setItemDelegateForColumn(column, time_delegate) + avail_delegate = AvailabilityDelegate(self.dbcon, view) + column = model.Columns.index("repre_info") + view.setItemDelegateForColumn(column, avail_delegate) + layout = QtWidgets.QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addLayout(top_bar_layout) @@ -1578,3 +1582,54 @@ def _load_subsets_by_loader(loader, subset_contexts, options, )) return error_info + + +class AvailabilityDelegate(QtWidgets.QStyledItemDelegate): + """ + Prints icons and downloaded representation ration for both sides. + """ + + def __init__(self, dbcon, parent=None): + super(AvailabilityDelegate, self).__init__(parent) + self.icons = {} + + def paint(self, painter, option, index): + super(AvailabilityDelegate, self).paint(painter, option, index) + option = QtWidgets.QStyleOptionViewItem(option) + option.showDecorationSelected = True + + # provider = index.data(lib.ProviderRole) + # value = index.data(lib.ProgressRole) + # date_value = index.data(lib.DateRole) + # is_failed = index.data(lib.FailedRole) + + provider_local = "local" + provider_remote = "gdrive" + + # idx = 0 + # for provider in [provider_local, provider_remote]: + # idx += 1 + # if not self.icons.get(provider): + # resource_path = os.path.dirname(__file__) + # resource_path = os.path.join(resource_path, "..", + # "providers", "resources") + # pix_url = "{}/{}.png".format(resource_path, provider) + # pixmap = QtGui.QPixmap(pix_url) + # self.icons[provider] = pixmap + # else: + # pixmap = self.icons[provider] + # + # padding = 10 * idx + # point = QtCore.QPoint(option.rect.x() + padding, + # option.rect.y() + + # (option.rect.height() - pixmap.height()) / 2) + # painter.drawPixmap(point, pixmap) + + painter.drawText( + option.rect, + option.displayAlignment, + "fook" + ) + + def displayText(self, value, locale): + pass From 565eb440f5636744a39f4717d31c17318cd35994 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 8 Nov 2021 17:47:37 +0100 Subject: [PATCH 3/8] OP-1906 - added files for Python2 hosts --- .../default_modules/sync_server/tray/__init__.py | 0 .../modules/default_modules/sync_server/tray/roles.py | 11 +++++++++++ 2 files changed, 11 insertions(+) create mode 100644 openpype/modules/default_modules/sync_server/tray/__init__.py create mode 100644 openpype/modules/default_modules/sync_server/tray/roles.py diff --git a/openpype/modules/default_modules/sync_server/tray/__init__.py b/openpype/modules/default_modules/sync_server/tray/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/openpype/modules/default_modules/sync_server/tray/roles.py b/openpype/modules/default_modules/sync_server/tray/roles.py new file mode 100644 index 00000000000..325e93c5f2c --- /dev/null +++ b/openpype/modules/default_modules/sync_server/tray/roles.py @@ -0,0 +1,11 @@ +from Qt import QtCore + +# roles for use in model's data function +# separated into its own file because Python 2 hosts (lib contains attrs) +ProviderRole = QtCore.Qt.UserRole + 12 +ProgressRole = QtCore.Qt.UserRole + 14 +DateRole = QtCore.Qt.UserRole + 16 +FailedRole = QtCore.Qt.UserRole + 18 +HeaderNameRole = QtCore.Qt.UserRole + 20 +FullItemRole = QtCore.Qt.UserRole + 22 +EditIconRole = QtCore.Qt.UserRole + 24 From a7d78bf5d4b989534d545dac8e9b66bbfa55843a Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 8 Nov 2021 17:50:07 +0100 Subject: [PATCH 4/8] OP-1906 - added availability for Site Sync for both sides to the Loader --- .../default_modules/sync_server/tray/lib.py | 9 --- openpype/tools/loader/model.py | 71 ++++++++++++----- openpype/tools/loader/widgets.py | 77 ++++++++++--------- 3 files changed, 94 insertions(+), 63 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/tray/lib.py b/openpype/modules/default_modules/sync_server/tray/lib.py index 25c600abd23..dda3598e648 100644 --- a/openpype/modules/default_modules/sync_server/tray/lib.py +++ b/openpype/modules/default_modules/sync_server/tray/lib.py @@ -1,4 +1,3 @@ -from Qt import QtCore import attr import abc import six @@ -19,14 +18,6 @@ DUMMY_PROJECT = "No project configured" -ProviderRole = QtCore.Qt.UserRole + 2 -ProgressRole = QtCore.Qt.UserRole + 4 -DateRole = QtCore.Qt.UserRole + 6 -FailedRole = QtCore.Qt.UserRole + 8 -HeaderNameRole = QtCore.Qt.UserRole + 10 -FullItemRole = QtCore.Qt.UserRole + 12 -EditIconRole = QtCore.Qt.UserRole + 14 - @six.add_metaclass(abc.ABCMeta) class AbstractColumnFilter: diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 6e9c7bf2207..75953d6f235 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -15,6 +15,7 @@ from openpype.tools.utils import lib from openpype.modules import ModulesManager +from openpype_modules.sync_server.tray import roles def is_filtering_recursible(): @@ -333,7 +334,6 @@ def set_version(self, index, version): repre_info = version_data.get("repre_info") if repre_info: item["repre_info"] = repre_info - item["repre_icon"] = version_data.get("repre_icon") def _fetch(self): asset_docs = self.dbcon.find( @@ -445,14 +445,16 @@ def _fetch(self): for _subset_id, doc in last_versions_by_subset_id.items(): version_ids.add(doc["_id"]) - site = self.active_site - query = self._repre_per_version_pipeline(list(version_ids), site) + query = self._repre_per_version_pipeline(list(version_ids), + self.active_site, + self.remote_site) repre_info = {} for doc in self.dbcon.aggregate(query): if self._doc_fetching_stop: return - doc["provider"] = self.active_provider + doc["active_provider"] = self.active_provider + doc["remote_provider"] = self.remote_provider repre_info[doc["_id"]] = doc self._doc_payload["repre_info_by_version_id"] = repre_info @@ -719,10 +721,6 @@ def data(self, index, role): item = index.internalPointer() return item.get("familyIcon", None) - if index.column() == self.columns_index.get("repre_info"): - item = index.internalPointer() - return item.get("repre_icon", None) - elif role == QtCore.Qt.ForegroundRole: item = index.internalPointer() version_doc = item.get("version_document") @@ -730,6 +728,16 @@ def data(self, index, role): if not version_doc["is_from_latest"]: return self.not_last_hero_brush + elif role == roles.ProgressRole: + item = index.internalPointer() + if not item.get("isGroup"): + return {"active": item.get("repre_info_local"), + "remote": item.get("repre_info_remote")} + + elif role == roles.ProviderRole: + return {"active": self.active_provider, + "remote": self.remote_provider} + return super(SubsetsModel, self).data(index, role) def flags(self, index): @@ -759,19 +767,25 @@ def _get_last_repre_info(self, repre_info_by_version_id, last_version_id): return data def _get_repre_dict(self, repre_info): - """Returns icon and str representation of availability""" + """Returns str representation of availability""" data = {} if repre_info: repres_str = "{}/{}".format( - int(math.floor(float(repre_info['avail_repre']))), + int(math.floor(float(repre_info['avail_repre_local']))), int(math.floor(float(repre_info['repre_count'])))) - data["repre_info"] = repres_str - data["repre_icon"] = self.repre_icons.get(self.active_provider) + data["repre_info_local"] = repres_str + + repres_str = "{}/{}".format( + int(math.floor(float(repre_info['avail_repre_remote']))), + int(math.floor(float(repre_info['repre_count'])))) + + data["repre_info_remote"] = repres_str return data - def _repre_per_version_pipeline(self, version_ids, site): + def _repre_per_version_pipeline(self, version_ids, + active_site, remote_site): query = [ {"$match": {"parent": {"$in": version_ids}, "type": "representation", @@ -780,7 +794,13 @@ def _repre_per_version_pipeline(self, version_ids, site): {'$addFields': { 'order_local': { '$filter': {'input': '$files.sites', 'as': 'p', - 'cond': {'$eq': ['$$p.name', site]} + 'cond': {'$eq': ['$$p.name', active_site]} + }} + }}, + {'$addFields': { + 'order_remote': { + '$filter': {'input': '$files.sites', 'as': 'p', + 'cond': {'$eq': ['$$p.name', remote_site]} }} }}, {'$addFields': { @@ -795,19 +815,32 @@ def _repre_per_version_pipeline(self, version_ids, site): ]} ]}, 0]} }}, + {'$addFields': { + 'progress_remote': {"$arrayElemAt": [{ + '$cond': [{'$size': "$order_remote.progress"}, + "$order_remote.progress", + # if exists created_dt count is as available + {'$cond': [ + {'$size': "$order_remote.created_dt"}, + [1], + [0] + ]} + ]}, 0]} + }}, {'$group': { # first group by repre '_id': '$_id', 'parent': {'$first': '$parent'}, - 'files_count': {'$sum': 1}, - 'files_avail': {'$sum': "$progress_local"}, - 'avail_ratio': {'$first': { - '$divide': [{'$sum': "$progress_local"}, {'$sum': 1}]}} + 'avail_ratio_local': {'$first': { + '$divide': [{'$sum': "$progress_local"}, {'$sum': 1}]}}, + 'avail_ratio_remote': {'$first': { + '$divide': [{'$sum': "$progress_remote"}, {'$sum': 1}]}} }}, {'$group': { # second group by parent, eg version_id '_id': '$parent', 'repre_count': {'$sum': 1}, # total representations # fully available representation for site - 'avail_repre': {'$sum': "$avail_ratio"} + 'avail_repre_local': {'$sum': "$avail_ratio_local"}, + 'avail_repre_remote': {'$sum': "$avail_ratio_remote"}, }}, ] return query diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 4bab37449b9..2160b27dd58 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -31,6 +31,8 @@ ) from . import lib +from openpype_modules.sync_server.tray import roles + class OverlayFrame(QtWidgets.QFrame): def __init__(self, label, parent): @@ -1591,45 +1593,50 @@ class AvailabilityDelegate(QtWidgets.QStyledItemDelegate): def __init__(self, dbcon, parent=None): super(AvailabilityDelegate, self).__init__(parent) - self.icons = {} + self.icons = tools_lib.get_repre_icons() def paint(self, painter, option, index): super(AvailabilityDelegate, self).paint(painter, option, index) option = QtWidgets.QStyleOptionViewItem(option) option.showDecorationSelected = True - # provider = index.data(lib.ProviderRole) - # value = index.data(lib.ProgressRole) - # date_value = index.data(lib.DateRole) - # is_failed = index.data(lib.FailedRole) - - provider_local = "local" - provider_remote = "gdrive" - - # idx = 0 - # for provider in [provider_local, provider_remote]: - # idx += 1 - # if not self.icons.get(provider): - # resource_path = os.path.dirname(__file__) - # resource_path = os.path.join(resource_path, "..", - # "providers", "resources") - # pix_url = "{}/{}.png".format(resource_path, provider) - # pixmap = QtGui.QPixmap(pix_url) - # self.icons[provider] = pixmap - # else: - # pixmap = self.icons[provider] - # - # padding = 10 * idx - # point = QtCore.QPoint(option.rect.x() + padding, - # option.rect.y() + - # (option.rect.height() - pixmap.height()) / 2) - # painter.drawPixmap(point, pixmap) - - painter.drawText( - option.rect, - option.displayAlignment, - "fook" - ) - def displayText(self, value, locale): - pass + print("roles.ProviderRole:: {}".format(roles.ProviderRole)) + providers = index.data(roles.ProviderRole) + values = index.data(roles.ProgressRole) + print("providers:: {}".format(providers)) + if not values: # group lines + return + + provider_active = providers["active"] + provider_remote = providers["remote"] + + availability_active = values["active"] + availability_remote = values["remote"] + + idx = 0 + height = width = 24 + for value, provider in [(availability_active, provider_active), + (availability_remote, provider_remote)]: + icon = self.icons.get(provider) + if not icon: + continue + + pixmap = icon.pixmap(icon.actualSize(QtCore.QSize(height, width))) + padding = 10 + (70 * idx) + point = QtCore.QPoint(option.rect.x() + padding, + option.rect.y() + + (option.rect.height() - pixmap.height()) / 2) + painter.drawPixmap(point, pixmap) + + text_rect = option.rect.translated(padding + width + 10, 0) + painter.drawText( + text_rect, + option.displayAlignment, + value + ) + + idx += 1 + + def displayText(self, value, locale): + pass From a3a6fbe8acb56566adf9ffc3f427e9addd538b9b Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 8 Nov 2021 18:27:47 +0100 Subject: [PATCH 5/8] OP-1906 - refactor - returned data structure simplified Data returned should be simple values, not arrays/dictionaries etc. Do not import from sync_server if not necessary (because of Python2) --- .../sync_server/tray/__init__.py | 0 .../default_modules/sync_server/tray/roles.py | 11 ------ openpype/tools/loader/model.py | 36 +++++++++++-------- openpype/tools/loader/widgets.py | 26 +++++++------- openpype/tools/utils/constants.py | 9 +++++ 5 files changed, 44 insertions(+), 38 deletions(-) delete mode 100644 openpype/modules/default_modules/sync_server/tray/__init__.py delete mode 100644 openpype/modules/default_modules/sync_server/tray/roles.py diff --git a/openpype/modules/default_modules/sync_server/tray/__init__.py b/openpype/modules/default_modules/sync_server/tray/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/openpype/modules/default_modules/sync_server/tray/roles.py b/openpype/modules/default_modules/sync_server/tray/roles.py deleted file mode 100644 index 325e93c5f2c..00000000000 --- a/openpype/modules/default_modules/sync_server/tray/roles.py +++ /dev/null @@ -1,11 +0,0 @@ -from Qt import QtCore - -# roles for use in model's data function -# separated into its own file because Python 2 hosts (lib contains attrs) -ProviderRole = QtCore.Qt.UserRole + 12 -ProgressRole = QtCore.Qt.UserRole + 14 -DateRole = QtCore.Qt.UserRole + 16 -FailedRole = QtCore.Qt.UserRole + 18 -HeaderNameRole = QtCore.Qt.UserRole + 20 -FullItemRole = QtCore.Qt.UserRole + 22 -EditIconRole = QtCore.Qt.UserRole + 24 diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 75953d6f235..42cd80844da 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -15,7 +15,12 @@ from openpype.tools.utils import lib from openpype.modules import ModulesManager -from openpype_modules.sync_server.tray import roles +from openpype.tools.utils.constants import ( + LOCAL_PROVIDER_ROLE, + REMOTE_PROVIDER_ROLE, + LOCAL_PROGRESS_ROLE, + REMOTE_PROGRESS_ROLE +) def is_filtering_recursible(): @@ -668,8 +673,8 @@ def data(self, index, role): if not index.isValid(): return + item = index.internalPointer() if role == self.SortDescendingRole: - item = index.internalPointer() if item.get("isGroup"): # Ensure groups be on top when sorting by descending order prefix = "2" @@ -685,7 +690,6 @@ def data(self, index, role): return prefix + order if role == self.SortAscendingRole: - item = index.internalPointer() if item.get("isGroup"): # Ensure groups be on top when sorting by ascending order prefix = "0" @@ -703,14 +707,12 @@ def data(self, index, role): if role == QtCore.Qt.DisplayRole: if index.column() == self.columns_index["family"]: # Show familyLabel instead of family - item = index.internalPointer() return item.get("familyLabel", None) elif role == QtCore.Qt.DecorationRole: # Add icon to subset column if index.column() == self.columns_index["subset"]: - item = index.internalPointer() if item.get("isGroup") or item.get("isMerged"): return item["icon"] else: @@ -718,25 +720,31 @@ def data(self, index, role): # Add icon to family column if index.column() == self.columns_index["family"]: - item = index.internalPointer() return item.get("familyIcon", None) elif role == QtCore.Qt.ForegroundRole: - item = index.internalPointer() version_doc = item.get("version_document") if version_doc and version_doc.get("type") == "hero_version": if not version_doc["is_from_latest"]: return self.not_last_hero_brush - elif role == roles.ProgressRole: - item = index.internalPointer() + elif role == LOCAL_PROGRESS_ROLE: if not item.get("isGroup"): - return {"active": item.get("repre_info_local"), - "remote": item.get("repre_info_remote")} + return item.get("repre_info_local") + else: + return None + + elif role == REMOTE_PROGRESS_ROLE: + if not item.get("isGroup"): + return item.get("repre_info_remote") + else: + return None + + elif role == LOCAL_PROVIDER_ROLE: + return self.active_provider - elif role == roles.ProviderRole: - return {"active": self.active_provider, - "remote": self.remote_provider} + elif role == REMOTE_PROVIDER_ROLE: + return self.remote_provider return super(SubsetsModel, self).data(index, role) diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 2160b27dd58..9c4a221e430 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -31,7 +31,12 @@ ) from . import lib -from openpype_modules.sync_server.tray import roles +from openpype.tools.utils.constants import ( + LOCAL_PROVIDER_ROLE, + REMOTE_PROVIDER_ROLE, + LOCAL_PROGRESS_ROLE, + REMOTE_PROGRESS_ROLE +) class OverlayFrame(QtWidgets.QFrame): @@ -1600,24 +1605,19 @@ def paint(self, painter, option, index): option = QtWidgets.QStyleOptionViewItem(option) option.showDecorationSelected = True + provider_active = index.data(LOCAL_PROVIDER_ROLE) + provider_remote = index.data(REMOTE_PROVIDER_ROLE) - print("roles.ProviderRole:: {}".format(roles.ProviderRole)) - providers = index.data(roles.ProviderRole) - values = index.data(roles.ProgressRole) - print("providers:: {}".format(providers)) - if not values: # group lines - return - - provider_active = providers["active"] - provider_remote = providers["remote"] + availability_active = index.data(LOCAL_PROGRESS_ROLE) + availability_remote = index.data(REMOTE_PROGRESS_ROLE) - availability_active = values["active"] - availability_remote = values["remote"] + if not availability_active or not availability_remote: # group lines + return idx = 0 height = width = 24 for value, provider in [(availability_active, provider_active), - (availability_remote, provider_remote)]: + (availability_remote, provider_remote)]: icon = self.icons.get(provider) if not icon: continue diff --git a/openpype/tools/utils/constants.py b/openpype/tools/utils/constants.py index 0e940a55957..8dee8b80577 100644 --- a/openpype/tools/utils/constants.py +++ b/openpype/tools/utils/constants.py @@ -8,3 +8,12 @@ TASK_NAME_ROLE = QtCore.Qt.UserRole + 301 TASK_TYPE_ROLE = QtCore.Qt.UserRole + 302 TASK_ORDER_ROLE = QtCore.Qt.UserRole + 403 + +LOCAL_PROVIDER_ROLE = QtCore.Qt.UserRole + 500 +REMOTE_PROVIDER_ROLE = QtCore.Qt.UserRole + 501 +LOCAL_PROGRESS_ROLE = QtCore.Qt.UserRole + 502 +REMOTE_PROGRESS_ROLE = QtCore.Qt.UserRole + 503 +DATE_ROLE = QtCore.Qt.UserRole + 504 +FAILED_ROLE = QtCore.Qt.UserRole + 505 +HEADER_NAME_ROLE = QtCore.Qt.UserRole + 506 +EDIT_ICON_ROLE = QtCore.Qt.UserRole + 507 From 93514721da0f77f263fb62e0d6f0062839d45902 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 9 Nov 2021 11:40:19 +0100 Subject: [PATCH 6/8] OP-1906 - refactor - roles in Site Sync Queue Used new role wrere possible. RepresentationModel stuck with old roles, much more complicated refactor needed in the future. --- .../sync_server/tray/delegates.py | 28 +++- .../sync_server/tray/models.py | 133 +++++++++--------- .../sync_server/tray/widgets.py | 4 +- openpype/tools/utils/constants.py | 12 +- 4 files changed, 104 insertions(+), 73 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/tray/delegates.py b/openpype/modules/default_modules/sync_server/tray/delegates.py index 461b9fffb36..955f549bb55 100644 --- a/openpype/modules/default_modules/sync_server/tray/delegates.py +++ b/openpype/modules/default_modules/sync_server/tray/delegates.py @@ -4,6 +4,15 @@ from openpype.lib import PypeLogger from . import lib +from openpype.tools.utils.constants import ( + LOCAL_PROVIDER_ROLE, + REMOTE_PROVIDER_ROLE, + LOCAL_PROGRESS_ROLE, + REMOTE_PROGRESS_ROLE, + LOCAL_DATE_ROLE, + REMOTE_DATE_ROLE +) + log = PypeLogger().get_logger("SyncServer") @@ -71,18 +80,29 @@ class ImageDelegate(QtWidgets.QStyledItemDelegate): Prints icon of site and progress of synchronization """ - def __init__(self, parent=None): + def __init__(self, parent=None, side=None): super(ImageDelegate, self).__init__(parent) self.icons = {} + self.side = side def paint(self, painter, option, index): super(ImageDelegate, self).paint(painter, option, index) option = QtWidgets.QStyleOptionViewItem(option) option.showDecorationSelected = True - provider = index.data(lib.ProviderRole) - value = index.data(lib.ProgressRole) - date_value = index.data(lib.DateRole) + if not self.side: + log.warning("No side provided, delegate won't work") + return + + if self.side == 'local': + provider = index.data(LOCAL_PROVIDER_ROLE) + value = index.data(LOCAL_PROGRESS_ROLE) + date_value = index.data(LOCAL_DATE_ROLE) + else: + provider = index.data(REMOTE_PROVIDER_ROLE) + value = index.data(REMOTE_PROGRESS_ROLE) + date_value = index.data(REMOTE_DATE_ROLE) + is_failed = index.data(lib.FailedRole) if not self.icons.get(provider): diff --git a/openpype/modules/default_modules/sync_server/tray/models.py b/openpype/modules/default_modules/sync_server/tray/models.py index 713e167a6a2..1bfa4f2bfcc 100644 --- a/openpype/modules/default_modules/sync_server/tray/models.py +++ b/openpype/modules/default_modules/sync_server/tray/models.py @@ -13,6 +13,19 @@ from . import lib +from openpype.tools.utils.constants import ( + LOCAL_PROVIDER_ROLE, + REMOTE_PROVIDER_ROLE, + LOCAL_PROGRESS_ROLE, + REMOTE_PROGRESS_ROLE, + HEADER_NAME_ROLE, + EDIT_ICON_ROLE, + LOCAL_DATE_ROLE, + REMOTE_DATE_ROLE, + LOCAL_FAILED_ROLE, + REMOTE_FAILED_ROLE +) + log = PypeLogger().get_logger("SyncServer") @@ -68,7 +81,7 @@ def headerData(self, section, orientation, role=Qt.DisplayRole): if orientation == Qt.Horizontal: return self.COLUMN_LABELS[section][1] - if role == lib.HeaderNameRole: + if role == HEADER_NAME_ROLE: if orientation == Qt.Horizontal: return self.COLUMN_LABELS[section][0] # return name @@ -459,37 +472,34 @@ def __init__(self, sync_server, header, project=None, parent=None): def data(self, index, role): item = self._data[index.row()] - if role == lib.FullItemRole: - return item - header_value = self._header[index.column()] - if role == lib.ProviderRole: - if header_value == 'local_site': - return item.local_provider - if header_value == 'remote_site': - return item.remote_provider - - if role == lib.ProgressRole: - if header_value == 'local_site': - return item.local_progress - if header_value == 'remote_site': - return item.remote_progress - - if role == lib.DateRole: - if header_value == 'local_site': - if item.created_dt: - return pretty_timestamp(item.created_dt) - if header_value == 'remote_site': - if item.sync_dt: - return pretty_timestamp(item.sync_dt) - - if role == lib.FailedRole: - if header_value == 'local_site': - return item.status == lib.STATUS[2] and \ - item.local_progress < 1 - if header_value == 'remote_site': - return item.status == lib.STATUS[2] and \ - item.remote_progress < 1 + if role == LOCAL_PROVIDER_ROLE: + return item.local_provider + + if role == REMOTE_PROVIDER_ROLE: + return item.remote_provider + + if role == LOCAL_PROGRESS_ROLE: + return item.local_progress + + if role == REMOTE_PROGRESS_ROLE: + return item.remote_progress + + if role == LOCAL_DATE_ROLE: + if item.created_dt: + return pretty_timestamp(item.created_dt) + + if role == REMOTE_DATE_ROLE: + if item.sync_dt: + return pretty_timestamp(item.sync_dt) + + if role == LOCAL_FAILED_ROLE: + return item.status == lib.STATUS[2] and \ + item.local_progress < 1 + + if role == REMOTE_FAILED_ROLE: + return item.status == lib.STATUS[2] and \ + item.remote_progress < 1 if role in (Qt.DisplayRole, Qt.EditRole): # because of ImageDelegate @@ -498,7 +508,7 @@ def data(self, index, role): return attr.asdict(item)[self._header[index.column()]] - if role == lib.EditIconRole: + if role == EDIT_ICON_ROLE: if self.can_edit and header_value in self.EDITABLE_COLUMNS: return self.edit_icon @@ -988,37 +998,34 @@ def __init__(self, sync_server, header, _id, def data(self, index, role): item = self._data[index.row()] - if role == lib.FullItemRole: - return item - header_value = self._header[index.column()] - if role == lib.ProviderRole: - if header_value == 'local_site': - return item.local_provider - if header_value == 'remote_site': - return item.remote_provider - - if role == lib.ProgressRole: - if header_value == 'local_site': - return item.local_progress - if header_value == 'remote_site': - return item.remote_progress - - if role == lib.DateRole: - if header_value == 'local_site': - if item.created_dt: - return pretty_timestamp(item.created_dt) - if header_value == 'remote_site': - if item.sync_dt: - return pretty_timestamp(item.sync_dt) - - if role == lib.FailedRole: - if header_value == 'local_site': - return item.status == lib.STATUS[2] and \ - item.local_progress < 1 - if header_value == 'remote_site': - return item.status == lib.STATUS[2] and \ - item.remote_progress < 1 + if role == LOCAL_PROVIDER_ROLE: + return item.local_provider + + if role == REMOTE_PROVIDER_ROLE: + return item.remote_provider + + if role == LOCAL_PROGRESS_ROLE: + return item.local_progress + + if role == REMOTE_PROGRESS_ROLE: + return item.remote_progress + + if role == LOCAL_DATE_ROLE: + if item.created_dt: + return pretty_timestamp(item.created_dt) + + if role == REMOTE_DATE_ROLE: + if item.sync_dt: + return pretty_timestamp(item.sync_dt) + + if role == LOCAL_FAILED_ROLE: + return item.status == lib.STATUS[2] and \ + item.local_progress < 1 + + if role == REMOTE_FAILED_ROLE: + return item.status == lib.STATUS[2] and \ + item.remote_progress < 1 if role in (Qt.DisplayRole, Qt.EditRole): # because of ImageDelegate @@ -1027,7 +1034,7 @@ def data(self, index, role): return attr.asdict(item)[self._header[index.column()]] - if role == lib.EditIconRole: + if role == EDIT_ICON_ROLE: if self.can_edit and header_value in self.EDITABLE_COLUMNS: return self.edit_icon diff --git a/openpype/modules/default_modules/sync_server/tray/widgets.py b/openpype/modules/default_modules/sync_server/tray/widgets.py index 5e368f9e0b6..2747aaf760c 100644 --- a/openpype/modules/default_modules/sync_server/tray/widgets.py +++ b/openpype/modules/default_modules/sync_server/tray/widgets.py @@ -591,11 +591,11 @@ def __init__(self, sync_server, project=None, parent=None): table_view.viewport().setAttribute(QtCore.Qt.WA_Hover, True) column = table_view.model().get_header_index("local_site") - delegate = delegates.ImageDelegate(self) + delegate = delegates.ImageDelegate(self, side="local") table_view.setItemDelegateForColumn(column, delegate) column = table_view.model().get_header_index("remote_site") - delegate = delegates.ImageDelegate(self) + delegate = delegates.ImageDelegate(self, side="remote") table_view.setItemDelegateForColumn(column, delegate) column = table_view.model().get_header_index("priority") diff --git a/openpype/tools/utils/constants.py b/openpype/tools/utils/constants.py index 8dee8b80577..e0789972f9e 100644 --- a/openpype/tools/utils/constants.py +++ b/openpype/tools/utils/constants.py @@ -13,7 +13,11 @@ REMOTE_PROVIDER_ROLE = QtCore.Qt.UserRole + 501 LOCAL_PROGRESS_ROLE = QtCore.Qt.UserRole + 502 REMOTE_PROGRESS_ROLE = QtCore.Qt.UserRole + 503 -DATE_ROLE = QtCore.Qt.UserRole + 504 -FAILED_ROLE = QtCore.Qt.UserRole + 505 -HEADER_NAME_ROLE = QtCore.Qt.UserRole + 506 -EDIT_ICON_ROLE = QtCore.Qt.UserRole + 507 +LOCAL_AVAILABILITY_ROLE = QtCore.Qt.UserRole + 504 +REMOTE_AVAILABILITY_ROLE = QtCore.Qt.UserRole + 505 +LOCAL_DATE_ROLE = QtCore.Qt.UserRole + 506 +REMOTE_DATE_ROLE = QtCore.Qt.UserRole + 507 +LOCAL_FAILED_ROLE = QtCore.Qt.UserRole + 508 +REMOTE_FAILED_ROLE = QtCore.Qt.UserRole + 509 +HEADER_NAME_ROLE = QtCore.Qt.UserRole + 510 +EDIT_ICON_ROLE = QtCore.Qt.UserRole + 511 From 05983fc1ebe5cde07873bd16c91c819f23d9ddbe Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 9 Nov 2021 13:43:17 +0100 Subject: [PATCH 7/8] OP-1906 - refactor - simplified roles Removed FullItemRole, replaced with more primitive returning roles --- .../sync_server/tray/delegates.py | 13 +- .../default_modules/sync_server/tray/lib.py | 6 +- .../sync_server/tray/models.py | 156 +++++++----------- .../sync_server/tray/widgets.py | 140 ++++++++++------ openpype/tools/utils/constants.py | 18 +- 5 files changed, 174 insertions(+), 159 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/tray/delegates.py b/openpype/modules/default_modules/sync_server/tray/delegates.py index 955f549bb55..5ab809a8166 100644 --- a/openpype/modules/default_modules/sync_server/tray/delegates.py +++ b/openpype/modules/default_modules/sync_server/tray/delegates.py @@ -10,7 +10,10 @@ LOCAL_PROGRESS_ROLE, REMOTE_PROGRESS_ROLE, LOCAL_DATE_ROLE, - REMOTE_DATE_ROLE + REMOTE_DATE_ROLE, + LOCAL_FAILED_ROLE, + REMOTE_FAILED_ROLE, + EDIT_ICON_ROLE ) log = PypeLogger().get_logger("SyncServer") @@ -23,7 +26,7 @@ def paint(self, painter, option, index): if option.widget.selectionModel().isSelected(index) or \ option.state & QtWidgets.QStyle.State_MouseOver: - edit_icon = index.data(lib.EditIconRole) + edit_icon = index.data(EDIT_ICON_ROLE) if not edit_icon: return @@ -47,7 +50,7 @@ def createEditor(self, parent, option, index): editor = PriorityLineEdit( parent, option.widget.selectionModel().selectedRows()) - editor.setFocus(True) + editor.setFocus() return editor def setModelData(self, editor, model, index): @@ -98,12 +101,12 @@ def paint(self, painter, option, index): provider = index.data(LOCAL_PROVIDER_ROLE) value = index.data(LOCAL_PROGRESS_ROLE) date_value = index.data(LOCAL_DATE_ROLE) + is_failed = index.data(LOCAL_FAILED_ROLE) else: provider = index.data(REMOTE_PROVIDER_ROLE) value = index.data(REMOTE_PROGRESS_ROLE) date_value = index.data(REMOTE_DATE_ROLE) - - is_failed = index.data(lib.FailedRole) + is_failed = index.data(REMOTE_FAILED_ROLE) if not self.icons.get(provider): resource_path = os.path.dirname(__file__) diff --git a/openpype/modules/default_modules/sync_server/tray/lib.py b/openpype/modules/default_modules/sync_server/tray/lib.py index dda3598e648..87344be634d 100644 --- a/openpype/modules/default_modules/sync_server/tray/lib.py +++ b/openpype/modules/default_modules/sync_server/tray/lib.py @@ -152,7 +152,7 @@ def translate_provider_for_icon(sync_server, project, site): return sync_server.get_provider_for_site(site=site) -def get_item_by_id(model, object_id): +def get_value_from_id_by_role(model, object_id, role): + """Return value from item with 'object_id' with 'role'.""" index = model.get_index(object_id) - item = model.data(index, FullItemRole) - return item + return model.data(index, role) diff --git a/openpype/modules/default_modules/sync_server/tray/models.py b/openpype/modules/default_modules/sync_server/tray/models.py index 1bfa4f2bfcc..80f41992cb3 100644 --- a/openpype/modules/default_modules/sync_server/tray/models.py +++ b/openpype/modules/default_modules/sync_server/tray/models.py @@ -23,7 +23,11 @@ LOCAL_DATE_ROLE, REMOTE_DATE_ROLE, LOCAL_FAILED_ROLE, - REMOTE_FAILED_ROLE + REMOTE_FAILED_ROLE, + STATUS_ROLE, + PATH_ROLE, + ERROR_ROLE, + TRIES_ROLE ) @@ -85,6 +89,64 @@ def headerData(self, section, orientation, role=Qt.DisplayRole): if orientation == Qt.Horizontal: return self.COLUMN_LABELS[section][0] # return name + def data(self, index, role): + item = self._data[index.row()] + + header_value = self._header[index.column()] + if role == LOCAL_PROVIDER_ROLE: + return item.local_provider + + if role == REMOTE_PROVIDER_ROLE: + return item.remote_provider + + if role == LOCAL_PROGRESS_ROLE: + return item.local_progress + + if role == REMOTE_PROGRESS_ROLE: + return item.remote_progress + + if role == LOCAL_DATE_ROLE: + if item.created_dt: + return pretty_timestamp(item.created_dt) + + if role == REMOTE_DATE_ROLE: + if item.sync_dt: + return pretty_timestamp(item.sync_dt) + + if role == LOCAL_FAILED_ROLE: + return item.status == lib.STATUS[2] and \ + item.local_progress < 1 + + if role == REMOTE_FAILED_ROLE: + return item.status == lib.STATUS[2] and \ + item.remote_progress < 1 + + if role in (Qt.DisplayRole, Qt.EditRole): + # because of ImageDelegate + if header_value in ['remote_site', 'local_site']: + return "" + + return attr.asdict(item)[self._header[index.column()]] + + if role == EDIT_ICON_ROLE: + if self.can_edit and header_value in self.EDITABLE_COLUMNS: + return self.edit_icon + + if role == PATH_ROLE: + return item.path + + if role == ERROR_ROLE: + return item.error + + if role == TRIES_ROLE: + return item.tries + + if role == STATUS_ROLE: + return item.status + + if role == Qt.UserRole: + return item._id + @property def can_edit(self): """Returns true if some site is user local site, eg. could edit""" @@ -469,52 +531,6 @@ def __init__(self, sync_server, header, project=None, parent=None): self.timer.timeout.connect(self.tick) self.timer.start(self.REFRESH_SEC) - def data(self, index, role): - item = self._data[index.row()] - - header_value = self._header[index.column()] - if role == LOCAL_PROVIDER_ROLE: - return item.local_provider - - if role == REMOTE_PROVIDER_ROLE: - return item.remote_provider - - if role == LOCAL_PROGRESS_ROLE: - return item.local_progress - - if role == REMOTE_PROGRESS_ROLE: - return item.remote_progress - - if role == LOCAL_DATE_ROLE: - if item.created_dt: - return pretty_timestamp(item.created_dt) - - if role == REMOTE_DATE_ROLE: - if item.sync_dt: - return pretty_timestamp(item.sync_dt) - - if role == LOCAL_FAILED_ROLE: - return item.status == lib.STATUS[2] and \ - item.local_progress < 1 - - if role == REMOTE_FAILED_ROLE: - return item.status == lib.STATUS[2] and \ - item.remote_progress < 1 - - if role in (Qt.DisplayRole, Qt.EditRole): - # because of ImageDelegate - if header_value in ['remote_site', 'local_site']: - return "" - - return attr.asdict(item)[self._header[index.column()]] - - if role == EDIT_ICON_ROLE: - if self.can_edit and header_value in self.EDITABLE_COLUMNS: - return self.edit_icon - - if role == Qt.UserRole: - return item._id - def add_page_records(self, local_site, remote_site, representations): """ Process all records from 'representation' and add them to storage. @@ -995,52 +1011,6 @@ def __init__(self, sync_server, header, _id, self.timer.timeout.connect(self.tick) self.timer.start(SyncRepresentationSummaryModel.REFRESH_SEC) - def data(self, index, role): - item = self._data[index.row()] - - header_value = self._header[index.column()] - if role == LOCAL_PROVIDER_ROLE: - return item.local_provider - - if role == REMOTE_PROVIDER_ROLE: - return item.remote_provider - - if role == LOCAL_PROGRESS_ROLE: - return item.local_progress - - if role == REMOTE_PROGRESS_ROLE: - return item.remote_progress - - if role == LOCAL_DATE_ROLE: - if item.created_dt: - return pretty_timestamp(item.created_dt) - - if role == REMOTE_DATE_ROLE: - if item.sync_dt: - return pretty_timestamp(item.sync_dt) - - if role == LOCAL_FAILED_ROLE: - return item.status == lib.STATUS[2] and \ - item.local_progress < 1 - - if role == REMOTE_FAILED_ROLE: - return item.status == lib.STATUS[2] and \ - item.remote_progress < 1 - - if role in (Qt.DisplayRole, Qt.EditRole): - # because of ImageDelegate - if header_value in ['remote_site', 'local_site']: - return "" - - return attr.asdict(item)[self._header[index.column()]] - - if role == EDIT_ICON_ROLE: - if self.can_edit and header_value in self.EDITABLE_COLUMNS: - return self.edit_icon - - if role == Qt.UserRole: - return item._id - def add_page_records(self, local_site, remote_site, representations): """ Process all records from 'representation' and add them to storage. diff --git a/openpype/modules/default_modules/sync_server/tray/widgets.py b/openpype/modules/default_modules/sync_server/tray/widgets.py index 2747aaf760c..87044889b70 100644 --- a/openpype/modules/default_modules/sync_server/tray/widgets.py +++ b/openpype/modules/default_modules/sync_server/tray/widgets.py @@ -22,6 +22,20 @@ from . import lib from . import delegates +from openpype.tools.utils.constants import ( + LOCAL_PROGRESS_ROLE, + REMOTE_PROGRESS_ROLE, + HEADER_NAME_ROLE, + STATUS_ROLE, + PATH_ROLE, + LOCAL_SITE_NAME_ROLE, + REMOTE_SITE_NAME_ROLE, + LOCAL_DATE_ROLE, + REMOTE_DATE_ROLE, + ERROR_ROLE, + TRIES_ROLE +) + log = PypeLogger().get_logger("SyncServer") @@ -289,14 +303,19 @@ def _on_context_menu(self, point): if is_multi: index = self.model.get_index(list(self._selected_ids)[0]) - item = self.model.data(index, lib.FullItemRole) + local_progress = self.model.data(index, LOCAL_PROGRESS_ROLE) + remote_progress = self.model.data(index, REMOTE_PROGRESS_ROLE) + status = self.model.data(index, STATUS_ROLE) else: - item = self.model.data(point_index, lib.FullItemRole) + local_progress = self.model.data(point_index, LOCAL_PROGRESS_ROLE) + remote_progress = self.model.data(point_index, + REMOTE_PROGRESS_ROLE) + status = self.model.data(point_index, STATUS_ROLE) + can_edit = self.model.can_edit - action_kwarg_map, actions_mapping, menu = self._prepare_menu(item, - is_multi, - can_edit) + action_kwarg_map, actions_mapping, menu = self._prepare_menu( + local_progress, remote_progress, is_multi, can_edit, status) result = menu.exec_(QtGui.QCursor.pos()) if result: @@ -307,7 +326,8 @@ def _on_context_menu(self, point): self.model.refresh() - def _prepare_menu(self, item, is_multi, can_edit): + def _prepare_menu(self, local_progress, remote_progress, + is_multi, can_edit, status=None): menu = QtWidgets.QMenu(self) actions_mapping = {} @@ -316,11 +336,6 @@ def _prepare_menu(self, item, is_multi, can_edit): active_site = self.model.active_site remote_site = self.model.remote_site - local_progress = item.local_progress - remote_progress = item.remote_progress - - project = self.model.project - for site, progress in {active_site: local_progress, remote_site: remote_progress}.items(): provider = self.sync_server.get_provider_for_site(site=site) @@ -360,12 +375,6 @@ def _prepare_menu(self, item, is_multi, can_edit): actions_mapping[action] = self._change_priority menu.addAction(action) - # # temp for testing only !!! - # action = QtWidgets.QAction("Download") - # action_kwarg_map[action] = self._get_action_kwargs(active_site) - # actions_mapping[action] = self._add_site - # menu.addAction(action) - if not actions_mapping: action = QtWidgets.QAction("< No action >") actions_mapping[action] = None @@ -376,11 +385,15 @@ def _prepare_menu(self, item, is_multi, can_edit): def _pause(self, selected_ids=None): log.debug("Pause {}".format(selected_ids)) for representation_id in selected_ids: - item = lib.get_item_by_id(self.model, representation_id) - if item.status not in [lib.STATUS[0], lib.STATUS[1]]: + status = lib.get_value_from_id_by_role(self.model, + representation_id, + STATUS_ROLE) + if status not in [lib.STATUS[0], lib.STATUS[1]]: continue for site_name in [self.model.active_site, self.model.remote_site]: - check_progress = self._get_progress(item, site_name) + check_progress = self._get_progress(self.model, + representation_id, + site_name) if check_progress < 1: self.sync_server.pause_representation(self.model.project, representation_id, @@ -391,11 +404,15 @@ def _pause(self, selected_ids=None): def _unpause(self, selected_ids=None): log.debug("UnPause {}".format(selected_ids)) for representation_id in selected_ids: - item = lib.get_item_by_id(self.model, representation_id) - if item.status not in lib.STATUS[3]: + status = lib.get_value_from_id_by_role(self.model, + representation_id, + STATUS_ROLE) + if status not in lib.STATUS[3]: continue for site_name in [self.model.active_site, self.model.remote_site]: - check_progress = self._get_progress(item, site_name) + check_progress = self._get_progress(self.model, + representation_id, + site_name) if check_progress < 1: self.sync_server.unpause_representation( self.model.project, @@ -408,8 +425,11 @@ def _unpause(self, selected_ids=None): def _add_site(self, selected_ids=None, site_name=None): log.debug("Add site {}:{}".format(selected_ids, site_name)) for representation_id in selected_ids: - item = lib.get_item_by_id(self.model, representation_id) - if item.local_site == site_name or item.remote_site == site_name: + item_local_site = lib.get_value_from_id_by_role( + self.model, representation_id, LOCAL_SITE_NAME_ROLE) + item_remote_site = lib.get_value_from_id_by_role( + self.model, representation_id, REMOTE_SITE_NAME_ROLE) + if site_name in [item_local_site, item_remote_site]: # site already exists skip continue @@ -460,8 +480,8 @@ def _reset_site(self, selected_ids=None, site_name=None): """ log.debug("Reset site {}:{}".format(selected_ids, site_name)) for representation_id in selected_ids: - item = lib.get_item_by_id(self.model, representation_id) - check_progress = self._get_progress(item, site_name, True) + check_progress = self._get_progress(self.model, representation_id, + site_name, True) # do not reset if opposite side is not fully there if check_progress != 1: @@ -482,11 +502,8 @@ def _reset_site(self, selected_ids=None, site_name=None): def _open_in_explorer(self, selected_ids=None, site_name=None): log.debug("Open in Explorer {}:{}".format(selected_ids, site_name)) for selected_id in selected_ids: - item = lib.get_item_by_id(self.model, selected_id) - if not item: - return - - fpath = item.path + fpath = lib.get_value_from_id_by_role(self.model, selected_id, + PATH_ROLE) project = self.model.project fpath = self.sync_server.get_local_file_path(project, site_name, @@ -514,10 +531,17 @@ def _change_priority(self, **kwargs): self.model.is_editing = True self.table_view.openPersistentEditor(real_index) - def _get_progress(self, item, site_name, opposite=False): + def _get_progress(self, model, representation_id, + site_name, opposite=False): """Returns progress value according to site (side)""" - progress = {'local': item.local_progress, - 'remote': item.remote_progress} + local_progress = lib.get_value_from_id_by_role(model, + representation_id, + LOCAL_PROGRESS_ROLE) + remote_progress = lib.get_value_from_id_by_role(model, + representation_id, + REMOTE_PROGRESS_ROLE) + progress = {'local': local_progress, + 'remote': remote_progress} side = 'remote' if site_name == self.model.active_site: side = 'local' @@ -631,19 +655,21 @@ def __init__(self, sync_server, project=None, parent=None): self.selection_model = self.table_view.selectionModel() self.selection_model.selectionChanged.connect(self._selection_changed) - def _prepare_menu(self, item, is_multi, can_edit): + def _prepare_menu(self, local_progress, remote_progress, + is_multi, can_edit, status=None): action_kwarg_map, actions_mapping, menu = \ - super()._prepare_menu(item, is_multi, can_edit) + super()._prepare_menu(local_progress, remote_progress, + is_multi, can_edit) if can_edit and ( - item.status in [lib.STATUS[0], lib.STATUS[1]] or is_multi): + status in [lib.STATUS[0], lib.STATUS[1]] or is_multi): action = QtWidgets.QAction("Pause in queue") actions_mapping[action] = self._pause # pause handles which site_name it will pause itself action_kwarg_map[action] = {"selected_ids": self._selected_ids} menu.addAction(action) - if can_edit and (item.status == lib.STATUS[3] or is_multi): + if can_edit and (status == lib.STATUS[3] or is_multi): action = QtWidgets.QAction("Unpause in queue") actions_mapping[action] = self._unpause action_kwarg_map[action] = {"selected_ids": self._selected_ids} @@ -753,11 +779,11 @@ def __init__(self, sync_server, _id=None, project=None, parent=None): table_view.verticalHeader().hide() column = model.get_header_index("local_site") - delegate = delegates.ImageDelegate(self) + delegate = delegates.ImageDelegate(self, side="local") table_view.setItemDelegateForColumn(column, delegate) column = model.get_header_index("remote_site") - delegate = delegates.ImageDelegate(self) + delegate = delegates.ImageDelegate(self, side="remote") table_view.setItemDelegateForColumn(column, delegate) if model.can_edit: @@ -815,12 +841,14 @@ def _show_detail(self, selected_ids=None): detail_window.exec() - def _prepare_menu(self, item, is_multi, can_edit): + def _prepare_menu(self, local_progress, remote_progress, + is_multi, can_edit, status=None): """Adds view (and model) dependent actions to default ones""" action_kwarg_map, actions_mapping, menu = \ - super()._prepare_menu(item, is_multi, can_edit) + super()._prepare_menu(local_progress, remote_progress, + is_multi, can_edit, status) - if item.status == lib.STATUS[2] or is_multi: + if status == lib.STATUS[2] or is_multi: action = QtWidgets.QAction("Open error detail") actions_mapping[action] = self._show_detail action_kwarg_map[action] = {"selected_ids": self._selected_ids} @@ -835,8 +863,8 @@ def _reset_site(self, selected_ids=None, site_name=None): redo of upload/download """ for file_id in selected_ids: - item = lib.get_item_by_id(self.model, file_id) - check_progress = self._get_progress(item, site_name, True) + check_progress = self._get_progress(self.model, file_id, + site_name, True) # do not reset if opposite side is not fully there if check_progress != 1: @@ -895,20 +923,28 @@ def __init__(self, model, selected_ids, parent=None): no_errors = True for file_id in selected_ids: - item = lib.get_item_by_id(model, file_id) - if not item.created_dt or not item.sync_dt or not item.error: + created_dt = lib.get_value_from_id_by_role(model, file_id, + LOCAL_DATE_ROLE) + sync_dt = lib.get_value_from_id_by_role(model, file_id, + REMOTE_DATE_ROLE) + errors = lib.get_value_from_id_by_role(model, file_id, + ERROR_ROLE) + if not created_dt or not sync_dt or not errors: continue + tries = lib.get_value_from_id_by_role(model, file_id, + TRIES_ROLE) + no_errors = False - dt = max(item.created_dt, item.sync_dt) + dt = max(created_dt, sync_dt) txts = [] txts.append("{}: {}
".format("Last update date", pretty_timestamp(dt))) txts.append("{}: {}
".format("Retries", - str(item.tries))) + str(tries))) txts.append("{}: {}
".format("Error message", - item.error)) + errors)) text_area = QtWidgets.QTextEdit("\n\n".join(txts)) text_area.setReadOnly(True) @@ -1162,7 +1198,7 @@ def _fix_size(self): column_name = self.model.headerData(column_idx, QtCore.Qt.Horizontal, - lib.HeaderNameRole) + HEADER_NAME_ROLE) button = self.filter_buttons.get(column_name) if not button: continue diff --git a/openpype/tools/utils/constants.py b/openpype/tools/utils/constants.py index e0789972f9e..5b6f4126c99 100644 --- a/openpype/tools/utils/constants.py +++ b/openpype/tools/utils/constants.py @@ -9,15 +9,21 @@ TASK_TYPE_ROLE = QtCore.Qt.UserRole + 302 TASK_ORDER_ROLE = QtCore.Qt.UserRole + 403 -LOCAL_PROVIDER_ROLE = QtCore.Qt.UserRole + 500 -REMOTE_PROVIDER_ROLE = QtCore.Qt.UserRole + 501 -LOCAL_PROGRESS_ROLE = QtCore.Qt.UserRole + 502 -REMOTE_PROGRESS_ROLE = QtCore.Qt.UserRole + 503 -LOCAL_AVAILABILITY_ROLE = QtCore.Qt.UserRole + 504 +LOCAL_PROVIDER_ROLE = QtCore.Qt.UserRole + 500 # provider of active site +REMOTE_PROVIDER_ROLE = QtCore.Qt.UserRole + 501 # provider of remote site +LOCAL_PROGRESS_ROLE = QtCore.Qt.UserRole + 502 # percentage downld on active +REMOTE_PROGRESS_ROLE = QtCore.Qt.UserRole + 503 # percentage upload on remote +LOCAL_AVAILABILITY_ROLE = QtCore.Qt.UserRole + 504 # ratio of presence active REMOTE_AVAILABILITY_ROLE = QtCore.Qt.UserRole + 505 -LOCAL_DATE_ROLE = QtCore.Qt.UserRole + 506 +LOCAL_DATE_ROLE = QtCore.Qt.UserRole + 506 # created_dt on active site REMOTE_DATE_ROLE = QtCore.Qt.UserRole + 507 LOCAL_FAILED_ROLE = QtCore.Qt.UserRole + 508 REMOTE_FAILED_ROLE = QtCore.Qt.UserRole + 509 HEADER_NAME_ROLE = QtCore.Qt.UserRole + 510 EDIT_ICON_ROLE = QtCore.Qt.UserRole + 511 +STATUS_ROLE = QtCore.Qt.UserRole + 512 +PATH_ROLE = QtCore.Qt.UserRole + 513 +LOCAL_SITE_NAME_ROLE = QtCore.Qt.UserRole + 514 +REMOTE_SITE_NAME_ROLE = QtCore.Qt.UserRole + 515 +ERROR_ROLE = QtCore.Qt.UserRole + 516 +TRIES_ROLE = QtCore.Qt.UserRole + 517 From b4ff20c01cb0c57ed7527e3517ae620be268b348 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 9 Nov 2021 13:44:30 +0100 Subject: [PATCH 8/8] OP-1906 - refactor - renamed progress role to availability role Progress and Availability is different, one is in percentage, second one is for full presence --- openpype/tools/loader/model.py | 8 ++++---- openpype/tools/loader/widgets.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 42cd80844da..d81fc11cf2d 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -18,8 +18,8 @@ from openpype.tools.utils.constants import ( LOCAL_PROVIDER_ROLE, REMOTE_PROVIDER_ROLE, - LOCAL_PROGRESS_ROLE, - REMOTE_PROGRESS_ROLE + LOCAL_AVAILABILITY_ROLE, + REMOTE_AVAILABILITY_ROLE ) @@ -728,13 +728,13 @@ def data(self, index, role): if not version_doc["is_from_latest"]: return self.not_last_hero_brush - elif role == LOCAL_PROGRESS_ROLE: + elif role == LOCAL_AVAILABILITY_ROLE: if not item.get("isGroup"): return item.get("repre_info_local") else: return None - elif role == REMOTE_PROGRESS_ROLE: + elif role == REMOTE_AVAILABILITY_ROLE: if not item.get("isGroup"): return item.get("repre_info_remote") else: diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 9c4a221e430..08b58eebbe7 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -34,8 +34,8 @@ from openpype.tools.utils.constants import ( LOCAL_PROVIDER_ROLE, REMOTE_PROVIDER_ROLE, - LOCAL_PROGRESS_ROLE, - REMOTE_PROGRESS_ROLE + LOCAL_AVAILABILITY_ROLE, + REMOTE_AVAILABILITY_ROLE ) @@ -1608,8 +1608,8 @@ def paint(self, painter, option, index): provider_active = index.data(LOCAL_PROVIDER_ROLE) provider_remote = index.data(REMOTE_PROVIDER_ROLE) - availability_active = index.data(LOCAL_PROGRESS_ROLE) - availability_remote = index.data(REMOTE_PROGRESS_ROLE) + availability_active = index.data(LOCAL_AVAILABILITY_ROLE) + availability_remote = index.data(REMOTE_AVAILABILITY_ROLE) if not availability_active or not availability_remote: # group lines return