AWS Thinkbox Discussion Forums

Plugin get job

Hey,

I’m trying to have a “PostRenderTasks” process that accesses the job information, in particular the output filename.

I have tried;

self.GetJob().JobOutputFileNames

But I’m not getting anything back. Seems like the data isn’t there. Is there something special going on when accessing the job through a plugin?

Do you know if there is output information stored with the job you’re testing with? If you open up the Job Properties dialog for this job from the Monitor, check the Submission Params page, and under Job Info Parameters, check if OutputFilename0 is listed. If it’s not, that would explain why the JobOutputFileNames property for the job returns an empty list.

Cheers,
Ryan

Yeah, I have the properties in the submission;

OutputDirectory0=K:\test\renders OutputFilename0=someting_####.png

Can you post the code you’re using? I tested the following code in a PostRenderTasks for a simple plugin and it seemed to work fine:

        jobFiles = self.GetJob().JobOutputFileNames
        if len(jobFiles) > 0:
            for file in jobFiles:
                self.LogInfo( "OUTPUT FILE: " + file )
        else:
            self.LogInfo( "NO OUTPUT FILES" )

Yes:) Developing a plugin for CelAction; celaction.com/, which is based on the Commandline plugin.

[code]from System.Text.RegularExpressions import *

from Deadline.Plugins import *
from Deadline.Jobs import *
from Deadline.Scripting import *

######################################################################

This is the function that Deadline calls to get an instance of the

main DeadlinePlugin class.

######################################################################
def GetDeadlinePlugin():
return CelActionPlugin()

def CleanupDeadlinePlugin( deadlinePlugin ):
deadlinePlugin.Cleanup()

######################################################################

This is the main DeadlinePlugin class for the CelAction plugin.

######################################################################
class CelActionPlugin(DeadlinePlugin):

def __init__( self ):
    self.InitializeProcessCallback += self.InitializeProcess
    self.RenderExecutableCallback += self.RenderExecutable
    self.RenderArgumentCallback += self.RenderArgument
    self.PostRenderTasksCallback += self.PostRenderTasks

def Cleanup(self):
    for stdoutHandler in self.StdoutHandlers:
        del stdoutHandler.HandleCallback

    del self.InitializeProcessCallback
    del self.RenderExecutableCallback
    del self.RenderArgumentCallback
    del self.PostRenderTasksCallback

def InitializeProcess(self):
    # Set the plugin specific settings.
    self.SingleFramesOnly = False

    # Set the process specific settings.
    self.StdoutHandling = True
    self.PopupHandling = True

    # Ignore 'celaction' Pop-up dialogs
    self.AddPopupIgnorer(".*Rendering.*")
    self.AddPopupIgnorer(".*Wait.*")

def RenderExecutable(self):
    return self.GetConfigEntry("RenderExecutable")

def RenderArgument(self):
    arguments = RepositoryUtils.CheckPathMapping(self.GetPluginInfoEntry( "Arguments" ).strip())
    arguments = arguments.replace( "<STARTFRAME>", str(self.GetStartFrame()) )
    arguments = arguments.replace( "<ENDFRAME>", str(self.GetEndFrame()) )
    arguments = self.ReplacePaddedFrame( arguments, "<STARTFRAME%([0-9]+)>", self.GetStartFrame() )
    arguments = self.ReplacePaddedFrame( arguments, "<ENDFRAME%([0-9]+)>", self.GetEndFrame() )
    arguments = arguments.replace( "<QUOTE>", "\"" )
    return arguments

def PostRenderTasks(self):
    print self.GetStartFrame()
    print self.GetJobInfoEntry('OutputFilename0')

def ReplacePaddedFrame( self, arguments, pattern, frame ):
    frameRegex = Regex( pattern )
    while True:
        frameMatch = frameRegex.Match( arguments )
        if frameMatch.Success:
            paddingSize = int( frameMatch.Groups[ 1 ].Value )
            if paddingSize > 0:
                padding = StringUtils.ToZeroPaddedString( frame, paddingSize, False )
            else:
                padding = str(frame)
            arguments = arguments.replace( frameMatch.Groups[ 0 ].Value, padding )
        else:
            break

    return arguments

[/code]

Thanks! I see that the plugin is using “print self.GetJobInfoEntry(‘OutputFilename0’)” in PostRenderTasks. Can you try replacing that with the code I uploaded in my previous post to see what gets printed out?

Ahh, I think I know what confused me. When printing “self.GetJob().JobOutputFileNames” directly you get “System.String[]”, which looks empty without printing the content of the list.

All working fine now:)

Having some trouble now setting some job data;

[code]import os
import re

from System.Text.RegularExpressions import *

from Deadline.Plugins import *
from Deadline.Jobs import *
from Deadline.Scripting import *

######################################################################

This is the function that Deadline calls to get an instance of the

main DeadlinePlugin class.

######################################################################
def GetDeadlinePlugin():
return CelActionPlugin()

def CleanupDeadlinePlugin( deadlinePlugin ):
deadlinePlugin.Cleanup()

######################################################################

This is the main DeadlinePlugin class for the CelAction plugin.

######################################################################
class CelActionPlugin(DeadlinePlugin):

