def _deleteJob(self):
     if self.job_id is not None:
         if self['keep_job_on_cancel_cook'].evaluateInt():
             af.Cmd().stopJobById(self.job_id)
         else:
             af.Cmd().deleteJobById(self.job_id)
     self._initData()
    def onSchedule(self, work_item):
        """
        [virtual] onSchedule(self, pdg.WorkItem) -> pdg.SchedulerResult

        This callback is evaluated when the given pdg.WorkItem is ready to be executed.
        """
        if len(work_item.command) == 0:
            return pdg.scheduleResult.CookSucceeded

        self._log('onSchedule input: {} - {}'.format(work_item.node.name,
                                                     work_item.name))

        # Ensure directories exist and serialize the work item
        self.createJobDirsAndSerializeWorkItems(work_item)

        # Create a task:
        task = self._constructTask(work_item)

        # Check that a block for the current TOP node exists:
        if not work_item.node.name in self.job_block_name_id:
            # We need to append a new block to the job,
            # as this is the first work item of a current TOP node.
            block = self._constructBlock(work_item)
            block.tasks.append(task)
            block_id = 0

            if self.job_id is None:
                # This is probably the first onSchedule call.
                # The job was not created.
                job = self._constructJob()
                job.blocks.append(block)
                if not self._sendJob(job):
                    return pdg.scheduleResult.CookFailed

            else:
                # Append a new block to the job
                struct = af.Cmd().appendBlocks(self.job_id, [block])
                if not 'block_ids' in struct['object']:
                    self._log('Error appending block:\n' + str(struct))
                    return pdg.scheduleResult.Failed

                block_id = struct['object']['block_ids'][0]

            self.job_block_name_id[work_item.node.name] = block_id
            self.job_tasks_id_workid[block_id] = {}
            self.job_tasks_id_workid[block_id][0] = work_item.id

        else:
            # Current TOP node block exists, we need just to append the task
            block_id = self.job_block_name_id[work_item.node.name]
            struct = af.Cmd().appendTasks(self.job_id, block_id, [task])
            if not 'task_ids' in struct['object']:
                self._log('Error appending task:\n' + str(struct))
                return pdg.scheduleResult.Failed

            task_id = struct['object']['task_ids'][0]
            self.job_tasks_id_workid[block_id][task_id] = work_item.id

        return pdg.scheduleResult.Succeeded
Exemple #3
0
def submit():

    input_rops = [i[0] for i in hou.pwd().inputDependencies()]
    rop_list = []
    job_ids = []
    cmd = af.Cmd()

    for rop in input_rops:

        rop.parm('af_offline_job').set(1)
        rop.parm('af_ubmit').pressButton()
        rop.parm('af_job_info_pretty').eval()
        rop_list.append(rop.evalParm('af_job_info_pretty'))
        rop.parm('af_offline_job').set(0)

    for i in range(len(rop_list)):

        cmd.data['mask'] = rop_list[i]
        job = cmd.getJobList()
        id = job[0]['id']
        job_ids.append(id)

        if i > 0:
            cmd.action = 'action'
            cmd.data['type'] = 'jobs'
            cmd.data['mask'] = rop_list[i]
            cmd.data['params'] = {'depend_mask': rop_list[i - 1]}
            cmd._sendRequest()

    job_ids.reverse()
    for id in job_ids:
        cmd.setJobState(id, 'start')
Exemple #4
0
def get_afanasy_hostnames():
    import af
    hostnames = []
    cmd = af.Cmd()
    clients = cmd.renderGetList()
    for client in clients:
        hostnames.append(client["name"])
    return hostnames
def setUserDialog():
    name, ok = QtWidgets.QInputDialog.getText(
        None, 'Set Render User', 'Ender New Name:', text=cgruconfig.VARS['USERNAME']
    )

    if not ok:
        return

    af.Cmd().renderSetUserName( name)
    refreshAfter()
