From a7d78bf5d4b989534d545dac8e9b66bbfa55843a Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 8 Nov 2021 17:50:07 +0100 Subject: [PATCH] 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 | 71 ++++++++++--------- 3 files changed, 91 insertions(+), 60 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/tray/lib.py b/openpype/modules/default_modules/sync_server/tray/lib.py index 25c600abd2..dda3598e64 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 @@ STATUS = { 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 6e9c7bf220..75953d6f23 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -15,6 +15,7 @@ from openpype.tools.utils.models import TreeModel, Item 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 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): 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 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): 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 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): 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 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): 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 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): 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 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): {'$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 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): ]} ]}, 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 4bab37449b..2160b27dd5 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -31,6 +31,8 @@ from .model import ( ) 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" + 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 - # 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) + provider_active = providers["active"] + provider_remote = providers["remote"] - painter.drawText( - option.rect, - option.displayAlignment, - "fook" - ) + availability_active = values["active"] + availability_remote = values["remote"] - def displayText(self, value, locale): - pass + 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