Exemplo n.º 1
0
    def publish(self, settings, item):
        """
        Executes the publish logic for the given item and settings.

        :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
        """

        publisher = self.parent

        # 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(_session_path())

        # ensure the session is saved in its current state
        alias_api.save_file()

        # get the path to a versioned copy of the file.
        version_path = publisher.util.get_version_path(path, "v001")

        # save to the new version path
        alias_api.save_file_as(version_path)
        self.logger.info(
            "A version number has been added to the Alias file...")
        self.logger.info("  Alias file path: %s" % (version_path, ))
Exemplo n.º 2
0
    def open_save_as_dialog(self):
        """
        Launch a Qt file browser to select a file, then save the supplied
        project to that path.
        """

        from sgtk.platform.qt import QtGui

        # Alias doesn't appear to have a "save as" dialog accessible via
        # python. so open our own Qt file dialog.
        file_dialog = QtGui.QFileDialog(
            parent=self.get_parent_window(),
            caption="Save As",
            directory=os.path.expanduser("~"),
            filter="Alias file (*.wire)",
        )
        file_dialog.setLabelText(QtGui.QFileDialog.Accept, "Save")
        file_dialog.setLabelText(QtGui.QFileDialog.Reject, "Cancel")
        file_dialog.setOption(QtGui.QFileDialog.DontResolveSymlinks)
        file_dialog.setOption(QtGui.QFileDialog.DontUseNativeDialog)
        if not file_dialog.exec_():
            return
        path = file_dialog.selectedFiles()[0]

        if os.path.splitext(path)[-1] != ".wire":
            path = "{0}.wire".format(path)

        if path:
            alias_api.save_file_as(path)
Exemplo n.º 3
0
    def save_file_as(self, path):
        """
        Convenience function to call the Alias Python API to save the file and ensure
        the context is saved for the current stage.

        :param path: the file path to save.
        :type path: str
        """

        status = alias_api.save_file_as(path)
        if status != int(alias_api.AlStatusCode.Success):
            self.logger.error(
                "Alias Python API Error: save_file_as('{}') returned non-success status code {}"
                .format(path, status))

        # Save context for the current stage that was updated
        self.save_context_for_stage()
Exemplo n.º 4
0
    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=_get_save_as_action())
            raise Exception(error_msg)

        # ---- 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):
                self.logger.warning(
                    "The current session does not match the configured work "
                    "file template.",
                    extra={
                        "action_button": {
                            "label": "Save File",
                            "tooltip": "Save the current Alias session to a "
                            "different file name",
                            # will launch wf2 if configured
                            "callback": _get_save_as_action(),
                        }
                    },
                )
            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: alias_api.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)
Exemplo n.º 5
0
    def execute(self,
                operation,
                file_path,
                context=None,
                parent_action=None,
                file_version=None,
                read_only=None,
                **kwargs):
        """
        Main hook entry point

        :param operation:       String
                                Scene operation to perform

        :param file_path:       String
                                File path to use if the operation
                                requires it (e.g. open)

        :param context:         Context
                                The context the file operation is being
                                performed in.

        :param parent_action:   This is the action that this scene operation is
                                being executed for.  This can be one of:
                                - open_file
                                - new_file
                                - save_file_as
                                - version_up

        :param file_version:    The version/revision of the file to be opened.  If this is 'None'
                                then the latest version should be opened.

        :param read_only:       Specifies if the file should be opened read-only or not

        :returns:               Depends on operation:
                                'current_path' - Return the current scene
                                                 file path as a String
                                'reset'        - True if scene was reset to an empty
                                                 state, otherwise False
                                all others     - None
        """

        self.parent.engine._stop_watching = True

        try:

            if operation == "current_path":
                return alias_api.get_current_path()

            elif operation == "open":
                # if the current file is an empty file, we can erase it and open the new file instead
                if alias_api.is_empty_file():
                    alias_api.open_file(file_path, new_stage=False)
                # otherwise, ask the use what he'd like to do
                else:
                    open_in_current_stage = (
                        self.parent.engine.open_delete_stages_dialog())
                    if open_in_current_stage == QtGui.QMessageBox.Cancel:
                        return
                    elif open_in_current_stage == QtGui.QMessageBox.No:
                        alias_api.open_file(file_path, new_stage=True)
                    else:
                        alias_api.reset()
                        alias_api.open_file(file_path, new_stage=False)

            elif operation == "save":
                alias_api.save_file()

            elif operation == "save_as":
                alias_api.save_file_as(file_path)

            elif operation == "reset":
                # do not reset the file if we try to open another one as we have to deal with the stages an resetting
                # the current session will delete all the stages
                if parent_action == "open_file":
                    return True
                if alias_api.is_empty_file() and len(
                        alias_api.get_stages()) == 1:
                    alias_api.reset()
                    return True
                else:
                    open_in_current_stage = self.parent.engine.open_delete_stages_dialog(
                        new_file=True)
                    if open_in_current_stage == QtGui.QMessageBox.Cancel:
                        return False
                    elif open_in_current_stage == QtGui.QMessageBox.No:
                        stage_name = uuid.uuid4().hex
                        alias_api.create_stage(stage_name)
                    else:
                        alias_api.reset()
                    return True

        finally:

            self.parent.engine._stop_watching = False
            if operation in ["save_as", "prepare_new", "open"]:
                self.parent.engine.save_context_for_stage(context)