Пример #1
0
def json_audit():
    project = Project()
    environment = Environment()

    asset_dir = project.get_assets_dir()

    failed_str = ""
    for i, asset in enumerate(project.list_assets(AssetType.PROP)):

        try:
            asset_obj = project.get_body(asset)
            element_obj = asset_obj.get_element(Department.MODEL,
                                                force_create=True)
            element_path = element_obj.checkout(
                environment.get_current_username())
            checkout.non_gui_open(element_path, asset)
            json_exporter_non_gui.exportProp(asset_obj)
        except Exception, err:
            error_str = ""
            error_str += "\nError exporting JSON for {0}".format(asset)
            error_str += "\n" + traceback.format_exc()
            print error_str

            failed_str += error_str
            continue
def publish_hda():
    project = Project()
    environment = Environment()
    
    if publish_window.published:
        user = publish_window.user
        comment = publish_window.comment
        
        if is_asset:
            if asset_name in project.list_assets():
                body = project.get_asset(asset_name)
                
            if os.path.exists(src):
                if body is not None:
                    if Element.DEFAULT_NAME in body.list_elements(Department.ASSEMBLY):
                        #save node definition
                        asset.type().definition().updateFromNode(asset)
                        asset.matchCurrentDefinition()
                        element = body.get_element(Department.ASSEMBLY, Element.DEFAULT_NAME)
                        dst = element.publish(user, src, comment)
                        #Ensure file has correct permissions
                        try:
                            os.chmod(dst, 0660)
                        except:
                            pass
                        hou.hda.uninstallFile(src, change_oplibraries_file=False)
                        saveFile = asset_name + "_assembly_main.hdanc"
                        dst = os.path.join(environment.get_assembly_dir(), saveFile)
                        hou.hda.installFile(dst)
            else:
                hou.ui.displayMessage("File does not exist")
def go():
    global checkout_window
    project = Project()
    environment = Environment()
    
    nodes = hou.selectedNodes()
    if len(nodes) == 1:
        #if selected node is digital asset
        if nodes[0].type().definition() is not None:
            asset = nodes[0]
            asset_name = nodes[0].type().name() #get name of asset
            index = asset_name.find("_main")
            asset_name = asset_name[:index]
            src = nodes[0].type().definition().libraryFilePath()
            current_user = environment.get_current_username()
            
            if asset_name in project.list_assets():
                body = project.get_asset(asset_name)
                
            if os.path.exists(src):
                if body is not None: 
                    if Element.DEFAULT_NAME in body.list_elements(Department.ASSEMBLY):
                        element = body.get_element(Department.ASSEMBLY, Element.DEFAULT_NAME)
                        element_path = element.checkout(current_user)
                        hou.hda.uninstallFile(src, change_oplibraries_file=False)
                        hou.hda.installFile(element_path)
                        asset.allowEditingOfContents()
                        hou.ui.displayMessage("Checkout Successful!", title='Success!')
            
    elif len(nodes) > 1:
        hou.ui.displayMessage("Only one node can be selected for checkout")
    else:
        checkout_window = CheckoutWindow(hou.ui.mainQtWindow(), [Department.LIGHTING, Department.FX])    
        checkout_window.finished.connect(checkout_shot)
Пример #4
0
 def __init__(self, parent, renderNodes):
     super(ExportDialog, self).__init__()
     self.parent = parent
     self.project = Project()
     self.environment = Environment()
     self.renderNodes = renderNodes
     self.initUI()
