Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
559160f
Remove framework dependency from dialogs classes
carlos-villavicencio-adsk Jun 15, 2026
4da2df7
Migrate build asset/template workflows
carlos-villavicencio-adsk Jun 15, 2026
eb20c5a
Remove more references
carlos-villavicencio-adsk Jun 16, 2026
9c0d72d
Use sandbox functions
carlos-villavicencio-adsk Jun 16, 2026
5f23754
Update references on models
carlos-villavicencio-adsk Jun 16, 2026
c1df4e3
Migrate thumbnail utilities
carlos-villavicencio-adsk Jun 16, 2026
1657118
Use more sandbox functions
carlos-villavicencio-adsk Jun 16, 2026
5952719
Finish migrating framework-floam references
carlos-villavicencio-adsk Jun 16, 2026
77efc5e
Update references from sgtk.flowam.create
carlos-villavicencio-adsk Jun 16, 2026
cb88ca1
Remove framework loading
carlos-villavicencio-adsk Jun 16, 2026
74da4d5
Rename fucntion to get FlowAMActions instance
carlos-villavicencio-adsk Jun 16, 2026
e3c5ba5
Rename `am_base_obj` to `flowam_actions`
carlos-villavicencio-adsk Jun 16, 2026
fc27088
Latest Updates
carlos-villavicencio-adsk Jun 16, 2026
4a3f936
Finish clean-up
carlos-villavicencio-adsk Jun 16, 2026
9fad77e
Update imports
carlos-villavicencio-adsk Jun 17, 2026
8dfe63d
Tested reference link and download workflows
carlos-villavicencio-adsk Jun 17, 2026
7e52826
Finished testing build scene, open, reference, discard.
carlos-villavicencio-adsk Jun 17, 2026
3d30405
Tested create template workflow
carlos-villavicencio-adsk Jun 17, 2026
7d66ea0
Add tk_core_ref value for testing
carlos-villavicencio-adsk Jun 17, 2026
a7329ae
Format
carlos-villavicencio-adsk Jun 17, 2026
19a5298
Fix fixture
carlos-villavicencio-adsk Jun 17, 2026
10c7615
remove migrated methods
carlos-villavicencio-adsk Jun 17, 2026
d04aa23
Rename `medm` directory to `flowam`
carlos-villavicencio-adsk Jun 17, 2026
c489bc4
Removed `enable_flowam` setting
carlos-villavicencio-adsk Jun 18, 2026
97c5e03
Get rid of `FlowAMActions` dependency injection and use app level module
carlos-villavicencio-adsk Jun 18, 2026
43df636
Update core new definitions
carlos-villavicencio-adsk Jun 18, 2026
f5c1d84
Fix format
carlos-villavicencio-adsk Jun 18, 2026
8e4a4af
Handle error
carlos-villavicencio-adsk Jun 19, 2026
fa1d044
Remove dead code
carlos-villavicencio-adsk Jun 19, 2026
9becc41
Update references, rename variables
carlos-villavicencio-adsk Jun 19, 2026
71eedd4
Fix discard draft logic
carlos-villavicencio-adsk Jun 19, 2026
12e841f
Format
carlos-villavicencio-adsk Jun 19, 2026
113d946
Update reference sequence
carlos-villavicencio-adsk Jun 19, 2026
b74125e
Improved `CreateReferenceError`
carlos-villavicencio-adsk Jun 19, 2026
2974c6b
CR fixes
carlos-villavicencio-adsk Jun 19, 2026
ce26987
Fix method signature
carlos-villavicencio-adsk Jun 22, 2026
38e0e20
Import flowam module just to be safe
carlos-villavicencio-adsk Jun 22, 2026
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
15 changes: 15 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
A loader application that lets you add new items to the scene.
"""

from types import ModuleType

import sgtk
import os

Expand All @@ -28,6 +30,7 @@ def init_app(self):
return

tk_multi_loader = self.import_module("tk_multi_loader")
self._flowam = tk_multi_loader.flowam

# the manager class provides the interface for loading. We store a
# reference to it to enable the create_loader_action_manager method exposed on
Expand Down Expand Up @@ -95,3 +98,15 @@ def create_loader_manager(self, bundle=None):
:returns: A :class:`tk_multi_loader.LoaderManager` instance
"""
return self._manager_class(bundle or self)

@property
def flowam(self) -> ModuleType:
"""
Access to the FlowAM integration module for this app. This module provides
drop-in replacements for the standard Shotgun-based Loader models and actions,
backed by Flow Asset Management (FlowAM) instead of the ShotGrid REST API.

:returns: The FlowAM integration module for this app
:rtype: :mod:`tk_multi_loader.flowam`
"""
return self._flowam
1 change: 1 addition & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ jobs:
- name: tk-framework-qtwidgets
- name: tk-framework-shotgunutils
- name: tk-shell
tk_core_ref: ticket/sg-43461/migrate-host-base
6 changes: 3 additions & 3 deletions hooks/tk-3dsmaxplus_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class MaxActions(HookBaseClass):
##############################################################################################################
# public interface - to be overridden by deriving classes

def generate_actions(self, sg_publish_data, actions, ui_area, **kwargs):
def generate_actions(self, sg_publish_data, actions, ui_area):
"""
Returns a list of action instances for a particular publish.
This method is called each time a user clicks a publish somewhere in the UI.
Expand Down Expand Up @@ -101,7 +101,7 @@ def generate_actions(self, sg_publish_data, actions, ui_area, **kwargs):

return action_instances

def execute_multiple_actions(self, actions, **kwargs):
def execute_multiple_actions(self, actions):
"""
Executes the specified action on a list of items.

Expand Down Expand Up @@ -132,7 +132,7 @@ def execute_multiple_actions(self, actions, **kwargs):
params = single_action["params"]
self.execute_action(name, params, sg_publish_data)