Exemple #6
0
def refresh():

    global Render
    global RenderFull

    if Render is None:
        # Get render by local host name
        renders = af.Cmd().renderGetLocal()
        if renders is not None and len(renders):
            Render = renders[0]

    if Render is not None:
        # Get render by ID, as we already know it
        obj = af.Cmd().renderGetId(Render['id'],'full')
        if obj is not None and 'object' in obj and 'render' in obj['object']:
            RenderFull = obj['object']
            Render = RenderFull['render']
            if Refresh:
                Refresh.setDefaultInterval()
        else:
            if obj is None:
                print('ERROR: NULL object reveived.')
            elif 'info' in obj:
                obj = obj['info']
                if obj['kind'] == 'error':
                    print('ERROR: %s' % obj['text'])
                else:
                    print('%s: %s' % (obj['kind'], obj['text']))
            else:
                print('ERROR: Unexpected object reveived:')
                print(json.dumps(RenderFull, sort_keys=True, indent=4))

            # "Reset" render information, if failed to reveive it
            # Most probably render was deleted,
            # and there is no more render with such ID
            Render = None
            RenderFull = None
            # Increase refresh interval by 10 times
            if Refresh:
                Refresh.setIntervalKoeff(10)

    cmd.Tray.showIcon( makeIcon())
    cmd.Tray.updateToolTip(makeTip())
    def onTick(self):
        """
        [virtual] Called during a cook.
                  Checks on jobs in flight to see if any have finished.
        """

        # check that the job was created
        if self.job_id is None:
            # OnTick can be called before onSchedule!
            # Before onSchedule job is not created/sent
            return pdg.tickResult.SchedulerReady

        # get job progress
        job_progress = af.Cmd().getJobProgress(self.job_id)
        if job_progress is None:
            self._log('Error getting job progress.')
            return pdg.tickResult.SchedulerBusy

        job_progress = job_progress['progress']
        ids_to_del = {}

        for block_id in self.job_tasks_id_workid:
            ids_to_del[block_id] = []
            for task_id in self.job_tasks_id_workid[block_id]:
                work_item_id = self.job_tasks_id_workid[block_id][task_id]
                task_progress = job_progress[block_id][task_id]
                state = task_progress['state']

                if state.find('RUN') != -1:
                    self.onWorkItemStartCook(work_item_id, -1)

                elif state.find('ERR') != -1:
                    if self['report_fail_on_error'].evaluateInt():
                        self.onWorkItemFailed(work_item_id, -1)
                        # If the graph is setup to block on failures, then
                        # we continue to track the task
                        if not self.isWaitForFailures:
                            ids_to_del[block_id].append(task_id)

                elif state.find('SKP') != -1:
                    self.onWorkItemCanceled(work_item_id, -1)
                    ids_to_del[block_id].append(task_id)

                elif state.find('DON') != -1:
                    time_started = task_progress['tst']
                    time_done = task_progress['tdn']
                    cook_time = float(time_started - time_done)
                    self.onWorkItemSucceeded(work_item_id, -1, cook_time)
                    ids_to_del[block_id].append(task_id)

        for block_id in ids_to_del:
            for task_id in ids_to_del[block_id]:
                del self.job_tasks_id_workid[block_id][task_id]

        return pdg.tickResult.SchedulerReady
def refresh():

    global Render
    global RenderFull

    if Render is None:
        renders = af.Cmd().renderGetLocal()
        if renders is not None and len(renders):
            Render = renders[0]

    if Render is not None:
        obj = af.Cmd().renderGetId(Render['id'],'full')
        if obj is not None and 'object' in obj and 'render' in obj['object']:
            RenderFull = obj['object']
            Render = RenderFull['render']
        else:
            print('ERROR: Unexpected object reveived:')
            print(json.dumps(RenderFull, sort_keys=True, indent=4))

    cmd.Tray.showIcon( makeIcon())
