コード例 #1
0
ファイル: collect_instances.py プロジェクト: 81819152/pype
    def process(self, context):
        """Collect all image sequence tools"""

        from avalon.fusion.lib import get_frame_path

        comp = context.data["currentComp"]

        # Get all savers in the comp
        tools = comp.GetToolList(False).values()
        savers = [tool for tool in tools if tool.ID == "Saver"]

        start, end = get_comp_render_range(comp)
        context.data["startFrame"] = start
        context.data["endFrame"] = end

        for tool in savers:
            path = tool["Clip"][comp.TIME_UNDEFINED]

            tool_attrs = tool.GetAttrs()
            active = not tool_attrs["TOOLB_PassThrough"]

            if not path:
                self.log.warning("Skipping saver because it "
                                 "has no path set: {}".format(tool.Name))
                continue

            filename = os.path.basename(path)
            head, padding, tail = get_frame_path(filename)
            ext = os.path.splitext(path)[1]
            assert tail == ext, ("Tail does not match %s" % ext)
            subset = head.rstrip("_. ")  # subset is head of the filename

            # Include start and end render frame in label
            label = "{subset} ({start}-{end})".format(subset=subset,
                                                      start=int(start),
                                                      end=int(end))

            instance = context.create_instance(subset)
            instance.data.update({
                "asset": os.environ["AVALON_ASSET"],  # todo: not a constant
                "subset": subset,
                "path": path,
                "outputDir": os.path.dirname(path),
                "ext": ext,  # todo: should be redundant
                "label": label,
                "families": ["saver"],
                "family": "saver",
                "active": active,
                "publish": active  # backwards compatibility
            })

            instance.append(tool)

            self.log.info("Found: \"%s\" " % path)

        # Sort/grouped by family (preserving local index)
        context[:] = sorted(context, key=self.sort_by_family)

        return context
コード例 #2
0
    def process(self, instance):

        context = instance.context

        key = "__hasRun{}".format(self.__class__.__name__)
        if context.data.get(key, False):
            return
        else:
            context.data[key] = True

        from avalon.fusion.lib import get_frame_path

        AVALON_DEADLINE = api.Session.get("AVALON_DEADLINE",
                                          "http://localhost:8082")
        assert AVALON_DEADLINE, "Requires AVALON_DEADLINE"

        # Collect all saver instances in context that are to be rendered
        saver_instances = []
        for instance in context[:]:
            if not self.families[0] in instance.data.get("families"):
                # Allow only saver family instances
                continue

            if not instance.data.get("publish", True):
                # Skip inactive instances
                continue
            self.log.debug(instance.data["name"])
            saver_instances.append(instance)

        if not saver_instances:
            raise RuntimeError("No instances found for Deadline submittion")

        fusion_version = int(context.data["fusionVersion"])
        filepath = context.data["currentFile"]
        filename = os.path.basename(filepath)
        comment = context.data.get("comment", "")
        deadline_user = context.data.get("deadlineUser", getpass.getuser())

        # Documentation for keys available at:
        # https://docs.thinkboxsoftware.com
        #    /products/deadline/8.0/1_User%20Manual/manual
        #    /manual-submission.html#job-info-file-options
        payload = {
            "JobInfo": {
                # Top-level group name
                "BatchName":
                filename,

                # Job name, as seen in Monitor
                "Name":
                filename,

                # User, as seen in Monitor
                "UserName":
                deadline_user,

                # Use a default submission pool for Fusion
                "Pool":
                "fusion",
                "Plugin":
                "Fusion",
                "Frames":
                "{start}-{end}".format(start=int(context.data["startFrame"]),
                                       end=int(context.data["endFrame"])),
                "Comment":
                comment,
            },
            "PluginInfo": {
                # Input
                "FlowFile": filepath,

                # Mandatory for Deadline
                "Version": str(fusion_version),

                # Render in high quality
                "HighQuality": True,

                # Whether saver output should be checked after rendering
                # is complete
                "CheckOutput": True,

                # Proxy: higher numbers smaller images for faster test renders
                # 1 = no proxy quality
                "Proxy": 1,
            },

            # Mandatory for Deadline, may be empty
            "AuxFiles": []
        }

        # Enable going to rendered frames from Deadline Monitor
        for index, instance in enumerate(saver_instances):
            head, padding, tail = get_frame_path(instance.data["path"])
            path = "{}{}{}".format(head, "#" * padding, tail)
            folder, filename = os.path.split(path)
            payload["JobInfo"]["OutputDirectory%d" % index] = folder
            payload["JobInfo"]["OutputFilename%d" % index] = filename

        # Include critical variables with submission
        keys = [
            # TODO: This won't work if the slaves don't have accesss to
            # these paths, such as if slaves are running Linux and the
            # submitter is on Windows.
            "PYTHONPATH",
            "OFX_PLUGIN_PATH",
            "FUSION9_MasterPrefs"
        ]
        environment = dict(
            {key: os.environ[key]
             for key in keys if key in os.environ}, **api.Session)

        payload["JobInfo"].update({
            "EnvironmentKeyValue%d" % index:
            "{key}={value}".format(key=key, value=environment[key])
            for index, key in enumerate(environment)
        })

        self.log.info("Submitting..")
        self.log.info(json.dumps(payload, indent=4, sort_keys=True))

        # E.g. http://192.168.0.1:8082/api/jobs
        url = "{}/api/jobs".format(AVALON_DEADLINE)
        response = requests.post(url, json=payload)
        if not response.ok:
            raise Exception(response.text)

        # Store the response for dependent job submission plug-ins
        for instance in saver_instances:
            instance.data["deadlineSubmissionJob"] = response.json()