Пример #5
0
def publish_hda():
    project = Project()
    environment = Environment()

    if publish_window.published:
        user = publish_window.user
        comment = publish_window.comment

        if is_asset:
            if asset_name in project.list_assets():
                body = project.get_asset(asset_name)

            if os.path.exists(src):
                if body is not None:
                    if Element.DEFAULT_NAME in body.list_elements(
                            Department.ASSEMBLY):
                        #save node definition
                        asset.type().definition().updateFromNode(asset)
                        asset.matchCurrentDefinition()
                        element = body.get_element(Department.ASSEMBLY,
                                                   Element.DEFAULT_NAME)
                        dst = element.publish(user, src, comment)
                        #Ensure file has correct permissions
                        try:
                            os.chmod(dst, 0660)
                        except:
                            pass
                        hou.hda.uninstallFile(src,
                                              change_oplibraries_file=False)
                        saveFile = asset_name + "_assembly_main.hdanc"
                        dst = os.path.join(environment.get_assembly_dir(),
                                           saveFile)
                        hou.hda.installFile(dst)
            else:
                hou.ui.displayMessage("File does not exist")
Пример #6
0
def rollback_hda():
    filepath = rollback_window.result
    if filepath is not None:
        environment = Environment()
        hou.hda.uninstallFile(src, change_oplibraries_file=False)
        dst = os.path.join(environment.get_hda_dir(), asset_name)
        hou.hda.installFile(dst)
        message_gui.info('Rollback successful')
def rego():
    '''
    reassembles the currently selected node. That means leaving all of the shop nets in place but throwing out the geo and bringing it in fresh.
    '''

    selection = hou.selectedNodes()

    if len(selection) > 1:
        message_gui.error('Please only select one item')
        return
    if len(selection) <1:
        message_gui.error('Please select an item to be reassembled')
        return

    hda = selection[0]

    name = hda.type().name()
    index = name.rfind('_')
    main = name[index:]
    asset_name = name[:index]

    if main.find('_main') == -1:
        message_gui.error('There was something wrong with the name. Try tabbing in the asset again and trying one more time.')
        return

    project = Project()
    environment = Environment()
    username = project.get_current_username()
    asset = project.get_asset(asset_name)
    assembly = asset.get_element(Department.ASSEMBLY)
    # Checkout assembly
    checkout_file = checkout.checkout_hda(hda, project, environment)
    reassemble(hda, project, environment, assembly, asset, checkout_file)
Пример #8
0
def publish_hda(publishWindow, selectedHDA, src):
	project = Project()
	environment = Environment()

	if publishWindow.published:

		user = publishWindow.user
		comment = publishWindow.comment
		hdaName = selectedHDA.type().name()
        department = publishWindow.elementName
        # TODO: UGLY HOTFIX FOR OLD ASSEMBLY & TOOL ASSETS
        asset_name = hdaName.replace("_" + department, "") if department not in [Department.ASSEMBLY, Department.HDA] else hdaName.replace("_main", "")
        body = project.get_body(asset_name)

        if body is None:
            message_gui.error("Asset not found in pipe.")
            return

        if os.path.exists(src):
            try:
                #save node definition this is the same as the Save Node Type menu option. Just to make sure I remember how this works - We are getting the definition of the selected hda and calling the function on it passing in the selected hda. We are not calling the funciton on the selected hda.
                selectedHDA.type().definition().updateFromNode(selectedHDA)
            except hou.OperationFailed, e:
                message_gui.error('There was a problem publishing the HDA to the pipeline.\n', details=str(e))
                return
            try:
                selectedHDA.matchCurrentDefinition()
            except hou.OperationFailed, e:
                message_gui.warning('There was a problem while trying to match the current definition. It\'s not a critical problem but it is a little troubling. Take a look at it and see if you can resolve the problem. Rest assured that the publish did work though', details=str(e))
Пример #9
0
def checkout_hda_go(hda=None):
    global checkout_window
    project = Project()
    environment = Environment()
    if hda is None:
        nodes = hou.selectedNodes()
        if len(nodes) == 1:
            hda = nodes[0]
        elif len(nodes) > 1:
            message_gui.error('Only one node can be selected for checkout')
            return
        else:
            message_gui.error('You need to select an asset node to checkout')
            return

    if hda.type().definition() is not None:
        result = checkout_hda(hda, project, environment)
        if result is not None:
            print('checkout successful')
            #I think having the node unlock is visual que enough that the checkout was fine. Mostly it's annoying to have the window there. And we have a window that will let them know if it didn't work.
            #message_gui.info('Checkout Successful!', title='Success!')
        else:
            message_gui.error('Checkout Failed', title='Failure :()')
    else:
        message_gui.error('Node is not a digital asset')
        return