Exemple #9
0
 def request_renderclients():
     client_list = []
     cmd = af.Cmd()
     clients = cmd.renderGetList()
     for client in clients:
         name = client['name']
         # version = client['engine']
         address = client['address']
         ip = address['ip']
         port = address['port']
         client_list.append(AF_RenderClient(name, "", ip, port))
     return client_list
Exemple #10
0
def refresh():
	renders = af.Cmd().renderGetLocal()
	if renders is not None and len(renders):
		render = renders[0]
		if "state" in render:
			online = render["state"].find('OFF') == -1
			nimby = render["state"].find('NbY') != -1
			NIMBY = render["state"].find('NBY') != -1
			busy = render["state"].find('RUN') != -1
			cmd.Tray.showRenderIcon(online, nimby or NIMBY, busy)
	else:
		cmd.Tray.showIcon()
Exemple #11
0
def showInfo(tray=None):
    renders = af.Cmd().renderGetLocal()

    if renders is None or len(renders) == 0:
        if tray is not None:
            tray.showMessage('Render information:',
                             'No local render client found.')
        return

    global WndInfo

    WndInfo = QtGui.QTextEdit()
    WndInfo.setPlainText(json.dumps(renders[0], sort_keys=True, indent=4))
    WndInfo.setReadOnly(True)
    WndInfo.resize(WndInfo.viewport().size())
    WndInfo.setWindowTitle('AFANASY Render Information:')
    WndInfo.show()
Exemple #12
0
def setNIMBY(text='(keeper)'):
    cmd = af.Cmd().renderSetNIMBY(text)
Exemple #13
0
def setFree(text='(keeper)'):
    cmd = af.Cmd().renderSetFree(text)
Exemple #14
0
def ejectNotMyTasks(text='(keeper)'):
    cmd = af.Cmd().renderEjectNotMyTasks(text)
    render.refreshAfter()
