Merge pull request #3702 from pypeclub/feature/OP-3475_Move-context-specific-functions-to-context-tools

General: Move context specific functions to context tools
This commit is contained in:
Jakub Trllo 2022-08-23 18:02:08 +02:00 committed by GitHub
commit e2c9543761
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 197 additions and 94 deletions

View file

@ -7,6 +7,8 @@ import logging
import functools import functools
import warnings import warnings
import six
from openpype.client import ( from openpype.client import (
get_project, get_project,
get_assets, get_assets,
@ -15,7 +17,6 @@ from openpype.client import (
get_workfile_info, get_workfile_info,
) )
from .profiles_filtering import filter_profiles from .profiles_filtering import filter_profiles
from .events import emit_event
from .path_templates import StringTemplate from .path_templates import StringTemplate
legacy_io = None legacy_io = None
@ -178,7 +179,7 @@ def is_latest(representation):
bool: Whether the representation is of latest version. bool: Whether the representation is of latest version.
Deprecated: Deprecated:
Function will be removed after release version 3.14.* Function will be removed after release version 3.15.*
""" """
from openpype.pipeline.context_tools import is_representation_from_latest from openpype.pipeline.context_tools import is_representation_from_latest
@ -191,7 +192,7 @@ def any_outdated():
"""Return whether the current scene has any outdated content. """Return whether the current scene has any outdated content.
Deprecated: Deprecated:
Function will be removed after release version 3.14.* Function will be removed after release version 3.15.*
""" """
from openpype.pipeline.load import any_outdated_containers from openpype.pipeline.load import any_outdated_containers
@ -212,7 +213,7 @@ def get_asset(asset_name=None):
(MongoDB document) (MongoDB document)
Deprecated: Deprecated:
Function will be removed after release version 3.14.* Function will be removed after release version 3.15.*
""" """
from openpype.pipeline.context_tools import get_current_project_asset from openpype.pipeline.context_tools import get_current_project_asset
@ -224,7 +225,7 @@ def get_asset(asset_name=None):
def get_system_general_anatomy_data(system_settings=None): def get_system_general_anatomy_data(system_settings=None):
""" """
Deprecated: Deprecated:
Function will be removed after release version 3.14.* Function will be removed after release version 3.15.*
""" """
from openpype.pipeline.template_data import get_general_template_data from openpype.pipeline.template_data import get_general_template_data
@ -296,7 +297,7 @@ def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None):
dict: Last version document for entered. dict: Last version document for entered.
Deprecated: Deprecated:
Function will be removed after release version 3.14.* Function will be removed after release version 3.15.*
""" """
if not project_name: if not project_name:
@ -344,6 +345,9 @@ def get_workfile_template_key_from_context(
Raises: Raises:
ValueError: When both 'dbcon' and 'project_name' were not ValueError: When both 'dbcon' and 'project_name' were not
passed. passed.
Deprecated:
Function will be removed after release version 3.16.*
""" """
from openpype.pipeline.workfile import ( from openpype.pipeline.workfile import (
@ -387,6 +391,9 @@ def get_workfile_template_key(
Raises: Raises:
ValueError: When both 'project_name' and 'project_settings' were not ValueError: When both 'project_name' and 'project_settings' were not
passed. passed.
Deprecated:
Function will be removed after release version 3.16.*
""" """
from openpype.pipeline.workfile import get_workfile_template_key from openpype.pipeline.workfile import get_workfile_template_key
@ -411,7 +418,7 @@ def get_workdir_data(project_doc, asset_doc, task_name, host_name):
dict: Data prepared for filling workdir template. dict: Data prepared for filling workdir template.
Deprecated: Deprecated:
Function will be removed after release version 3.14.* Function will be removed after release version 3.15.*
""" """
from openpype.pipeline.template_data import get_template_data from openpype.pipeline.template_data import get_template_data
@ -447,6 +454,9 @@ def get_workdir_with_workdir_data(
Raises: Raises:
ValueError: When both `anatomy` and `project_name` are set to None. ValueError: When both `anatomy` and `project_name` are set to None.
Deprecated:
Function will be removed after release version 3.15.*
""" """
if not anatomy and not project_name: if not anatomy and not project_name:
@ -492,6 +502,9 @@ def get_workdir(
Returns: Returns:
TemplateResult: Workdir path. TemplateResult: Workdir path.
Deprecated:
Function will be removed after release version 3.15.*
""" """
from openpype.pipeline.workfile import get_workdir from openpype.pipeline.workfile import get_workdir
@ -518,7 +531,7 @@ def template_data_from_session(session=None):
dict: All available data from session. dict: All available data from session.
Deprecated: Deprecated:
Function will be removed after release version 3.14.* Function will be removed after release version 3.15.*
""" """
from openpype.pipeline.context_tools import get_template_data_from_session from openpype.pipeline.context_tools import get_template_data_from_session
@ -526,7 +539,7 @@ def template_data_from_session(session=None):
return get_template_data_from_session(session) return get_template_data_from_session(session)
@with_pipeline_io @deprecated("openpype.pipeline.context_tools.compute_session_changes")
def compute_session_changes( def compute_session_changes(
session, task=None, asset=None, app=None, template_key=None session, task=None, asset=None, app=None, template_key=None
): ):
@ -547,64 +560,49 @@ def compute_session_changes(
Returns: Returns:
dict: The required changes in the Session dictionary. dict: The required changes in the Session dictionary.
Deprecated:
Function will be removed after release version 3.16.*
""" """
from openpype.pipeline.context_tools import get_workdir_from_session from openpype.pipeline import legacy_io
from openpype.pipeline.context_tools import compute_session_changes
changes = dict() if isinstance(asset, six.string_types):
project_name = legacy_io.active_project()
asset = get_asset_by_name(project_name, asset)
# If no changes, return directly return compute_session_changes(
if not any([task, asset, app]): session,
return changes asset,
task,
# Get asset document and asset template_key
asset_document = None )
asset_tasks = None
if isinstance(asset, dict):
# Assume asset database document
asset_document = asset
asset_tasks = asset_document.get("data", {}).get("tasks")
asset = asset["name"]
if not asset_document or not asset_tasks:
# Assume asset name
project_name = session["AVALON_PROJECT"]
asset_document = get_asset_by_name(
project_name, asset, fields=["data.tasks"]
)
assert asset_document, "Asset must exist"
# Detect any changes compared session
mapping = {
"AVALON_ASSET": asset,
"AVALON_TASK": task,
"AVALON_APP": app,
}
changes = {
key: value
for key, value in mapping.items()
if value and value != session.get(key)
}
if not changes:
return changes
# Compute work directory (with the temporary changed session so far)
_session = session.copy()
_session.update(changes)
changes["AVALON_WORKDIR"] = get_workdir_from_session(_session)
return changes
@deprecated("openpype.pipeline.context_tools.get_workdir_from_session") @deprecated("openpype.pipeline.context_tools.get_workdir_from_session")
def get_workdir_from_session(session=None, template_key=None): def get_workdir_from_session(session=None, template_key=None):
"""Calculate workdir path based on session data.
Args:
session (Union[None, Dict[str, str]]): Session to use. If not passed
current context session is used (from legacy_io).
template_key (Union[str, None]): Precalculate template key to define
workfile template name in Anatomy.
Returns:
str: Workdir path.
Deprecated:
Function will be removed after release version 3.16.*
"""
from openpype.pipeline.context_tools import get_workdir_from_session from openpype.pipeline.context_tools import get_workdir_from_session
return get_workdir_from_session(session, template_key) return get_workdir_from_session(session, template_key)
@with_pipeline_io @deprecated("openpype.pipeline.context_tools.change_current_context")
def update_current_task(task=None, asset=None, app=None, template_key=None): def update_current_task(task=None, asset=None, app=None, template_key=None):
"""Update active Session to a new task work area. """Update active Session to a new task work area.
@ -617,35 +615,19 @@ def update_current_task(task=None, asset=None, app=None, template_key=None):
Returns: Returns:
dict: The changed key, values in the current Session. dict: The changed key, values in the current Session.
Deprecated:
Function will be removed after release version 3.16.*
""" """
changes = compute_session_changes( from openpype.pipeline import legacy_io
legacy_io.Session, from openpype.pipeline.context_tools import change_current_context
task=task,
asset=asset,
app=app,
template_key=template_key
)
# Update the Session and environments. Pop from environments all keys with project_name = legacy_io.active_project()
# value set to None. if isinstance(asset, six.string_types):
for key, value in changes.items(): asset = get_asset_by_name(project_name, asset)
legacy_io.Session[key] = value
if value is None:
os.environ.pop(key, None)
else:
os.environ[key] = value
data = changes.copy() return change_current_context(asset, task, template_key)
# Convert env keys to human readable keys
data["project_name"] = legacy_io.Session["AVALON_PROJECT"]
data["asset_name"] = legacy_io.Session["AVALON_ASSET"]
data["task_name"] = legacy_io.Session["AVALON_TASK"]
# Emit session change
emit_event("taskChanged", data)
return changes
@deprecated("openpype.client.get_workfile_info") @deprecated("openpype.client.get_workfile_info")
@ -664,6 +646,9 @@ def get_workfile_doc(asset_id, task_name, filename, dbcon=None):
Returns: Returns:
dict: Workfile document or None. dict: Workfile document or None.
Deprecated:
Function will be removed after release version 3.15.*
""" """
# Use legacy_io if dbcon is not entered # Use legacy_io if dbcon is not entered
@ -774,6 +759,11 @@ def save_workfile_data_to_doc(workfile_doc, data, dbcon=None):
@deprecated("openpype.pipeline.workfile.BuildWorkfile") @deprecated("openpype.pipeline.workfile.BuildWorkfile")
def BuildWorkfile(): def BuildWorkfile():
"""Build workfile class was moved to workfile pipeline.
Deprecated:
Function will be removed after release version 3.16.*
"""
from openpype.pipeline.workfile import BuildWorkfile from openpype.pipeline.workfile import BuildWorkfile
return BuildWorkfile() return BuildWorkfile()
@ -816,10 +806,7 @@ def change_timer_to_current_context():
Deprecated: Deprecated:
This method is specific for TimersManager module so please use the This method is specific for TimersManager module so please use the
functionality from there. Function will be removed after release functionality from there. Function will be removed after release
version 3.14.* version 3.15.*
TODO:
- use TimersManager's static method instead of reimplementing it here
""" """
from openpype.pipeline import legacy_io from openpype.pipeline import legacy_io
@ -934,6 +921,9 @@ def get_custom_workfile_template_by_context(
Returns: Returns:
str: Path to template or None if none of profiles match current str: Path to template or None if none of profiles match current
context. (Existence of formatted path is not validated.) context. (Existence of formatted path is not validated.)
Deprecated:
Function will be removed after release version 3.16.*
""" """
if anatomy is None: if anatomy is None:
@ -992,6 +982,9 @@ def get_custom_workfile_template_by_string_context(
Returns: Returns:
str: Path to template or None if none of profiles match current str: Path to template or None if none of profiles match current
context. (Existence of formatted path is not validated.) context. (Existence of formatted path is not validated.)
Deprecated:
Function will be removed after release version 3.16.*
""" """
project_name = None project_name = None
@ -1026,6 +1019,9 @@ def get_custom_workfile_template(template_profiles):
Returns: Returns:
str: Path to template or None if none of profiles match current str: Path to template or None if none of profiles match current
context. (Existence of formatted path is not validated.) context. (Existence of formatted path is not validated.)
Deprecated:
Function will be removed after release version 3.16.*
""" """
from openpype.pipeline import legacy_io from openpype.pipeline import legacy_io
@ -1054,6 +1050,9 @@ def get_last_workfile_with_version(
Returns: Returns:
tuple: Last workfile<str> with version<int> if there is any otherwise tuple: Last workfile<str> with version<int> if there is any otherwise
returns (None, None). returns (None, None).
Deprecated:
Function will be removed after release version 3.16.*
""" """
from openpype.pipeline.workfile import get_last_workfile_with_version from openpype.pipeline.workfile import get_last_workfile_with_version
@ -1080,6 +1079,9 @@ def get_last_workfile(
Returns: Returns:
str: Last or first workfile as filename of full path to filename. str: Last or first workfile as filename of full path to filename.
Deprecated:
Function will be removed after release version 3.16.*
""" """
from openpype.pipeline.workfile import get_last_workfile from openpype.pipeline.workfile import get_last_workfile

View file

@ -16,6 +16,7 @@ from openpype.client import (
get_asset_by_name, get_asset_by_name,
version_is_latest, version_is_latest,
) )
from openpype.lib.events import emit_event
from openpype.modules import load_modules, ModulesManager from openpype.modules import load_modules, ModulesManager
from openpype.settings import get_project_settings from openpype.settings import get_project_settings
@ -445,3 +446,103 @@ def get_custom_workfile_template_from_session(
session["AVALON_APP"], session["AVALON_APP"],
project_settings=project_settings project_settings=project_settings
) )
def compute_session_changes(
session, asset_doc, task_name, template_key=None
):
"""Compute the changes for a session object on task under asset.
Function does not change the session object, only returns changes.
Args:
session (Dict[str, str]): The initial session to compute changes to.
This is required for computing the full Work Directory, as that
also depends on the values that haven't changed.
asset_doc (Dict[str, Any]): Asset document to switch to.
task_name (str): Name of task to switch to.
template_key (Union[str, None]): Prepare workfile template key in
anatomy templates.
Returns:
Dict[str, str]: Changes in the Session dictionary.
"""
changes = {}
# Get asset document and asset
if not asset_doc:
task_name = None
asset_name = None
else:
asset_name = asset_doc["name"]
# Detect any changes compared session
mapping = {
"AVALON_ASSET": asset_name,
"AVALON_TASK": task_name,
}
changes = {
key: value
for key, value in mapping.items()
if value != session.get(key)
}
if not changes:
return changes
# Compute work directory (with the temporary changed session so far)
changed_session = session.copy()
changed_session.update(changes)
workdir = None
if asset_doc:
workdir = get_workdir_from_session(
changed_session, template_key
)
changes["AVALON_WORKDIR"] = workdir
return changes
def change_current_context(asset_doc, task_name, template_key=None):
"""Update active Session to a new task work area.
This updates the live Session to a different task under asset.
Args:
asset_doc (Dict[str, Any]): The asset document to set.
task_name (str): The task to set under asset.
template_key (Union[str, None]): Prepared template key to be used for
workfile template in Anatomy.
Returns:
Dict[str, str]: The changed key, values in the current Session.
"""
changes = compute_session_changes(
legacy_io.Session,
asset_doc,
task_name,
template_key=template_key
)
# Update the Session and environments. Pop from environments all keys with
# value set to None.
for key, value in changes.items():
legacy_io.Session[key] = value
if value is None:
os.environ.pop(key, None)
else:
os.environ[key] = value
data = changes.copy()
# Convert env keys to human readable keys
data["project_name"] = legacy_io.Session["AVALON_PROJECT"]
data["asset_name"] = legacy_io.Session["AVALON_ASSET"]
data["task_name"] = legacy_io.Session["AVALON_TASK"]
# Emit session change
emit_event("taskChanged", data)
return changes

View file

@ -14,15 +14,15 @@ from openpype.lib import (
emit_event, emit_event,
create_workdir_extra_folders, create_workdir_extra_folders,
) )
from openpype.lib.avalon_context import (
update_current_task,
compute_session_changes
)
from openpype.pipeline import ( from openpype.pipeline import (
registered_host, registered_host,
legacy_io, legacy_io,
Anatomy, Anatomy,
) )
from openpype.pipeline.context_tools import (
compute_session_changes,
change_current_context
)
from openpype.pipeline.workfile import get_workfile_template_key from openpype.pipeline.workfile import get_workfile_template_key
from .model import ( from .model import (
@ -408,8 +408,8 @@ class FilesWidget(QtWidgets.QWidget):
) )
changes = compute_session_changes( changes = compute_session_changes(
session, session,
asset=self._get_asset_doc(), self._get_asset_doc(),
task=self._task_name, self._task_name,
template_key=self.template_key template_key=self.template_key
) )
session.update(changes) session.update(changes)
@ -422,8 +422,8 @@ class FilesWidget(QtWidgets.QWidget):
session = legacy_io.Session.copy() session = legacy_io.Session.copy()
changes = compute_session_changes( changes = compute_session_changes(
session, session,
asset=self._get_asset_doc(), self._get_asset_doc(),
task=self._task_name, self._task_name,
template_key=self.template_key template_key=self.template_key
) )
if not changes: if not changes:
@ -431,9 +431,9 @@ class FilesWidget(QtWidgets.QWidget):
# to avoid any unwanted Task Changed callbacks to be triggered. # to avoid any unwanted Task Changed callbacks to be triggered.
return return
update_current_task( change_current_context(
asset=self._get_asset_doc(), self._get_asset_doc(),
task=self._task_name, self._task_name,
template_key=self.template_key template_key=self.template_key
) )