Пример #10
0
def checkout_shot_go():
    global checkout_window
    project = Project()
    environment = Environment()

    checkout_window = CheckoutWindow(hou.ui.mainQtWindow(),
                                     [Department.LIGHTING, Department.FX])
    checkout_window.finished.connect(checkout_shot)
Пример #11
0
def audit():
    project = Project()
    environment = Environment()

    asset_dir = project.get_assets_dir()

    for i, asset in enumerate(project.list_assets(AssetType.PROP)):

        asset_obj = project.get_body(asset)
        element_obj = asset_obj.get_element(Department.MODEL,
                                            force_create=True)
        element_path = element_obj.checkout(environment.get_current_username())
        #cmds.file(rename='/tmp/lol'+str(i)+'.mb')
        #cmds.file(save=True)
        checkout.non_gui_open(element_path, asset)

    print 'Done'
Пример #12
0
def post_assemble():
    mari.projects.close()
    asset_name = mari_assemble_dialog.result
    print asset_name

    if asset_name is None:
        return

    # Set up the project and environment
    project = Project()
    environment = Environment()
    # get the username and asset
    username = project.get_current_username()
    asset = project.get_asset(asset_name)

    # get the texture element and check it out
    texture = asset.get_element(Department.TEXTURE)
    checkout_file = texture.checkout(username)

    # Get the path to the directory with all of the alembics
    model = asset.get_element(Department.MODEL)
    cache = model.get_cache_dir()

    geo_files = [
        x for x in os.listdir(model.get_cache_dir()) if not os.path.isdir(x)
    ]
    # Remove anything that is not an alemibic file
    for file_path in list(geo_files):
        if (not str(file_path).lower().endswith('.abc')):
            geo_files.remove(file_path)

    if len(geo_files) > 1:
        result = message_gui.light_error(
            'There are multiple alembic files in ' + str(file_path) +
            ' and there should only be one.\nWould you like to continue anyways?\nIt might not work.'
        )
        if not result:
            return
    elif len(geo_files) > 1:
        message_gui.error(
            'There is not an alembic cache for this asset. Make sure that the model has been published in Maya and that the static alembic has been exported.'
        )
        return

    geo_file_path = os.path.join(cache, geo_files[0])
    mari.projects.create(
        texture.get_long_name(), geo_file_path, [], [], dict(), [
            {
                '/': mari.geo.GEOMETRY_IMPORT_DONT_MERGE_CHILDREN
            },
        ])

    # At this point there should be no files left to add but if there are then the user was warned about it and we can go ahead and try to load those in.
    # This was from when we exported a bunch of alembics from Maya instead of just one. And since it shouldn't get called unless something goes wrong I figure it might be interesting to see what would happen if something goes wrong so we might as well leave it.
    for i in range(1, len(geo_files)):
        geo_file_path = os.path.join(cache, geo_files[i])
        mari.geo.load(geo_file_path)
        print 'Loaded ' + geo_file_path
Пример #13
0
def non_gui_publish_hda(hda=None,comment='N/A'):
	if hda is None:
		print ('Error with asset')

	project = Project()
	environment = Environment()
	user = environment.get_current_username()
	hdaName = hda.type().name()


	department=None

	if str(hda) not in Department.ALL:
		print 'v1 asset'
		department=Department.ASSEMBLY
	else:
		department=str(hda)


	asset_name = hdaName.replace("_" + department, "") if department not in [Department.ASSEMBLY, Department.HDA] else hdaName.replace("_main", "")
	body = project.get_body(asset_name)


	if body is None:
		message_gui.error('No asset in pipe')
		return

	#TODO: publish tools
	if body.is_tool():
		print (asset_name+' is tool')
		return
		department=Department.HDA



	hda_src = hda.type().definition().libraryFilePath()
	print hda_src
	element = body.get_element(department, Element.DEFAULT_NAME,force_create=True)

	try:
		hda.type().definition().updateFromNode(hda)
	except hou.OperationFailed, e:
		message_gui.error('There was a problem publishing the HDA to the pipeline.\n', details=str(e))
		return