Exemple #15
0
def setnimby(text='(keeper)'):
    cmd = af.Cmd().renderSetNimby(text)
    def evaluateCmd(self, i_start=False):
        if not self.constructed:
            return

        self.evaluated = False
        self.bStart.setEnabled(False)
        # self.fileChange()

        # Check parameters:
        # Frame range:

        framestart = self.fields['framestart'].value()
        frameend = self.fields['frameend'].value()
        frameby = self.fields['frameby'].value()
        framespt = self.fields['framespt'].value()

        if i_start:

            if framestart > frameend:
                QtWidgets.QMessageBox.critical(
                    self, 'Critical', 'First frame is greater that last.')
                return

            tasksnum = (1.0 + frameend - framestart) / (1.0 * frameby *
                                                        framespt)

            if tasksnum > 10000.0:
                answer = QtWidgets.QMessageBox.warning(
                    self, 'Warning', 'Number of tasks > 10000',
                    QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Abort)
                if answer != QtWidgets.QMessageBox.Yes:
                    return
            if tasksnum > 100000.0:
                answer = QtWidgets.QMessageBox.warning(
                    self, 'Warning', 'Number of tasks > 100000',
                    QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Abort)
                if answer != QtWidgets.QMessageBox.Yes:
                    return
            if tasksnum > 1000000.0:
                self.teCmd.setText(
                    'The number of tasks over one million. Call you system '
                    'administrator, supervisor or TD.')
                return

        # Check wdir:
        if self.fields['scenewdir'].isChecked():
            self.fields['wdir'].setEnabled(False)
        else:
            self.fields['wdir'].setEnabled(True)
        # Set job name:
        if self.fields['jobnamescene'].isChecked():
            self.fields['jobname'].setText(
                os.path.basename(str(self.fields['scenefile'].text())))
            self.fields['jobname'].setEnabled(False)
        else:
            self.fields['jobname'].setEnabled(True)

        # Check scene:
        scene = str(self.fields['scenefile'].text())
        if len(scene) == 0:
            return

        name, ext = os.path.splitext(scene)
        if ext in ScenesSequences:
            scene = afcommon.patternFromFile(scene)
        elif not os.path.isfile(scene):
            self.teCmd.setText('Scene file does not exist.')
            return

        scene = os.path.normpath(scene)
        scene = os.path.abspath(scene)
        self.fields['scenefile'].setText(scene)

        # Check working directory:
        if self.fields['scenewdir'].isChecked():
            self.fields['wdir'].setText(
                os.path.dirname(str(self.fields['scenefile'].text())))

        if not os.path.isdir(self.fields['wdir'].text()):
            self.teCmd.setText('Working directory does not exist.')
            return
        self.fields['wdir'].setText(
            os.path.abspath(str(self.fields['wdir'].text())))

        # Check job name:
        if str(self.fields['jobname'].text()) == '':
            self.teCmd.setText('Job name is empty.')
            return

        # Get File Type Override
        servType = getComboBoxString(self.fields['servicetype'])

        # Construct command:
        cmd = os.environ['AF_ROOT']
        cmd = os.path.join(cmd, 'python')
        cmd = os.path.join(cmd, 'afjob.py')
        cmd = '"%s" "%s"' % (os.getenv('CGRU_PYTHONEXE', 'python'), cmd)
        cmd += ' "%s"' % self.fields['scenefile'].text()
        cmd += ' %d' % self.fields['framestart'].value()
        cmd += ' %d' % self.fields['frameend'].value()
        cmd += ' -by %d' % self.fields['frameby'].value()
        cmd += ' -fpt %d' % self.fields['framespt'].value()
        cmd += ' -seq %d' % self.fields['frameseq'].value()
        if not str(self.fields['node'].text()) == '':
            cmd += ' -node "%s"' % self.fields['node'].text()

        if not str(self.fields['take'].text()) == '':
            cmd += ' -take "%s"' % self.fields['take'].text()

        if not str(self.fields['outimages'].text()) == '':
            cmd += ' -output "%s"' % self.fields['outimages'].text()

        if not str(self.fields['preview'].text()) == '':
            cmd += ' -images "%s"' % self.fields['preview'].text()

        if not str(self.fields['extrargs'].text()) == '':
            cmd += ' -extrargs "%s"' % self.fields['extrargs'].text()

        if len(servType) and servType != 'none':
            cmd += ' -type "%s"' % servType

        if str(self.fields['os'].text()) == '':
            cmd += ' -os any'
        else:
            cmd += ' -os "%s"' % self.fields['os'].text()

        cmd += ' -pwd "%s"' % self.fields['wdir'].text()

        if self.fields['capacity'].value() > 0:
            cmd += ' -capacity %d' % self.fields['capacity'].value()

        if self.fields['maxruntasks'].value() > 0:
            cmd += ' -maxruntasks %d' % self.fields['maxruntasks'].value()

        if self.fields['maxtasksperhost'].value() > 0:
            cmd += ' -maxtasksperhost %d' % self.fields[
                'maxtasksperhost'].value()

        if self.fields['priority'].value() > -1:
            cmd += ' -priority %d' % self.fields['priority'].value()

        if not str(self.fields['dependmask'].text()) == '':
            cmd += ' -depmask "%s"' % self.fields['dependmask'].text()

        if not str(self.fields['dependglobal'].text()) == '':
            cmd += ' -depglbl "%s"' % self.fields['dependglobal'].text()

        if not str(self.fields['hostsmask'].text()) == '':
            cmd += ' -hostsmask "%s"' % self.fields['hostsmask'].text()

        if not str(self.fields['hostsexclude'].text()) == '':
            cmd += ' -hostsexcl "%s"' % self.fields['hostsexclude'].text()

        # Render Pools Additon
        if str(self.cbSelectedPool.currentText() != "Don't use pool."):
            for pool in self.pools:
                if pool["name"] == self.cbSelectedPool.currentText():
                    afanasy_hostnames = []
                    included_hostnames = []
                    excluded_hostnames = []

                    # get afanasy hostnames
                    afModuleCmd = af.Cmd()
                    af_clients = afModuleCmd.renderGetList()
                    for af_client in af_clients:
                        afanasy_hostnames.append(af_client["name"])

                    # get included hostnames
                    clients = pool["clients"]
                    for client in clients:
                        included_hostnames.append(client["hostname"])

                    # compute excluded hosts
                    for af_hostname in afanasy_hostnames:
                        if not af_hostname in included_hostnames:
                            excluded_hostnames.append(af_hostname)

                    # generate host exclude mask
                    regex_mask = ""
                    for excluded_hostname in excluded_hostnames:
                        regex_mask += excluded_hostname + "|"
                    if regex_mask.endswith("|"):
                        regex_mask = regex_mask[:-1]
                    if regex_mask != "":
                        cmd += ' -hostsexcl "%s"' % regex_mask

        if self.fields['paused'].isChecked():
            cmd += ' -pause'

        cmd += ' -name "%s"' % self.fields['jobname'].text()

        if not str(self.fields['exec'].text()) == '':
            cmd += ' -exec "%s"' % self.fields['exec'].text()

        # Evaluated:
        self.teCmd.setText(cmd)
        self.evaluated = True
        self.bStart.setEnabled(True)
        print('Evaluated')
