예제 #1
0
    def iterRows(self, proc: Processor) -> Iterator[Sequence[str]]:
        tasks = proc.tasks
        taskRunDB = proc.taskRunDB

        # Determine all keys that exist for the given task names.
        keys = sorted(union(
            taskRunDB.getKeys(taskName) for taskName in proc.args.task
            ))

        yield [ 'create date', 'create time', 'result' ] + keys
        for task in tasks:
            taskName = task.getName()
            taskKeys = taskRunDB.getKeys(taskName)
            # TODO: Which properties are useful to export?
            timestamp = formatTime(task.getJob().getCreateTime())
            # Assuming format "2008-09-16 15:21"
            results = [timestamp[:10], timestamp[-5:], getTaskStatus(task)]
            for key in keys:
                if key in taskKeys:
                    # TODO: Querying one run at a time is not really efficient.
                    data = list(taskRunDB.getData(
                        taskName, [ task.getLatestRun().getId() ], key
                        ))
                    if len(data) == 0:
                        results.append('')
                    else:
                        assert len(data) == 1
                        value = data[0][1]
                        results.append(str(value))
                else:
                    results.append('')
            yield results
예제 #2
0
def createStatusBar(tasks: Sequence[Task], length: int = 10) -> XMLContent:
    if len(tasks) == 0:
        return None
    elif len(tasks) <= length:
        return xhtml.table(class_='statusfew')[xhtml.tbody[xhtml.tr[(xhtml.td(
            class_=getTaskStatus(task)) for task in tasks)]]]
    else:
        statusFreq = dict.fromkeys(statusList, 0)
        for task in tasks:
            statusFreq[getTaskStatus(task)] += 1

        def iterBars() -> Iterator[XMLContent]:
            for status in statusList:
                freq = statusFreq[status]
                if freq != 0:
                    yield xhtml.td(
                        style=f'width:{100 * freq // len(tasks):d}%',
                        class_=status)[str(freq)]

        return xhtml.table(
            class_='statusmany')[xhtml.tbody[xhtml.tr[iterBars()]]]
예제 #3
0
def getJobStatus(job: Job) -> str:
    '''Summarizes the current status of the given job by combining the task
    statuses into a single value.
    '''
    # Return cached status, if available.
    jobId = job.getId()
    status = _finalJobStatus.get(jobId)
    if status is None:
        status = combinedStatus(
            getTaskStatus(task) for task in job.iterTasks())
        assert status is not None
        if job.hasFinalResult():
            # Status will never change again, so store it.
            _finalJobStatus[jobId] = status
    return status
예제 #4
0
def getProductStatus(job: Job, name: str) -> Optional[str]:
    '''Returns the status of the product with the given name.
    Raises KeyError if there is no product with the given name in the given job.
    '''
    product = job.getProduct(name)
    if not product.isCombined():
        if product.isBlocked():
            return 'cancelled'
        elif product.isAvailable():
            # In the case of multiple producers, we don't know which
            # producer created the default locator, so there is no
            # obviously right choice for the status.
            # So we choose something simple instead.
            return 'ok'
        # Not blocked and not available, so must be idle or busy.
        # The generic case can handle that just fine.
    return combinedStatus(
        getTaskStatus(task) for task in job.getProducers(name))
예제 #5
0
    def iterRows(self, **kwargs: object) -> Iterator[XMLContent]:
        proc = cast(ProcT, kwargs['proc'])
        job = cast(JobProcessorMixin, proc).job
        jobId = job.getId()
        products = self.getProducts(proc)
        hasLocal = any(prod.isLocal() for prod in products)
        for product in products:
            productName = product.getName()
            potentialProducers = {
                task.getName()
                for task in job.getProducers(productName)
            }
            actualProducers = {
                taskName
                for taskName, locator_ in product.getProducers()
            }
            # For user inputs, actualProducers includes tasks that are not
            # in potentialProducers.
            producers = sorted(
                self.filterProducers(proc,
                                     potentialProducers | actualProducers))
            rowStyle = getProductStatus(job, productName) if self.showColors \
                                                          else None

            consumers = sorted(job.getConsumers(productName))

            first = True
            for taskName in producers:
                task = job.getTask(taskName)
                if task is None:
                    # No actual producer; this must be an input product.
                    producerStatus = 'ok'
                    finishedTask = True
                else:
                    producerStatus = getTaskStatus(task)
                    finishedTask = task.isExecutionFinished()

                cells = []
                if first:
                    cells.append(cell(rowspan=len(producers))[productName])
                if first and hasLocal:
                    cells.append(
                        cell(rowspan=len(producers))
                        [createTaskRunnerDetailsLink((
                            product.getLocalAt() or '?') if product.isLocal(
                            ) and not product.isBlocked() else None)])
                if self.showProducers:
                    cells.append(
                        cell(
                            class_=producerStatus if self.showColors else None)
                        ['(job input)' if task is None else createTaskInfoLink(
                            jobId, taskName)])
                if first and self.showConsumers:
                    cells.append(
                        cell(rowspan=len(producers))[xhtml.br.join(
                            createTaskInfoLink(jobId, consumer.getName())
                            for consumer in consumers)])
                locator = product.getLocator(taskName)
                if locator is None and not actualProducers:
                    # For old jobs, only one locator per product was stored.
                    locator = product.getLocator()
                if not self.showColors:
                    locatorStyle = None
                elif locator is None:
                    assert task is not None, \
                        f'input without locator: {taskName}'
                    if finishedTask:
                        locatorStyle = 'cancelled'
                    else:
                        locatorStyle = getTaskStatus(task)
                else:
                    locatorStyle = producerStatus
                cells.append(
                    cell(class_=locatorStyle)[formatLocator(
                        product, locator, finishedTask)])
                yield row(class_=rowStyle)[cells]
                first = False
예제 #6
0
 def iterRowStyles(  # pylint: disable=unused-argument
         self, rowNr: int, record: Task, **kwargs: object) -> Iterator[str]:
     yield getTaskStatus(record)