Пример #14
0
def go():
    parent = QtGui.QApplication.activeWindow()
    if mari.projects.current() is None:
        message_gui.error(
            'You need to have a project open in order to publish it.')
        return

    # Get the file location of the mari archive so that the publish windown will get the hightlight right.
    project_name = mari.projects.current().name()
    src = project_name
    index = project_name.find('_texture')
    if index > 0:
        environment = Environment()
        workspace = environment.get_user_workspace()
        src = os.path.join(workspace, project_name, project_name + '.mra')

    global mari_publish_dialog
    mari_publish_dialog = PublishWindow(src, parent, [Department.TEXTURE])
    mari_publish_dialog.finished.connect(post_publish)
Пример #15
0
def post_publish():
    element = mari_publish_dialog.result

    if mari_publish_dialog.published:
        #save the file
        project = mari.projects.current()
        project_id = project.uuid()
        export_images.go()
        project.save()
        project.close()

        #Publish
        user = mari_publish_dialog.user
        src = mari_publish_dialog.src
        comment = mari_publish_dialog.comment
        env = Environment()
        user_dir = env.get_user_workspace()

        archive_file = os.path.join(user_dir, str(src) + '.mra')
        mari.projects.archive(project_id, archive_file)

        dst = element.publish(user, archive_file, comment)
        #Ensure file has correct permissions
        try:
            os.chmod(dst, 0660)
        except:
            pass

        #Delete Temp file
        try:
            os.remove(archive_file)
        except:
            print 'There was an error while removing the temp file.'
            pass

        remove = message_gui.yes_or_no(
            'The Mari Project is safely published. Would you like to remove the project from your Mari cache?'
        )

        if remove:
            mari.projects.remove(project_id)
Пример #16
0
def go():
	parent = maya_main_window()
	filePath = cmds.file(q=True, sceneName=True)
	if not filePath:
		filePath = Environment().get_user_workspace()
		filePath = os.path.join(filePath, 'untitled.mb')
		filePath = pipeline_io.version_file(filePath)
		cmds.file(rename=filePath)
		cmds.file(save=True)
	global maya_publish_dialog
	maya_publish_dialog = PublishWindow(filePath, parent, [Department.MODEL, Department.RIG, Department.LAYOUT, Department.ANIM, Department.CFX, Department.CYCLES])
	maya_publish_dialog.finished.connect(post_publish)
Пример #17
0
def commit_conversions():

    # Find all boxes that have nodes that were made by the conversion script
    boxes = []
    for item in hou.selectedItems():
        if not isinstance(item, hou.NetworkBox):
            continue

        # If the box doesn't have two nodes in it, it's definitely not ours
        nodes = item.nodes()
        if len(nodes) != 2:
            continue

        # If neither is named _new and/or neither is named _old, it's not one of ours
        if not "_new" in nodes[0].name() and not "_new" in nodes[1].name():
            continue
        if not "_old" in nodes[0].name() and not "_old" in nodes[1].name():
            continue

        # If the assets are not named the same, it's not one of ours
        print nodes[0].name()[:-4]
        print nodes[1].name()[:-4]




        if nodes[0].name()[:-4] != nodes[1].name()[:-4]:
            continue

        # If it passed the tests, add it to the list of network boxes we can work with
        boxes.append(item)

    print boxes

    # Don't go on unless there's a valid network box
    if len(boxes) < 1:
        error_message("There aren't any network boxes created by the conversion script.")
        return

    for box in boxes:
        old_node = next((node for node in box.nodes() if "_old" in node.name()), None)
        new_node = next((node for node in box.nodes() if "_new" in node.name()), None)

        old_hda = old_node.type().definition()
        old_hda.setIcon(Environment().get_project_dir() + '/byu-pipeline-tools/assets/images/icons/tool-icons/1.png')

        publish.non_gui_publish_go(old_node, "Converted to V2")
        for child in new_node.allSubChildren():
            if "_material" in child.type().name() or "_modify" in child.type().name():
                publish.non_gui_publish_go(child, "Converted from V1")