Exemple #17
0
def exitTalk(    text = '(keeper)'): af.Cmd().talkExit( text)
def exitMonitor( text = '(keeper)'): af.Cmd().monitorExit( text)
Exemple #18
0
def ejectNotMyTasks(text='(keeper)'):
    cmd = af.Cmd().renderEjectNotMyTasks(text)
Exemple #19
0
def ejectAndNIMBY():
    cmd = af.Cmd().renderEjectAndNIMBY()
    render.refreshAfter()
Exemple #20
0
def setNIMBY():
    cmd = af.Cmd().renderSetNIMBY()
    render.refreshAfter()
Exemple #21
0
def setnimby():
    cmd = af.Cmd().renderSetNimby()
    render.refreshAfter()
Exemple #22
0
# Example of use of Afanasy's API to generate a summary of the state of the
# render farm.
# Copyright (c) 2016 rise|fx (Elie Michel) - Released under MIT License

import af

cmd = af.Cmd()


def isSysJob(job):
    return job['st'] == 0


## Jobs ##

joblist = cmd.getJobList()
job_state_counters = {}
job_count = 0

for job in joblist:
    if isSysJob(job):
        continue

    job_count += 1
    for s in job['state'].split():
        job_state_counters[s] = job_state_counters.get(s, 0) + 1

print("Out of %d jobs:" % job_count)
print(" * %d are running" % job_state_counters.get('RUN', 0))
print(" * %d have error" % job_state_counters.get('ERR', 0))
print(" * %d are skipped" % job_state_counters.get('SKP', 0))
Exemple #23
0
def setFreeUnpause():
    cmd = af.Cmd().renderSetFreeUnpause()
    render.refreshAfter()
Exemple #24
0
def exitRender():
    af.Cmd().renderExit()
Exemple #25
0
def ejectNotMyTasks():
    cmd = af.Cmd().renderEjectNotMyTasks()
    render.refreshAfter()
Exemple #26
0
def exitMonitor():
    af.Cmd().monitorExit()
Exemple #27
0
def exitRender(  text = '(keeper)'): af.Cmd().renderExit( text)
def exitTalk(    text = '(keeper)'): af.Cmd().talkExit( text)
Exemple #28
0
def setnimby(text='(keeper)'):
    cmd = af.Cmd().renderSetNimby(text)
    render.refreshAfter()
Exemple #29
0
def exitMonitor( text = '(keeper)'): af.Cmd().monitorExit( text)
def exitClients( text = '(keeper)'):
Exemple #30
0
def setFree(text='(keeper)'):
    cmd = af.Cmd().renderSetFree(text)
    render.refreshAfter()