def __init__( self ):
    self.InitializeProcessCallback += self.InitializeProcess
    self.RenderExecutableCallback += self.RenderExecutable
    self.RenderArgumentCallback += self.RenderArgument
    self.PostRenderTasksCallback += self.PostRenderTasks

def Cleanup(self):
    for stdoutHandler in self.StdoutHandlers:
        del stdoutHandler.HandleCallback

    del self.InitializeProcessCallback
    del self.RenderExecutableCallback
    del self.RenderArgumentCallback
    del self.PostRenderTasksCallback

def InitializeProcess(self):
    # Set the plugin specific settings.
    self.SingleFramesOnly = False

    # Set the process specific settings.
    self.StdoutHandling = True
    self.PopupHandling = True

    # Ignore 'celaction' Pop-up dialogs
    self.AddPopupIgnorer(".*Rendering.*")
    self.AddPopupIgnorer(".*Wait.*")

def RenderExecutable(self):
    return self.GetConfigEntry("RenderExecutable")

def RenderArgument(self):
    arguments = RepositoryUtils.CheckPathMapping(self.GetPluginInfoEntry( "Arguments" ).strip())
    arguments = arguments.replace( "<STARTFRAME>", str(self.GetStartFrame()) )
    arguments = arguments.replace( "<ENDFRAME>", str(self.GetEndFrame()) )
    arguments = self.ReplacePaddedFrame( arguments, "<STARTFRAME%([0-9]+)>", self.GetStartFrame() )
    arguments = self.ReplacePaddedFrame( arguments, "<ENDFRAME%([0-9]+)>", self.GetEndFrame() )
    arguments = arguments.replace( "<QUOTE>", "\"" )
    return arguments

def PostRenderTasks(self):
    output_dir = self.GetJob().JobOutputDirectories[0]
    output_name = self.GetJob().JobOutputFileNames[0]

    padding = len(output_name.split('#')) - 1
    head = output_name.split('#' * padding)[0]
    tail = output_name.split('#' * padding)[1]

    files = []
    pattern = r'%s.*_[0-9]{%s}%s' % (head, padding, tail)
    for f in os.listdir(output_dir):
        if re.findall(pattern, f):
            files.append(f.replace(tail, '')[:-padding])

    for item in list(set(files)):
        value = item + '#' * padding + tail
        print value
        self.GetJob().SetJobEnvironmentKeyValue('OutputFilename1', value)

def ReplacePaddedFrame( self, arguments, pattern, frame ):
    frameRegex = Regex( pattern )
    while True:
        frameMatch = frameRegex.Match( arguments )
        if frameMatch.Success:
            paddingSize = int( frameMatch.Groups[ 1 ].Value )
            if paddingSize > 0:
                padding = StringUtils.ToZeroPaddedString( frame, paddingSize, False )
            else:
                padding = str(frame)
            arguments = arguments.replace( frameMatch.Groups[ 0 ].Value, padding )
        else:
            break

    return arguments

[/code]

Where “self.GetJob().SetJobEnvironmentKeyValue(‘OutputFilename1’, value)” doesn’t seem to work.

PS. I know the value would get overwritten, but just trying to get something written first.

You just need to save the job after making the changes. For example:

        job = self.GetJob()
        for item in list(set(files)):
            value = item + '#' * padding + tail
            print value
            job.SetJobEnvironmentKeyValue('OutputFilename1', value)
        RepositoryUtils.SaveJob( job )

Cheers,
Ryan

Ahh, I can see that I got the wrong method. Is there not a way to add outputs?

Current:

OutputDirectory0=K:\test\renders OutputFilename0=someting_####.png EnvironmentKeyValue0=OutputFilename1=someting_5llew_####.png

Expected:

OutputDirectory0=K:\test\renders OutputFilename0=someting_####.png OutputFilename1=someting_5llew_####.png

For that, you can use RepositoryUtils.UpdateJobOutputFileNames( job, listOfFileNames ). So in your case, you probably want to do something like this:

    def PostRenderTasks(self):
        output_dir = self.GetJob().JobOutputDirectories[0]
        output_name = self.GetJob().JobOutputFileNames[0]

        padding = len(output_name.split('#')) - 1
        head = output_name.split('#' * padding)[0]
        tail = output_name.split('#' * padding)[1]

        files = []
        pattern = r'%s.*_[0-9]{%s}%s' % (head, padding, tail)
        for f in os.listdir(output_dir):
            if re.findall(pattern, f):
                files.append(f.replace(tail, '')[:-padding])

        output_paths = []
        output_paths.append( os.path.join( output_dir , output_path ) )
        
        for item in list(set(files)):
            value = item + '#' * padding + tail
            print value
            output_paths.append( os.path.join( output_dir , value ) )
        
        job = self.GetJob()
        RepositoryUtils.UpdateJobOutputFileNames( job, output_paths )

Sorry, forgot to mention that the reason you have to use RepositoryUtils.UpdateJobOutputFileNames() instead of simply updating the job object directly is that the output properties for the job are stored separately from the other job properties like priority, name, pool, etc, and so they need to be modified differently.

Thank you, Ryan:)

That worked perfectly.

Privacy | Site terms | Cookie preferences