def assemble_hda():
    asset_name = checkout_window.result

    if asset_name is None:
        return

    project = Project()
    environment = Environment()
    username = project.get_current_username()
    asset = project.get_asset(asset_name)
    assembly = asset.get_element(Department.ASSEMBLY)
    # Checkout assembly
    checkout_file = assembly.checkout(username)

    if asset.get_type() == AssetType.SET:
        assemble_set(project, environment, assembly, asset, checkout_file)
    else:
        assemble(project, environment, assembly, asset, checkout_file)
Пример #19
0
    return sys._getframe(1).f_code.co_name
def super_print(message):
    with open(os.path.join(Project().get_users_dir(), Project().get_current_username(), "houdini_log.txt"), "a+") as f:
        print(message)
        sys.stdout.flush()
        f.write("\n" + str(datetime.datetime.now()) + "\n")
        f.write(message)
        f.flush()

# DEBUGGING END

# I set this sucker up as a singleton. It's a matter of preference.
this = sys.modules[__name__]

# The source HDA's are currently stored inside the pipe source code.
hda_path = os.path.join(Environment().get_project_dir(), "byu-pipeline-tools", "houdini-tools", "otls")

# We define the template HDAs definitions here, for use in the methods below
hda_definitions = {
    Department.MATERIAL: hou.hdaDefinition(hou.sopNodeTypeCategory(), "byu_material", os.path.join(hda_path, "byu_material.hda")),
    Department.MODIFY: hou.hdaDefinition(hou.sopNodeTypeCategory(), "byu_modify", os.path.join(hda_path, "byu_modify.hda")),
    Department.HAIR: hou.hdaDefinition(hou.objNodeTypeCategory(), "byu_hair", os.path.join(hda_path, "byu_hair.hda")),
    Department.CLOTH: hou.hdaDefinition(hou.objNodeTypeCategory(), "byu_cloth", os.path.join(hda_path, "byu_cloth.hda"))
}

# The order in which these nodes appear is the order they will be created in
byu_geo_departments = [Department.MODIFY, Department.MATERIAL]
byu_character_departments = [Department.HAIR, Department.CLOTH]

