mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
be able to handle situations when OpenPypeVersion is not available
This commit is contained in:
parent
c04f253c0f
commit
887fd9aca3
1 changed files with 131 additions and 23 deletions
|
|
@ -312,6 +312,7 @@ class MongoSettingsHandler(SettingsHandler):
|
||||||
"staging_version"
|
"staging_version"
|
||||||
)
|
)
|
||||||
key_suffix = "_versioned"
|
key_suffix = "_versioned"
|
||||||
|
_version_order_key = "versions_order"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# Get mongo connection
|
# Get mongo connection
|
||||||
|
|
@ -322,8 +323,8 @@ class MongoSettingsHandler(SettingsHandler):
|
||||||
|
|
||||||
self._anatomy_keys = None
|
self._anatomy_keys = None
|
||||||
self._attribute_keys = None
|
self._attribute_keys = None
|
||||||
# TODO prepare version of pype
|
|
||||||
# - pype version should define how are settings saved and loaded
|
self._version_order_checked = False
|
||||||
|
|
||||||
self._system_settings_key = SYSTEM_SETTINGS_KEY + self.key_suffix
|
self._system_settings_key = SYSTEM_SETTINGS_KEY + self.key_suffix
|
||||||
self._project_settings_key = PROJECT_SETTINGS_KEY + self.key_suffix
|
self._project_settings_key = PROJECT_SETTINGS_KEY + self.key_suffix
|
||||||
|
|
@ -668,21 +669,88 @@ class MongoSettingsHandler(SettingsHandler):
|
||||||
upsert=True
|
upsert=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_objected_version(self, version_str):
|
def _check_version_order(self):
|
||||||
|
"""This method will work only in OpenPype process.
|
||||||
|
|
||||||
|
Will create/update mongo document where OpenPype versions are stored
|
||||||
|
in semantic version order.
|
||||||
|
|
||||||
|
This document can be then used to find closes version of settings in
|
||||||
|
processes where 'OpenPypeVersion' is not available.
|
||||||
|
"""
|
||||||
|
# Do this step only once
|
||||||
|
if self._version_order_checked:
|
||||||
|
return
|
||||||
|
self._version_order_checked = True
|
||||||
|
|
||||||
from openpype.lib.openpype_version import get_OpenPypeVersion
|
from openpype.lib.openpype_version import get_OpenPypeVersion
|
||||||
|
|
||||||
OpenPypeVersion = get_OpenPypeVersion()
|
OpenPypeVersion = get_OpenPypeVersion()
|
||||||
|
# Skip if 'OpenPypeVersion' is not available
|
||||||
if OpenPypeVersion is None:
|
if OpenPypeVersion is None:
|
||||||
return None
|
return
|
||||||
return OpenPypeVersion(version=version_str)
|
|
||||||
|
# Query document holding sorted list of version strings
|
||||||
|
doc = self.collection.find_one({"type": self._version_order_key})
|
||||||
|
if not doc:
|
||||||
|
# Just create the document if does not exists yet
|
||||||
|
self.collection.replace_one(
|
||||||
|
{"type": self._version_order_key},
|
||||||
|
{
|
||||||
|
"type": self._version_order_key,
|
||||||
|
"versions": [self._current_version]
|
||||||
|
},
|
||||||
|
upsert=True
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Skip if current version is already available
|
||||||
|
if self._current_version in doc["versions"]:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Add all versions into list
|
||||||
|
objected_versions = [
|
||||||
|
OpenPypeVersion(version=self._current_version)
|
||||||
|
]
|
||||||
|
for version_str in doc["versions"]:
|
||||||
|
objected_versions.append(OpenPypeVersion(version=version_str))
|
||||||
|
|
||||||
|
# Store version string by their order
|
||||||
|
new_versions = []
|
||||||
|
for version in sorted(objected_versions):
|
||||||
|
new_versions.append(str(version))
|
||||||
|
|
||||||
|
# Update versions list and push changes to Mongo
|
||||||
|
doc["versions"] = new_versions
|
||||||
|
self.collection.replace_one(
|
||||||
|
{"type": self._version_order_key},
|
||||||
|
doc,
|
||||||
|
upsert=True
|
||||||
|
)
|
||||||
|
|
||||||
def _find_closest_settings(self, key, legacy_key, additional_filters=None):
|
def _find_closest_settings(self, key, legacy_key, additional_filters=None):
|
||||||
|
"""Try to find closes available versioned settings for settings key.
|
||||||
|
|
||||||
|
This method should be used only if settings for current OpenPype
|
||||||
|
version are not available.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key(str): Settings key under which are settings stored ("type").
|
||||||
|
legacy_key(str): Settings key under which were stored not versioned
|
||||||
|
settings.
|
||||||
|
additional_filters(dict): Additional filters of document. Used
|
||||||
|
for project specific settings.
|
||||||
|
"""
|
||||||
|
# Trigger check of versions
|
||||||
|
self._check_version_order()
|
||||||
|
|
||||||
doc_filters = {
|
doc_filters = {
|
||||||
"type": {"$in": [key, legacy_key]}
|
"type": {"$in": [key, legacy_key]}
|
||||||
}
|
}
|
||||||
if additional_filters:
|
if additional_filters:
|
||||||
doc_filters.update(additional_filters)
|
doc_filters.update(additional_filters)
|
||||||
|
|
||||||
|
# Query base data of each settings doc
|
||||||
other_versions = self.collection.find(
|
other_versions = self.collection.find(
|
||||||
doc_filters,
|
doc_filters,
|
||||||
{
|
{
|
||||||
|
|
@ -691,33 +759,73 @@ class MongoSettingsHandler(SettingsHandler):
|
||||||
"type": True
|
"type": True
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
# Query doc with list of sorted versions
|
||||||
|
versioned_doc = self.collection.find_one(
|
||||||
|
{"type": self._version_order_key}
|
||||||
|
)
|
||||||
|
# Separate queried docs
|
||||||
legacy_settings_doc = None
|
legacy_settings_doc = None
|
||||||
versioned_settings = []
|
versioned_settings_by_version = {}
|
||||||
for doc in other_versions:
|
for doc in other_versions:
|
||||||
if doc["type"] == legacy_key:
|
if doc["type"] == legacy_key:
|
||||||
legacy_settings_doc = doc
|
legacy_settings_doc = doc
|
||||||
|
elif doc["type"] == key:
|
||||||
|
versioned_settings_by_version[doc["version"]] = doc
|
||||||
|
|
||||||
|
# Cases when only legacy settings can be used
|
||||||
|
if (
|
||||||
|
# There are not versioned documents yet
|
||||||
|
not versioned_settings_by_version
|
||||||
|
# Versioned document is not available at all
|
||||||
|
# - this can happen only if old build of OpenPype was used
|
||||||
|
or not versioned_doc
|
||||||
|
# Current OpenPype version is not available
|
||||||
|
# - something went really wrong when this happens
|
||||||
|
or self._current_version not in versioned_doc["versions"]
|
||||||
|
):
|
||||||
|
if not legacy_settings_doc:
|
||||||
|
return None
|
||||||
|
return self.collection.find_one(
|
||||||
|
{"_id": legacy_settings_doc["_id"]}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Separate versions to lower and higher and keep their order
|
||||||
|
lower_versions = []
|
||||||
|
higher_versions = []
|
||||||
|
before = True
|
||||||
|
for version_str in versioned_doc["versions"]:
|
||||||
|
if version_str == self._current_version:
|
||||||
|
before = False
|
||||||
|
elif before:
|
||||||
|
lower_versions.append(version_str)
|
||||||
else:
|
else:
|
||||||
versioned_settings.append(doc)
|
higher_versions.append(version_str)
|
||||||
|
|
||||||
current_version = None
|
# Use legacy settings doc as source document
|
||||||
if versioned_settings:
|
src_doc_id = None
|
||||||
current_version = self._get_objected_version(self._current_version)
|
if legacy_settings_doc:
|
||||||
|
src_doc_id = legacy_settings_doc["_id"]
|
||||||
|
|
||||||
closest_version_doc = legacy_settings_doc
|
# Find highest version which has available settings
|
||||||
if current_version is not None:
|
if lower_versions:
|
||||||
closest_version = None
|
for version_str in reversed(lower_versions):
|
||||||
for version_doc in versioned_settings:
|
doc = versioned_settings_by_version.get(version_str)
|
||||||
version = self._get_objected_version(version_doc["version"])
|
if doc:
|
||||||
if version > current_version:
|
src_doc_id = doc["_id"]
|
||||||
continue
|
break
|
||||||
if closest_version is None or closest_version < version:
|
|
||||||
closest_version = version
|
|
||||||
closest_version_doc = version_doc
|
|
||||||
|
|
||||||
if not closest_version_doc:
|
# Use versions with higher version only if there are not legacy
|
||||||
return None
|
# settings and there are not any versions before
|
||||||
|
if src_doc_id is None and higher_versions:
|
||||||
|
for version_str in higher_versions:
|
||||||
|
doc = versioned_settings_by_version.get(version_str)
|
||||||
|
if doc:
|
||||||
|
src_doc_id = doc["_id"]
|
||||||
|
break
|
||||||
|
|
||||||
return self.collection.find_one({"_id": closest_version_doc["_id"]})
|
if src_doc_id is None:
|
||||||
|
return src_doc_id
|
||||||
|
return self.collection.find_one({"_id": src_doc_id})
|
||||||
|
|
||||||
def _find_closest_system_settings(self):
|
def _find_closest_system_settings(self):
|
||||||
return self._find_closest_settings(
|
return self._find_closest_settings(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue