Publish Plugins¶
Publish plugins are hooks that handle processing of collected publish items. After all items have been collected, the Publisher attempts to match the items with the appropriate publish plugins. All matched plugins show up as child tasks within the publish item hierarchy.
With tk-multi-publish2 v2.0.0
and higher, each plugin can define a custom UI
that allows users to make changes to the publish settings prior to publishing.
See the methods and properties section below for details on how to implement a
custom publish plugin UI.
Like the collectors, you can override one of the shipped publish plugins or write your own to meet the particular needs of your studio.
Publish Plugin API¶
-
class
tk_multi_publish2.base_hooks.
PublishPlugin
(parent)[source]¶ Bases:
tank.hook.Hook
This class defines the required interface for a publish plugin. Publish plugins are responsible for operating on items collected by the collector plugin. Publish plugins define which items they will operate on as well as the execution logic for each phase of the publish process.
-
icon
¶ The path to an icon on disk that is representative of this plugin (
str
).The icon will be displayed on the left side of the task driven by this plugin, as shown in the image below.
Icons can be stored within the same bundle as the plugin itself and referenced relative to the disk location of the plugin, accessible via
sgtk.Hook.disk_location()
.Example implementation:
@property def icon(self): return os.path.join( self.disk_location, "icons", "publish.png" )
Note
Publish plugins drive the tasks that operate on publish items. It can be helpful to think of items as “things” and tasks as the “actions” that operate on those “things”. A publish icon that represents some type of action can help artists understand the distinction between items and tasks in the interface.
-
name
¶ The general name for this plugin (
str
).This value is not generally used for display. Instances of the plugin are defined within the app’s configuration and those instance names are what is shown in the interface for the tasks.
-
description
¶ Verbose, multi-line description of what the plugin does (
str
).The string can contain html for formatting for display in the UI (any html tags supported by Qt’s rich text engine).
The description is displayed via the plugin’s default
create_settings_widget()
implementation, as shown in the image below:A simple implementation example:
@property def description(self): return ''' Creates a publish in Shotgun. A <b>Publish</b> entry will be created in Shotgun which will include a reference to the file's path on disk. Other users will be able to access the published file via the <b><a href='%s'>Loader</a></b> so long as they have access to the file's location on disk. ''' % (loader_url,)
-
settings
¶ A
dict
defining the configuration interface for this plugin.The dictionary can include any number of settings required by the plugin, and takes the form:
{ <setting_name>: { "type": <type>, "default": <default>, "description": <description> }, <setting_name>: { "type": <type>, "default": <default>, "description": <description> }, ... }
The keys in the dictionary represent the names of the settings. The values are a dictionary comprised of 3 additional key/value pairs.
type
: The type of the setting. This should correspond to one of the data types that toolkit accepts for app and engine settings such ashook
,template
,string
, etc.default
: The default value for the settings. This can beNone
.description
: A description of the setting as a string.
Example implementation:
@property def settings(self): return { "Publish Template": { "type": "template", "default": None, "description": "The output path template for this plugin." }, "Resolution": { "type": "str", "default": "1920x1080" "description": "The output resolution to export before publishing." } }
The settings are exposed via the
settings
key as the plugins are configured via thepublish_plugins
setting in the app’s configuration. Example:publish_plugins: - name: Export and Publish hook: "{config}/export_and_publish.py" settings: Publish Template: export_template Resolution: 2048x1556
The values configured for the plugin will be supplied via settings parameter in the
accept()
,validate()
,publish()
, andfinalize()
methods.The values also drive the custom UI defined by the plugin whick allows artists to manipulate the settings at runtime. See the
create_settings_widget()
,set_ui_settings()
, andget_ui_settings()
for additional information.Note
See the hooks defined in the publisher app’s
hooks/
folder for additional example implementations.
-
item_filters
¶ A
list
of item type wildcardstr
objects that this plugin is interested in.As items are collected by the collector hook, they are given an item type string (see
create_item()
). The strings provided by this property will be compared to each collected item’s type.Only items with types matching entries in this list will be considered by the
accept()
method. As such, this method makes it possible to quickly identify which items the plugin may be interested in. Any sophisticated acceptance logic is deferred to theaccept()
method.Strings can contain glob patters such as
*
, for example["maya.*", "file.maya"]
.
-
accept
(settings, item)[source]¶ This method is called by the publisher to see if the plugin accepts the supplied item for processing.
Only items matching the filters defined via the
item_filters
property will be presented to this method.A publish task will be generated for each item accepted here.
This method returns a
dict
of the following form:{ "accepted": <bool>, "enabled": <bool>, "visible": <bool>, "checked": <bool>, }
The keys correspond to the acceptance state of the supplied item. Not all keys are required. The keys are defined as follows:
accepted
: Indicates if the plugin is interested in this value at all. IfFalse
, no task will be created for this plugin. Required.enabled
: IfTrue
, the created task will be enabled in the UI, otherwise it will be disabled (no interaction allowed). Optional,True
by default.visible
: IfTrue
, the created task will be visible in the UI, otherwise it will be hidden. Optional,True
by default.checked
: IfTrue
, the created task will be checked in the UI, otherwise it will be unchecked. Optional,True
by default.
In addition to the item, the configured settings for this plugin are supplied. The information provided by each of these arguments can be used to decide whether to accept the item.
For example, the item’s
properties
dict
may house meta data about the item, populated during collection. This data can be used to inform the acceptance logic.Example implementation:
def accept(self, settings, item): accept = True # get the path for the item as set during collection path = item.properties["path"] # ensure the file is not too big size_in_bytes = os.stat(path).st_stize if size_in_bytes > math.pow(10, 9): # 1 GB self.logger.warning("File is too big (> 1 GB)!") accept = False return {"accepted": accepted}
Parameters: Returns: dictionary with boolean keys accepted, required and enabled
-
validate
(settings, item)[source]¶ Validates the given item, ensuring it is ok to publish.
Returns a boolean to indicate whether the item is ready to publish. Returning
True
will indicate that the item is ready to publish. IfFalse
is returned, the publisher will disallow publishing of the item.An exception can also be raised to indicate validation failed. When an exception is raised, the error message will be displayed as a tooltip on the task as well as in the logging view of the publisher.
Simple implementation example for a Maya session item validation:
def validate(self, settings, item): path = cmds.file(query=True, sn=True) # ensure the file has been saved if not path: raise Exception("The Maya session has not been saved.") return True
Parameters: Returns: True if item is valid, False otherwise.
-
publish
(settings, item)[source]¶ Executes the publish logic for the given item and settings.
Any raised exceptions will indicate that the publish pass has failed and the publisher will stop execution.
Simple implementation example for a Maya session item publish:
def publish(self, settings, item): path = item.properties["path"] # ensure the session is saved cmds.file(rename=path) cmds.file(save=True, force=True) # the hook's parent is the publisher publisher = self.parent # get the publish info publish_version = publisher.util.get_version_number(path) publish_name = publisher.util.get_publish_name(path) # register the publish and pack the publish info into the item's # properties dict item.properties["sg_publish_data"] = sgtk.util.register_publish( "tk": publisher.sgtk, "context": item.context, "comment": item.description, "path": path, "name": publish_name, "version_number": publish_version, "thumbnail_path": item.get_thumbnail_as_path(), "published_file_type": "Maya Scene", "dependency_paths": self._maya_get_session_depenencies() )
Parameters:
-
finalize
(settings, item)[source]¶ Execute the finalize logic for the given item and settings.
This method can be used to do any type of cleanup or reporting after publishing is complete.
Any raised exceptions will indicate that the finalize pass has failed and the publisher will stop execution.
Simple implementation example for a Maya session item finalization:
def finalize(self, settings, item): path = item.properties["path"] # get the next version of the path next_version_path = publisher.util.get_next_version_path(path) # save to the next version path cmds.file(rename=next_version_path) cmds.file(save=True, force=True)
Parameters:
-
create_settings_widget
(parent)[source]¶ Creates a Qt widget, for the supplied parent widget (a container widget on the right side of the publish UI).
Parameters: parent – The parent to use for the widget being created Returns: A QtGui.QWidget or subclass that displays information about the plugin and/or editable widgets for modifying the plugin’s settings.
-
get_ui_settings
(widget)[source]¶ Invoked by the publisher when the selection changes so the new settings can be applied on the previously selected tasks.
The widget argument is the widget that was previously created by create_settings_widget.
The method returns an dictionary, where the key is the name of a setting that should be updated and the value is the new value of that setting. Note that it is not necessary to return all the values from the UI. This is to allow the publisher to update a subset of settings when multiple tasks have been selected.
Example:
{ "setting_a": "/path/to/a/file" }
Parameters: widget – The widget that was created by create_settings_widget
-
set_ui_settings
(widget, settings)[source]¶ Allows the custom UI to populate its fields with the settings from the currently selected tasks.
The widget is the widget created and returned by create_settings_widget.
A list of settings dictionaries are supplied representing the current values of the settings for selected tasks. The settings dictionaries correspond to the dictionaries returned by the settings property of the hook.
Example:
settings = [ { "seeting_a": "/path/to/a/file" "setting_b": False }, { "setting_a": "/path/to/a/file" "setting_b": False }]
The default values for the settings will be the ones specified in the environment file. Each task has its own copy of the settings.
When invoked with multiple settings dictionaries, it is the responsibility of the custom UI to decide how to display the information. If you do not wish to implement the editing of multiple tasks at the same time, you can raise a NotImplementedError when there is more than one item in the list and the publisher will inform the user than only one task of that type can be edited at a time.
Parameters: - widget – The widget that was created by create_settings_widget
- settings – a list of dictionaries of settings for each selected task.
-