hda_dir = Environment().get_hda_dir()
Пример #20
0
class ExportDialog(QtWidgets.QWidget):

    finished = QtCore.Signal()

    def __init__(self, parent, renderNodes):
        super(ExportDialog, self).__init__()
        self.parent = parent
        self.project = Project()
        self.environment = Environment()
        self.renderNodes = renderNodes
        self.initUI()

    def initUI(self):
        # Window layout
        self.setFixedSize(360, 420)
        self.setWindowTitle('Confirm Export')
        main_layout = QtWidgets.QVBoxLayout()
        self.setLayout(main_layout)

        # Job Name Input Widget
        self.jobName = QtWidgets.QLineEdit('JobName')
        self.jobName.selectAll()
        name_layout = QtWidgets.QHBoxLayout()
        name_layout.addWidget(QtWidgets.QLabel('Job Name:'))
        name_layout.addWidget(self.jobName)
        main_layout.addLayout(name_layout)

        # Number of Cores Input Widget
        self.numCores = QtWidgets.QLineEdit('4')
        coresLayout = QtWidgets.QHBoxLayout()
        coresLayout.addWidget(QtWidgets.QLabel('Number of Cores:'))
        coresLayout.addWidget(self.numCores)
        main_layout.addLayout(coresLayout)

        # Priority and Start Time
        # Priority
        self.priority = QtWidgets.QComboBox()
        priority_opt = [
            'Very Low', 'Low', 'Medium', 'High', 'Very High', 'Critical'
        ]
        for opt in priority_opt:
            self.priority.addItem(opt)
        self.priority.setCurrentIndex(2)
        # Begin time
        self.delay = QtWidgets.QComboBox()
        delay_opts = ['Immediate', 'Manual', 'Delayed']
        for opt in delay_opts:
            self.delay.addItem(opt)
        self.delay.currentIndexChanged.connect(self.delaytime)
        # Combo box options layout
        opts_layout = QtWidgets.QHBoxLayout()
        opts_layout.addWidget(QtWidgets.QLabel('Priority:'))
        opts_layout.addWidget(self.priority)
        opts_layout.addWidget(QtWidgets.QLabel('Begin:'))
        opts_layout.addWidget(self.delay)
        opts_layout.addStretch()
        main_layout.addLayout(opts_layout)

        # Time-frame selection for delayed jobs
        self.delay_time = QtWidgets.QLineEdit('5')
        self.delay_unit = QtWidgets.QComboBox()
        delay_unit_opts = ['mins', 'hours', 'days']
        for opt in delay_unit_opts:
            self.delay_unit.addItem(opt)
        self.delay_unit.setCurrentIndex(0)
        # Delay time layout
        self.delay_layout = QtWidgets.QHBoxLayout()
        self.delay_layout.addWidget(QtWidgets.QLabel('Delay time:'))
        self.delay_layout.addWidget(self.delay_time)
        self.delay_layout.addWidget(self.delay_unit)
        self.delay_layout.addStretch()
        self.delaytime(0)
        main_layout.addLayout(self.delay_layout)

        # Mantra node selection list
        self.select = QtWidgets.QListWidget()
        self.select.setSelectionMode(
            QtWidgets.QAbstractItemView.ExtendedSelection)
        for node in self.renderNodes:
            item = QtWidgets.QListWidgetItem(node.name())
            self.select.addItem(item)
            # must come after adding to widget
            item.setSelected(True)
        main_layout.addWidget(self.select)

        # Buttons
        self.export_btn = QtWidgets.QPushButton('Export')
        self.export_btn.clicked.connect(self.export)
        self.cancel_btn = QtWidgets.QPushButton('Cancel')
        self.cancel_btn.clicked.connect(self.close)
        btn_layout = QtWidgets.QHBoxLayout()
        btn_layout.addWidget(self.cancel_btn)
        btn_layout.addWidget(self.export_btn)
        main_layout.addLayout(btn_layout)

    # Show/Hide the delay-time options
    def delaytime(self, index):
        i = 0
        items = self.delay_layout.count()
        while i < items:
            item = self.delay_layout.itemAt(i).widget()
            if item:
                item.setVisible(index == 2)
            i = i + 1

    # Export selected mantra nodes for rendering
    def export(self):
        self.close()

        # Get user, project, and time info so we can make a temp folder
        user = self.environment.get_current_username()
        projectName = self.project.get_name().lower()
        time_now = datetime.datetime.now()

        #Make a temp folder for the rib files based on the user and the current time
        ribDir = self.project.get_project_dir(
        ) + '/ribs/' + user + '_' + time_now.strftime('%m%d%y_%H%M%S')
        print 'ribDir', ribDir, ' renderNodes size: ', len(self.renderNodes)
        os.makedirs(ribDir)

        # Sanitize job title
        title = re.sub(r'[{}"\']', '',
                       str(self.jobName.text())).strip(' \t\n\r')
        if len(title) == 0:
            title = self.empty_text

        numCores = int(
            re.sub(r'[{}"\']', '', str(self.numCores.text())).strip(' \t\n\r'))
        if numCores < 1:
            numCores = 1

        # This job we send to tractor
        job = author.Job()
        job.title = title
        job.priority = self.priority.currentIndex()
        path = '/opt/pixar/RenderManProServer-21.5/bin/'
        job.envkey = [
            'setenv PATH=' + path +
            ' RMANTREE=/opt/pixar/RenderManProServer-21.5'
        ]
        job.service = 'PixarRender'
        job.comment = 'Spooled by ' + user

        # Loop through each frame of our nodes and create frame tasks and append it to the job script
        for index, node in enumerate(self.renderNodes):
            # Make sure this node was selected for export
            print node.name()
            if self.select.item(index).isSelected():
                name = node.name()
                validFrameRange = node.parm('trange').eval()
                if validFrameRange == 0:
                    start = int(hou.frame())
                    end = int(hou.frame())
                    step = 1
                else:
                    start = int(node.parm('f1').eval())
                    end = int(node.parm('f2').eval())
                    step = int(node.parm('f3').eval())
                task = author.Task()
                task.title = '%s [%d-%d]' % (name, start, end)

                oldOutputMode = node.parm('rib_outputmode').eval()
                try:
                    oldDiskFile = node.parm('soho_diskfile').expression()
                    useExpression = True
                    print 'We are getting rid of expressiion'
                except:
                    oldDiskFile = node.parm('soho_diskfile').eval()
                    useExpression = False
                    print 'we didn\'t get rid of them'
                # Activate rib output
                node.parm('rib_outputmode').set(True)
                node.parm('soho_diskfile').deleteAllKeyframes()
                node.parm('soho_diskfile').set(ribDir +
                                               ('/%s_$F04.rib' % name))

                print 'start rib making'
                script = os.path.join(self.project.get_project_dir(),
                                      'byu-pipeline-tools', 'houdini-tools',
                                      'parallelRibs', 'taskDistribution.sh')
                subprocess.call([
                    'sh', script,
                    str(start),
                    str(end),
                    str(node.path()),
                    str(saveHipRenderCopy()),
                    str(numCores)
                ])
                print 'finish rib making'

                # Loop through every frame in framerange
                for frame in range(start, end + 1, step):
                    subtask = author.Task()
                    subtask.title = 'Frame %04d' % (frame)
                    ribFile = '%s/%s_%04d.rib' % (ribDir, name, frame)
                    print 'Here is the rib file ', ribFile

                    # Commands for Debugging
                    cmdPATH = author.Command()
                    cmdPATH.argv = ['echo', '${PATH}']
                    cmdRMANTREE = author.Command()
                    cmdRMANTREE.argv = ['echo', '${RMANTREE}']
                    printenv = author.Command()
                    printenv.argv = ['printenv']
                    # subtask.addCommand(cmdPATH)
                    # subtask.addCommand(cmdRMANTREE)
                    # subtask.addCommand(printenv)

                    # Real Commands
                    command = author.Command()
                    command.argv = ['prman', '-progress', ribFile]
                    command.service = 'PixarRender'
                    subtask.addCommand(command)
                    task.addChild(subtask)
                job.addChild(task)

                # Restore rib output
                node.parm('soho_outputmode').set(oldOutputMode)
                if useExpression:
                    node.parm('soho_diskfile').setExpression(oldDiskFile)
                else:
                    node.parm('soho_diskfile').set(oldDiskFile)

        command = author.Command()
        command.argv = ['rm', '-rf', ribDir]
        job.addCleanup(command)

        # print 'This is the new job script \n', job.asTcl()

        # Attempt to spool job, with the option to keep trying
        choice = True
        while choice:
            try:
                job.spool()
                message_gui.info('Job sent to Tractor!')
                break
            except Exception as err:
                choice = message_gui.yes_or_no(
                    'We ran into this problem while spooling the job:\nWould you like to try again?',
                    details=str(err),
                    title='Continue?')
        #Cleanup ifd files, if they didn't want to retry
        if not choice:
            shutil.rmtree(ribDir)