Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Refactor: changed legacy way to update database for Hero version integrate #3941

Merged
merged 10 commits into from
Oct 11, 2022
43 changes: 43 additions & 0 deletions openpype/client/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
CURRENT_ASSET_DOC_SCHEMA = "openpype:asset-3.0"
CURRENT_SUBSET_SCHEMA = "openpype:subset-3.0"
CURRENT_VERSION_SCHEMA = "openpype:version-3.0"
CURRENT_HERO_VERSION_SCHEMA = "openpype:hero_version-1.0"
CURRENT_REPRESENTATION_SCHEMA = "openpype:representation-2.0"
CURRENT_WORKFILE_INFO_SCHEMA = "openpype:workfile-1.0"
CURRENT_THUMBNAIL_SCHEMA = "openpype:thumbnail-1.0"
Expand Down Expand Up @@ -162,6 +163,34 @@ def new_version_doc(version, subset_id, data=None, entity_id=None):
}


def new_hero_version_doc(version_id, subset_id, data=None, entity_id=None):
"""Create skeleton data of hero version document.

Args:
version_id (ObjectId): Is considered as unique identifier of version
under subset.
subset_id (Union[str, ObjectId]): Id of parent subset.
data (Dict[str, Any]): Version document data.
entity_id (Union[str, ObjectId]): Predefined id of document. New id is
created if not passed.

Returns:
Dict[str, Any]: Skeleton of version document.
"""

if data is None:
data = {}

return {
"_id": _create_or_convert_to_mongo_id(entity_id),
"schema": CURRENT_HERO_VERSION_SCHEMA,
"type": "hero_version",
"version_id": version_id,
"parent": subset_id,
"data": data
}


def new_representation_doc(
name, version_id, context, data=None, entity_id=None
):
Expand Down Expand Up @@ -293,6 +322,20 @@ def prepare_version_update_data(old_doc, new_doc, replace=True):
return _prepare_update_data(old_doc, new_doc, replace)


def prepare_hero_version_update_data(old_doc, new_doc, replace=True):
"""Compare two hero version documents and prepare update data.

Based on compared values will create update data for 'UpdateOperation'.

Empty output means that documents are identical.

Returns:
Dict[str, Any]: Changes between old and new document.
"""

return _prepare_update_data(old_doc, new_doc, replace)


def prepare_representation_update_data(old_doc, new_doc, replace=True):
"""Compare two representation documents and prepare update data.

Expand Down
120 changes: 59 additions & 61 deletions openpype/plugins/publish/integrate_hero_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
import errno
import shutil

from bson.objectid import ObjectId
from pymongo import InsertOne, ReplaceOne
import pyblish.api

from openpype.client import (
Expand All @@ -14,10 +12,15 @@
get_archived_representations,
get_representations,
)
from openpype.client.operations import (
OperationsSession,
new_hero_version_doc,
prepare_hero_version_update_data,
prepare_representation_update_data,
)
from openpype.lib import create_hard_link
from openpype.pipeline import (
schema,
legacy_io,
schema
)
from openpype.pipeline.publish import get_publish_template_name

Expand Down Expand Up @@ -187,35 +190,33 @@ def integrate_instance(
repre["name"].lower(): repre for repre in old_repres
}

if old_version:
new_version_id = old_version["_id"]
else:
new_version_id = ObjectId()

new_hero_version = {
"_id": new_version_id,
"version_id": src_version_entity["_id"],
"parent": src_version_entity["parent"],
"type": "hero_version",
"schema": "openpype:hero_version-1.0"
}
schema.validate(new_hero_version)
op_session = OperationsSession()

# Don't make changes in database until everything is O.K.
bulk_writes = []
entity_id = None
if old_version:
entity_id = old_version["_id"]
new_hero_version = new_hero_version_doc(
src_version_entity["_id"],
src_version_entity["parent"],
entity_id=entity_id
)

if old_version:
self.log.debug("Replacing old hero version.")
bulk_writes.append(
ReplaceOne(
{"_id": new_hero_version["_id"]},
new_hero_version
)
new_hero_version["_id"] = old_version["_id"]
kalisp marked this conversation as resolved.
Show resolved Hide resolved
update_data = prepare_hero_version_update_data(
old_version, new_hero_version
)
op_session.update_entity(
project_name,
new_hero_version["type"],
old_version["_id"],
update_data
)
else:
self.log.debug("Creating first hero version.")
bulk_writes.append(
InsertOne(new_hero_version)
op_session.create_entity(
project_name, new_hero_version["type"], new_hero_version
)

# Separate old representations into `to replace` and `to delete`
Expand All @@ -235,7 +236,7 @@ def integrate_instance(
archived_repres = list(get_archived_representations(
project_name,
# Check what is type of archived representation
version_ids=[new_version_id]
version_ids=[new_hero_version["_id"]]
))
archived_repres_by_name = {}
for repre in archived_repres:
Expand Down Expand Up @@ -382,34 +383,37 @@ def integrate_instance(
# Replace current representation
if repre_name_low in old_repres_to_replace:
old_repre = old_repres_to_replace.pop(repre_name_low)

repre["_id"] = old_repre["_id"]
bulk_writes.append(
ReplaceOne(
{"_id": old_repre["_id"]},
repre
)
update_data = prepare_representation_update_data(
old_repre, repre)
op_session.update_entity(
project_name,
old_repre["type"],
old_repre["_id"],
update_data
)

# Unarchive representation
elif repre_name_low in archived_repres_by_name:
archived_repre = archived_repres_by_name.pop(
repre_name_low
)
old_id = archived_repre["old_id"]
repre["_id"] = old_id
bulk_writes.append(
ReplaceOne(
{"old_id": old_id},
repre
)
repre["_id"] = archived_repre["old_id"]
update_data = prepare_representation_update_data(
archived_repre, repre)
op_session.update_entity(
project_name,
old_repre["type"],
archived_repre["_id"],
update_data
)

# Create representation
else:
repre["_id"] = ObjectId()
bulk_writes.append(
InsertOne(repre)
)
repre.pop("_id", None)
op_session.create_entity(project_name, "representation",
repre)

self.path_checks = []

Expand All @@ -430,28 +434,22 @@ def integrate_instance(
archived_repre = archived_repres_by_name.pop(
repre_name_low
)
repre["old_id"] = repre["_id"]
repre["_id"] = archived_repre["_id"]
repre["type"] = archived_repre["type"]
bulk_writes.append(
ReplaceOne(
{"_id": archived_repre["_id"]},
repre
)
)

changes = {"old_id": repre["_id"],
"_id": archived_repre["_id"],
"type": archived_repre["type"]}
op_session.update_entity(project_name,
archived_repre["type"],
archived_repre["_id"],
changes)
else:
repre["old_id"] = repre["_id"]
repre["_id"] = ObjectId()
repre["old_id"] = repre.pop("_id")
repre["type"] = "archived_representation"
bulk_writes.append(
InsertOne(repre)
)
op_session.create_entity(project_name,
"archived_representation",
repre)

if bulk_writes:
legacy_io.database[project_name].bulk_write(
bulk_writes
)
op_session.commit()

# Remove backuped previous hero
if (
Expand Down