def execute_action(self, name, params, sg_publish_data, **kwargs):
def execute_action(self, name, params, sg_publish_data):
"""
Execute a given action. The data sent to this be method will
represent one of the actions enumerated by the generate_actions method.
Expand Down
30 changes: 10 additions & 20 deletions hooks/tk-desktop_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ def generate_actions(
sg_publish_data: dict,
actions: list,
ui_area: str,
**kwargs,
) -> list:
"""
Return a list of action instances for a particular publish.
Expand Down Expand Up @@ -77,21 +76,15 @@ def generate_actions(

action_instances = []

enable_flowam = app.get_setting("enable_flowam", False)
if enable_flowam:
am_base_obj = kwargs.get("am_base_obj")
if not am_base_obj:
raise Exception(
"FlowAM is enabled but no Asset Management base object was passed to the action hook. "
"FlowAM specific actions will not be generated."
)
if app.context.flow_project_id:
flowam_actions = app.flowam.FlowAMActions()

if "download" in actions and sg_publish_data.get("type") == "PublishedFile":
version_number = sg_publish_data.get("version_number")

if (
version_number is not None
and version_number != am_base_obj.DRAFT_VERSION_IDENTIFIER
and version_number != flowam_actions.DRAFT_VERSION_IDENTIFIER
):
action_instances.append(
{
Expand Down Expand Up @@ -130,9 +123,9 @@ def generate_actions(
if (
"reference_copy_link" in actions
and sg_publish_data.get(
"version_number", am_base_obj.DRAFT_VERSION_IDENTIFIER
"version_number", flowam_actions.DRAFT_VERSION_IDENTIFIER
)
> am_base_obj.DRAFT_VERSION_IDENTIFIER
> flowam_actions.DRAFT_VERSION_IDENTIFIER
):
action_instances.append(
{
Expand All @@ -146,7 +139,7 @@ def generate_actions(

return action_instances

def execute_multiple_actions(self, actions: list, **kwargs) -> None:
def execute_multiple_actions(self, actions: list) -> None:
"""
Executes the specified action on a list of items.

Expand All @@ -171,22 +164,19 @@ def execute_multiple_actions(self, actions: list, **kwargs) -> None:

:param list actions: Action dictionaries.
"""
app = self.parent
app.log_info("Executing action '%s' on the selection")
# Helps to visually scope selections
# Execute each action.
for single_action in actions:
name = single_action["name"]
sg_publish_data = single_action["sg_publish_data"]
params = single_action["params"]
self.execute_action(name, params, sg_publish_data, **kwargs)
self.execute_action(name, params, sg_publish_data)

def execute_action(
self,
name: str,
params: Any,
sg_publish_data: dict,
**kwargs,
) -> None:
"""
Print out all actions. The data sent to this be method will
Expand All @@ -202,7 +192,7 @@ def execute_action(
"Execute action called for action %s. "
"Parameters: %s. Publish Data: %s" % (name, params, sg_publish_data)
)
am_base_obj = kwargs.get("am_base_obj")
flowam_actions = app.flowam.FlowAMActions()

if name == "create_generic_asset":
# Right click a task the left panel
Expand All @@ -213,10 +203,10 @@ def execute_action(
self._launch_publisher(name, sg_publish_data)

elif name == "reference_copy_link":
am_base_obj._create_reference_copy_link(sg_publish_data)
flowam_actions._create_reference_copy_link(sg_publish_data)

elif name == "download":
am_base_obj._download_asset_revision(sg_publish_data)
flowam_actions._download_asset_revision(sg_publish_data)

def _launch_publisher(self, action_name: str, sg_publish_data: dict) -> None:
"""
Expand Down
6 changes: 3 additions & 3 deletions hooks/tk-flame_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class FlameActionError(Exception):
class FlameActions(HookBaseClass):
##############################################################################################################
# public interface - to be overridden by deriving classes
def generate_actions(self, sg_publish_data, actions, ui_area, **kwargs):
def generate_actions(self, sg_publish_data, actions, ui_area):
"""
Returns a list of action instances for a particular publish.
This method is called each time a user clicks a publish somewhere in the UI.
Expand Down Expand Up @@ -136,7 +136,7 @@ def generate_actions(self, sg_publish_data, actions, ui_area, **kwargs):

return action_instances

def execute_multiple_actions(self, actions, **kwargs):
def execute_multiple_actions(self, actions):
"""
Executes the specified action on a list of items.

Expand Down Expand Up @@ -167,7 +167,7 @@ def execute_multiple_actions(self, actions, **kwargs):
params = single_action["params"]
self.execute_action(name, params, sg_publish_data)

def execute_action(self, name, params, sg_publish_data, **kwargs):
def execute_action(self, name, params, sg_publish_data):
"""
Execute a given action. The data sent to this be method will
represent one of the actions enumerated by the generate_actions method.
Expand Down
56 changes: 26 additions & 30 deletions hooks/tk-houdini_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import re

import sgtk
from tank_vendor.flow_integration_sdk.sandbox import is_new_asset

HookBaseClass = sgtk.get_hook_baseclass()

Expand All @@ -25,7 +26,7 @@ class HoudiniActions(HookBaseClass):
##############################################################################################################
# public interface - to be overridden by deriving classes

def generate_actions(self, sg_publish_data, actions, ui_area, **kwargs):
def generate_actions(self, sg_publish_data, actions, ui_area):
"""
Returns a list of action instances for a particular publish.
This method is called each time a user clicks a publish somewhere in the UI.
Expand Down Expand Up @@ -102,22 +103,18 @@ def generate_actions(self, sg_publish_data, actions, ui_area, **kwargs):
# -----------------------
# FlowAM specific actions
# -----------------------
enable_flowam = app.get_setting("enable_flowam", False)
if enable_flowam:
am_base_obj = kwargs.get("am_base_obj")
if not am_base_obj:
raise Exception(
"FlowAM is enabled but no Asset Management base object was passed to the action hook. "
"FlowAM specific actions will not be generated."
)
if self.parent.context.flow_project_id:
flowam_actions = app.flowam.FlowAMActions()

if "open" in actions and sg_publish_data.get("type") == "PublishedFile":
if (
am_base_obj._is_local_draft(sg_publish_data)
flowam_actions.is_local_draft_by_revision(
sg_publish_data.get("sg_flow_revision_id")
)
or sg_publish_data.get(
"version_number", am_base_obj.DRAFT_VERSION_IDENTIFIER
"version_number", flowam_actions.DRAFT_VERSION_IDENTIFIER
)
> am_base_obj.DRAFT_VERSION_IDENTIFIER
> flowam_actions.DRAFT_VERSION_IDENTIFIER
):
action_instances.append(
{
Expand All @@ -134,7 +131,7 @@ def generate_actions(self, sg_publish_data, actions, ui_area, **kwargs):

if (
version_number is not None
and version_number != am_base_obj.DRAFT_VERSION_IDENTIFIER
and version_number != flowam_actions.DRAFT_VERSION_IDENTIFIER
):
action_instances.append(
{
Expand All @@ -148,9 +145,9 @@ def generate_actions(self, sg_publish_data, actions, ui_area, **kwargs):
if "discard_draft" in actions:
draft_id = sg_publish_data.get("sg_flow_revision_id")

if am_base_obj._is_local_draft(
sg_publish_data
) and am_base_obj._is_new_asset(draft_id):
if flowam_actions.is_local_draft_by_revision(
sg_publish_data.get("sg_flow_revision_id")
) and is_new_asset(draft_id):
action_instances.append(
{
"name": "discard_draft",
Expand All @@ -163,9 +160,9 @@ def generate_actions(self, sg_publish_data, actions, ui_area, **kwargs):
if (
"reference_copy_link" in actions
and sg_publish_data.get(
"version_number", am_base_obj.DRAFT_VERSION_IDENTIFIER
"version_number", flowam_actions.DRAFT_VERSION_IDENTIFIER
)
!= am_base_obj.DRAFT_VERSION_IDENTIFIER
!= flowam_actions.DRAFT_VERSION_IDENTIFIER
):
action_instances.append(
{
Expand Down Expand Up @@ -199,7 +196,7 @@ def generate_actions(self, sg_publish_data, actions, ui_area, **kwargs):

return action_instances

def execute_multiple_actions(self, actions, **kwargs):
def execute_multiple_actions(self, actions):
"""
Executes the specified action on a list of items.

Expand Down Expand Up @@ -228,9 +225,9 @@ def execute_multiple_actions(self, actions, **kwargs):
name = single_action["name"]
sg_publish_data = single_action["sg_publish_data"]
params = single_action["params"]
self.execute_action(name, params, sg_publish_data, **kwargs)
self.execute_action(name, params, sg_publish_data)

def execute_action(self, name, params, sg_publish_data, **kwargs):
def execute_action(self, name, params, sg_publish_data):
"""
Execute a given action. The data sent to this be method will
represent one of the actions enumerated by the generate_actions method.
Expand All @@ -249,27 +246,26 @@ def execute_action(self, name, params, sg_publish_data, **kwargs):
# -----------------------
# FlowAM specific actions
# -----------------------
enable_flowam = app.get_setting("enable_flowam", False)
if enable_flowam:
am_base_obj = kwargs.get("am_base_obj")
if self.parent.context.flow_project_id:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like it is better to just create a function to group flow logic.
For example create a _flow_execute_action and called it when flow project id exists

flowam_actions = app.flowam.FlowAMActions()

if name == "open":
am_base_obj._do_open(sg_publish_data)
flowam_actions._do_open(sg_publish_data)

if name == "reference_copy_link":
am_base_obj._create_reference_copy_link(sg_publish_data)
flowam_actions._create_reference_copy_link(sg_publish_data)

if name == "discard_draft":
am_base_obj._discard_draft(sg_publish_data)
flowam_actions._discard_draft(sg_publish_data)

if name == "build_new_scene":
am_base_obj._build_new_scene(sg_publish_data)
flowam_actions._build_new_scene(sg_publish_data)

if name == "build_new_template":
am_base_obj._build_new_template(sg_publish_data)
flowam_actions._build_new_template(sg_publish_data)

if name == "download":
am_base_obj._download_asset_revision(sg_publish_data)
flowam_actions._download_asset_revision(sg_publish_data)

return

Expand Down
6 changes: 3 additions & 3 deletions hooks/tk-mari_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class MariActions(HookBaseClass):
##############################################################################################################
# public interface - to be overridden by deriving classes

def generate_actions(self, sg_publish_data, actions, ui_area, **kwargs):
def generate_actions(self, sg_publish_data, actions, ui_area):
"""
Returns a list of action instances for a particular publish.
This method is called each time a user clicks a publish somewhere in the UI.
Expand Down Expand Up @@ -108,7 +108,7 @@ def generate_actions(self, sg_publish_data, actions, ui_area, **kwargs):

return action_instances

def execute_multiple_actions(self, actions, **kwargs):
def execute_multiple_actions(self, actions):
"""
Executes the specified action on a list of items.

Expand Down Expand Up @@ -139,7 +139,7 @@ def execute_multiple_actions(self, actions, **kwargs):
params = single_action["params"]
self.execute_action(name, params, sg_publish_data)

def execute_action(self, name, params, sg_publish_data, **kwargs):
def execute_action(self, name, params, sg_publish_data):
"""
Execute a given action. The data sent to this be method will
represent one of the actions enumerated by the generate_actions method.
Expand Down
Loading