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

General: Move change context functions #2839

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 4 additions & 13 deletions openpype/hosts/fusion/scripts/fusion_switch_shot.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@

# Pipeline imports
import avalon.api
from avalon import io, pipeline
from avalon import io

from openpype.lib import version_up
from openpype.hosts.fusion import api
from openpype.hosts.fusion.api import lib
from openpype.lib.avalon_context import get_workdir_from_session

log = logging.getLogger("Update Slap Comp")

Expand Down Expand Up @@ -44,16 +45,6 @@ def _format_version_folder(folder):
return version_folder


def _get_work_folder(session):
"""Convenience function to get the work folder path of the current asset"""

# Get new filename, create path based on asset and work template
template_work = self._project["config"]["template"]["work"]
work_path = pipeline._format_work_template(template_work, session)

return os.path.normpath(work_path)


def _get_fusion_instance():
fusion = getattr(sys.modules["__main__"], "fusion", None)
if fusion is None:
Expand All @@ -72,7 +63,7 @@ def _format_filepath(session):
asset = session["AVALON_ASSET"]

# Save updated slap comp
work_path = _get_work_folder(session)
work_path = get_workdir_from_session(session)
walk_to_dir = os.path.join(work_path, "scenes", "slapcomp")
slapcomp_dir = os.path.abspath(walk_to_dir)

Expand Down Expand Up @@ -112,7 +103,7 @@ def _update_savers(comp, session):
None
"""

new_work = _get_work_folder(session)
new_work = get_workdir_from_session(session)
renders = os.path.join(new_work, "renders")
version_folder = _format_version_folder(renders)
renders_version = os.path.join(renders, version_folder)
Expand Down
16 changes: 3 additions & 13 deletions openpype/hosts/fusion/utility_scripts/switch_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
from Qt import QtWidgets, QtCore

import avalon.api
from avalon import io, pipeline
from avalon import io
from avalon.vendor import qtawesome as qta

from openpype import style
from openpype.hosts.fusion import api
from openpype.lib.avalon_context import get_workdir_from_session

log = logging.getLogger("Fusion Switch Shot")

Expand Down Expand Up @@ -123,7 +124,7 @@ def _on_use_current_comp(self):

def _on_open_from_dir(self):

start_dir = self._get_context_directory()
start_dir = get_workdir_from_session()
comp_file, _ = QtWidgets.QFileDialog.getOpenFileName(
self, "Choose comp", start_dir)

Expand Down Expand Up @@ -157,17 +158,6 @@ def _on_switch(self):
import colorbleed.scripts.fusion_switch_shot as switch_shot
switch_shot.switch(asset_name=asset, filepath=file_name, new=True)

def _get_context_directory(self):

project = io.find_one({"type": "project",
"name": avalon.api.Session["AVALON_PROJECT"]},
projection={"config": True})

template = project["config"]["template"]["work"]
dir = pipeline._format_work_template(template, avalon.api.Session)

return dir

def collect_slap_comps(self, directory):
items = glob.glob("{}/*.comp".format(directory))
return items
Expand Down
160 changes: 160 additions & 0 deletions openpype/lib/avalon_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,166 @@ def get_workdir(
)


def template_data_from_session(session=None):
""" Return dictionary with template from session keys.

Args:
session (dict, Optional): The Session to use. If not provided use the
currently active global Session.
iLLiCiTiT marked this conversation as resolved.
Show resolved Hide resolved
Returns:
dict: All available data from session.
"""
from avalon import io
import avalon.api

if session is None:
session = avalon.api.Session

project_name = session["AVALON_PROJECT"]
project_doc = io._database[project_name].find_one({"type": "project"})
asset_doc = io._database[project_name].find_one({
"type": "asset",
"name": session["AVALON_ASSET"]
})
task_name = session["AVALON_TASK"]
host_name = session["AVALON_APP"]
return get_workdir_data(project_doc, asset_doc, task_name, host_name)


def compute_session_changes(
session, task=None, asset=None, app=None, template_key=None
):
"""Compute the changes for a Session object on asset, task or app switch

This does *NOT* update the Session object, but returns the changes
required for a valid update of the Session.

Args:
session (dict): 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.
task (str, Optional): Name of task to switch to.
asset (str or dict, Optional): Name of asset to switch to.
You can also directly provide the Asset dictionary as returned
from the database to avoid an additional query. (optimization)
app (str, Optional): Name of app to switch to.

Returns:
dict: The required changes in the Session dictionary.

