def get_references(self): """Get references.""" self.logger.debug("Getting references") COL_SEPARATOR = "COLSEP" ROW_SEPARATOR = "ROWSEP" references_string = alias_api.get_references() references = [] self.logger.debug("Received: {}".format(references_string)) for row in references_string.split(ROW_SEPARATOR): if not row or COL_SEPARATOR not in row: continue name, path = row.split(COL_SEPARATOR) references.append({ "node": name, "type": "reference", "path": path.replace("/", os.path.sep), }) self.logger.debug("Sending: {}".format(references)) return references
def _alias_find_additional_session_dependencies(): """ Find additional dependencies from the session """ references = [] for reference in alias_api.get_references(): path = reference.path if path not in references: references.append(path) return references
def scan_scene(self): """ The scan scene method is executed once at startup and its purpose is to analyze the current scene and return a list of references that are to be potentially operated on. The return data structure is a list of dictionaries. Each scene reference that is returned should be represented by a dictionary with three keys: - "node": The name of the 'node' that is to be operated on. Most DCCs have a concept of a node, path or some other way to address a particular object in the scene. - "type": The object type that this is. This is later passed to the update method so that it knows how to handle the object. - "path": Path on disk to the referenced object. Toolkit will scan the list of items, see if any of the objects matches any templates and try to determine if there is a more recent version available. Any such versions are then displayed in the UI as out of date. """ refs = [] # only deal with references which match a template for r in alias_api.get_references(): reference_template = self._get_reference_template_from_path( r.source_path) if not reference_template: reference_template = self._get_reference_template_from_path( r.path) # here, we've imported a file as reference and we need to use the source path to get the next # available version if reference_template and reference_template.validate(r.path): refs.append({ "node": r.name if r.uuid == [] else r.uuid, "type": "reference", "path": r.source_path.replace("/", os.path.sep), }) else: refs.append({ "node": r.name if r.uuid == [] else r.uuid, "type": "reference", "path": r.path.replace("/", os.path.sep), }) return refs
def accept(self, settings, item): """ Method called by the publisher to determine if an item is of any interest to this plugin. 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. Returns a dictionary with the following booleans: - accepted: Indicates if the plugin is interested in this value at all. Required. - enabled: If True, the plugin will be enabled in the UI, otherwise it will be disabled. Optional, True by default. - visible: If True, the plugin will be visible in the UI, otherwise it will be hidden. Optional, True by default. - checked: If True, the plugin will be checked in the UI, otherwise it will be unchecked. Optional, True by default. :param settings: Dictionary of Settings. The keys are strings, matching the keys returned in the settings property. The values are `Setting` instances. :param item: Item to process :returns: dictionary with boolean keys accepted, required and enabled """ publisher = self.parent publish_template_setting = settings.get("Publish Template").value if publish_template_setting: # if a publish template is configured, disable context change. This # is a temporary measure until the publisher handles context switching # natively. item.context_change_allowed = False # get the publish template definition to determine if we are trying to publish a WREF file. # If so, disable the plugin if some references are loaded in the current session publish_template = publisher.engine.get_template_by_name( publish_template_setting) if publish_template and "wref" in publish_template.definition: alias_references = alias_api.get_references() if alias_references: return { "accepted": True, "enabled": False, "checked": False } path = _session_path() if not path: # the session has not been saved before (no path determined). # provide a save button. the session will need to be saved before # validation will succeed. self.logger.warn("The Alias session has not been saved.", extra=_get_save_as_action()) self.logger.info( "Alias '%s' plugin accepted the current Alias session." % (self.name, )) return {"accepted": True, "checked": False}
def validate(self, settings, item): """ Validates the given item to check that it is ok to publish. Returns a boolean to indicate validity. :param settings: Dictionary of Settings. The keys are strings, matching the keys returned in the settings property. The values are `Setting` instances. :param item: Item to process :returns: True if item is valid, False otherwise. """ publisher = self.parent path = _session_path() # ---- ensure the session has been saved if not path: # the session still requires saving. provide a save button. # validation fails. error_msg = "The Alias session has not been saved." self.logger.error( error_msg, extra=sgtk.platform.current_engine().open_save_as_dialog ) raise Exception(error_msg) # ---- check that references exist, display warning for invalid refs for reference in alias_api.get_references(): ref_path = reference.path if not os.path.exists(ref_path): self.logger.warning( "Reference path does not exist '{}'".format(ref_path) ) # ---- check the session against any attached work template # get the path in a normalized state. no trailing separator, # separators are appropriate for current os, no double separators, # etc. path = sgtk.util.ShotgunPath.normalize(path) # if the session item has a known work template, see if the path # matches. if not, warn the user and provide a way to save the file to # a different path work_template = item.properties.get("work_template") if work_template: if not work_template.validate(path): error_msg = "The current session does not match the configured work file template." self.logger.warning( error_msg, extra={ "action_button": { "label": "Save File", "tooltip": "Save the current Alias session to a " "different file name", "callback": sgtk.platform.current_engine().open_save_as_dialog, } }, ) raise Exception(error_msg) else: self.logger.debug("Work template configured and matches session file.") else: self.logger.debug("No work template configured.") # ---- see if the version can be bumped post-publish # check to see if the next version of the work file already exists on # disk. if so, warn the user and provide the ability to jump to save # to that version now (next_version_path, version) = self._get_next_version_info(path, item) if next_version_path and os.path.exists(next_version_path): # determine the next available version_number. just keep asking for # the next one until we get one that doesn't exist. while os.path.exists(next_version_path): (next_version_path, version) = self._get_next_version_info( next_version_path, item ) error_msg = "The next version of this file already exists on disk." self.logger.error( error_msg, extra={ "action_button": { "label": "Save to v%s" % (version,), "tooltip": "Save to the next available version number, " "v%s" % (version,), "callback": lambda: publisher.engine.save_file_as( next_version_path ), } }, ) raise Exception(error_msg) # ---- populate the necessary properties and call base class validation # populate the publish template on the item if found publish_template_setting = settings.get("Publish Template") publish_template = publisher.engine.get_template_by_name( publish_template_setting.value ) if publish_template: item.properties["publish_template"] = publish_template # set the session path on the item for use by the base plugin validation # step. NOTE: this path could change prior to the publish phase. item.properties["path"] = path # run the base class validation return super(AliasSessionPublishPlugin, self).validate(settings, item)