"""
changes = dict()

# If no changes, return directly
if not any([task, asset, app]):
return changes

# Get asset document and asset
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:
from avalon import io

# Assume asset name
asset_document = io.find_one(
{
"name": asset,
"type": "asset"
},
{"data.tasks": True}
)
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


def get_workdir_from_session(session=None, template_key=None):
import avalon.api

if session is None:
session = avalon.api.Session
project_name = session["AVALON_PROJECT"]
host_name = session["AVALON_APP"]
anatomy = Anatomy(project_name)
template_data = template_data_from_session(session)
anatomy_filled = anatomy.format(template_data)

if not template_key:
task_type = template_data["task"]["type"]
template_key = get_workfile_template_key(
task_type,
host_name,
project_name=project_name
)
return anatomy_filled[template_key]["folder"]


def update_current_task(task=None, asset=None, app=None, template_key=None):
"""Update active Session to a new task work area.

This updates the live Session to a different `asset`, `task` or `app`.

Args:
task (str): The task to set.
asset (str): The asset to set.
app (str): The app to set.

Returns:
dict: The changed key, values in the current Session.

"""
import avalon.api
from avalon.pipeline import emit

changes = compute_session_changes(
avalon.api.Session,
task=task,
asset=asset,
app=app,
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():
avalon.api.Session[key] = value
if value is None:
os.environ.pop(key, None)
else:
os.environ[key] = value

# Emit session change
emit("taskChanged", changes.copy())

return changes


@with_avalon
def get_workfile_doc(asset_id, task_name, filename, dbcon=None):
"""Return workfile document for entered context.
Expand Down
18 changes: 5 additions & 13 deletions openpype/scripts/fusion_switch_shot.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
import logging

# Pipeline imports
from avalon import api, io, pipeline
from avalon import api, io
import avalon.fusion

# Config imports
import openpype.lib as pype
import openpype.hosts.fusion.lib as fusion_lib

from openpype.lib.avalon_context import get_workdir_from_session

log = logging.getLogger("Update Slap Comp")

self = sys.modules[__name__]
Expand Down Expand Up @@ -44,16 +46,6 @@ def _format_version_folder(folder):
return version_folder


def _get_work_folder(session):
"""Convenience function to get the work folder path of the current asset"""

# Get new filename, create path based on asset and work template
template_work = self._project["config"]["template"]["work"]
work_path = pipeline._format_work_template(template_work, session)

return os.path.normpath(work_path)


def _get_fusion_instance():
fusion = getattr(sys.modules["__main__"], "fusion", None)
if fusion is None:
Expand All @@ -72,7 +64,7 @@ def _format_filepath(session):
asset = session["AVALON_ASSET"]

# Save updated slap comp
work_path = _get_work_folder(session)
work_path = get_workdir_from_session(session)
walk_to_dir = os.path.join(work_path, "scenes", "slapcomp")
slapcomp_dir = os.path.abspath(walk_to_dir)

Expand Down Expand Up @@ -103,7 +95,7 @@ def _update_savers(comp, session):
None
"""

new_work = _get_work_folder(session)
new_work = get_workdir_from_session(session)
renders = os.path.join(new_work, "renders")
version_folder = _format_version_folder(renders)
renders_version = os.path.join(renders, version_folder)
Expand Down
8 changes: 5 additions & 3 deletions openpype/tools/assetcreator/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

import ftrack_api
from Qt import QtWidgets, QtCore
from openpype import style
from openpype.api import get_current_project_settings
from openpype.lib.avalon_context import update_current_task
from openpype.tools.utils.lib import qt_app_context
from avalon import io, api, style, schema
from avalon import io, api, schema
from . import widget, model

module = sys.modules[__name__]
Expand Down Expand Up @@ -463,12 +465,12 @@ def create_asset(self):
return
task_name = task_model.itemData(index)[0]
try:
api.update_current_task(task=task_name, asset=asset_name)
update_current_task(task=task_name, asset=asset_name)
self.open_app()

finally:
if origin_task is not None and origin_asset is not None:
api.update_current_task(
update_current_task(
task=origin_task, asset=origin_asset
)

Expand Down
10 changes: 7 additions & 3 deletions openpype/tools/workfiles/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
create_workdir_extra_folders,
get_system_general_anatomy_data
)
from openpype.lib.avalon_context import (
update_current_task,
compute_session_changes
)
from .model import FilesModel
from .view import FilesView

Expand Down Expand Up @@ -667,7 +671,7 @@ def _get_session(self):
session["AVALON_APP"],
project_name=session["AVALON_PROJECT"]
)
changes = pipeline.compute_session_changes(
changes = compute_session_changes(
session,
asset=self._get_asset_doc(),
task=self._task_name,
Expand All @@ -681,7 +685,7 @@ def _enter_session(self):
"""Enter the asset and task session currently selected"""

session = api.Session.copy()
changes = pipeline.compute_session_changes(
changes = compute_session_changes(
session,
asset=self._get_asset_doc(),
task=self._task_name,
Expand All @@ -692,7 +696,7 @@ def _enter_session(self):
# to avoid any unwanted Task Changed callbacks to be triggered.
return

api.update_current_task(
update_current_task(
asset=self._get_asset_doc(),
task=self._task_name,
template_key=self.template_key
Expand Down