def presentContent(self, **kwargs: object) -> XMLContent: proc = cast(ReportTasks_GET.Processor, kwargs['proc']) taskFilter = proc.args.task if len(proc.taskDefDB) == 0: yield xhtml.p['No tasks have been defined yet.'] yield xhtml.p['Go to the ', pageLink('Design')['Design page'], ' to input your execution graph.'] return yield FilterForm.instance.present(numListItems=10, **kwargs) if len(taskFilter) == 0: return keySets = [proc.taskRunDB.getKeys(taskName) for taskName in taskFilter] commonKeys = intersection(keySets) combinedKeys = union(keySets) if combinedKeys: # For at least one selected task mid-level data is available. if commonKeys: numCommonKeys = len(commonKeys) yield xhtml.p[ pageLink('ExtractedData', ReportTaskArgs.subset(proc.args) )['Visualize mid-level data'], f" ({numCommonKeys:d} {pluralize('key', numCommonKeys)})"] else: yield xhtml.p['The selected tasks have mid-level data, ' 'but they have no keys in common.'] yield FilteredTaskRunsTable.instance.present(**kwargs)
def __presentLinks( self, taskRunner: Optional[TaskRunner]) -> Iterable[XMLContent]: if taskRunner is not None: args = ResourceIdArgs(id=taskRunner.getId()) yield pageLink('TaskRunnerEdit', args)['Edit properties of this Task Runner'] yield pageLink('ResourceDelete', args)['Delete this Task Runner']
def presentContent(self, **kwargs: object) -> XMLContent: proc = cast(ProductDetails_GET.Processor, kwargs['proc']) productDefId = proc.args.id producers = proc.producers consumers = proc.consumers numProducers = len(producers) numConsumers = len(consumers) deleteProduct = ( 'Delete this product: ' 'not possible, because it is currently being used by ', str(numProducers), ' ', pluralize('producer', numProducers), ' and ', str(numConsumers), ' ', pluralize('consumer', numConsumers), '.' ) if producers or consumers else pageLink( 'ProductDelete', DeleteArgs(id = productDefId) )[ 'Delete this Product' ] yield xhtml.h3[ 'Details of product ', xhtml.b[ productDefId ], ':' ] yield xhtml.div(class_='hgroup wrap')[ DetailsTable.instance, GraphPanel.instance ].present(graph=proc.graph, **kwargs) yield xhtml.p[ pageLink('ProductEdit', proc.args)[ 'Edit this product' ], xhtml.br, deleteProduct ]
def presentContent(self, **kwargs: object) -> XMLContent: proc = cast(UserDetails_GET.Processor, kwargs['proc']) infoUserName = proc.args.user requestUser = proc.user requestUserName = requestUser.name yield xhtml.h3[ 'Details of user ', xhtml.b[ infoUserName ], ':' ] yield DetailsTable.instance.present(**kwargs) if infoUserName == requestUserName: if requestUser.hasPrivilege('u/mo'): yield xhtml.p[ pageLink('ChangePassword')[ 'Change your password' ] ] yield xhtml.h3[ 'Recent jobs:' ] yield OwnedJobsTable.instance.present(**kwargs) reportOwnerArgs = ReportArgs(owner={infoUserName}) yield xhtml.p[ pageLink('ReportIndex', reportOwnerArgs)[ f'Show all jobs owned by {infoUserName}' ] ] yield xhtml.p[ pageLink('ReportTasks', reportOwnerArgs)[ f'Show tasks owned by {infoUserName}' ] ]
def iterLinks(self, proc: Processor) -> Iterable[XMLContent]: yield pageLink('FastExecute', proc.args)[ 'Execute this configuration' ], ' (confirmation only)' configId = proc.args.configId yield pageLink('Execute', config=configId)[ 'Load this configuration' ], ' (provide inputs and parameters)' yield pageLink('ReportIndex', desc=configId)[ 'Show history of this configuration' ] yield pageLink('Execute', config=configId, step='edit')[ 'Edit this configuration' ] if proc.scheduleIds: numSchedules = len(proc.scheduleIds) yield ( 'Delete this configuration: not possible, because it is' ' currently being used by ', str(numSchedules), ' ', pluralize('schedule', numSchedules), '.' ) else: yield pageLink('DelJobConfig', DeleteArgs(id=configId))[ 'Delete this configuration' ]
def presentCSVLink(page: str, args: CSVArgs) -> XML: return xhtml.p[ 'Export data in CSV format: ', pageLink(page, args.override(sep=CSVSeparator.COMMA))['comma'], ' or ', pageLink(page, args.override(sep=CSVSeparator.SEMICOLON))['semicolon'], ' separated', xhtml.br, 'Note: Excel only accepts the list separator from the OS regional ' 'settings.']
def iterOptions(self) -> Iterator[Tuple[XMLContent, XMLContent]]: for resType in reservedTypes: name = resType.name yield ( pageLink(resType.editPage)[ presentResTypeName(name) ], f'{reservedResourceTypeDescriptions[name]}.' ) yield ( pageLink('ResourceEdit')['Custom'], 'A user-defined resource type.' )
def iterRows(self, **kwargs: object) -> Iterator[XMLContent]: proc = cast(ScheduleDetails_GET.Processor, kwargs['proc']) tagKey = proc.scheduled['tagKey'] tagValue = proc.scheduled['tagValue'] numMatches = len(proc.scheduled.getMatchingConfigIds(proc.configDB)) yield 'key:\u00A0', tagKey yield 'value:\u00A0', tagValue tagArgs = TagArgs(tagkey = tagKey, tagvalue = tagValue) yield cell(colspan = 2)[ pageLink('LoadExecute', tagArgs)[ 'view' ], ' or ', pageLink('FastExecute', tagArgs)[ 'execute' ], f' {numMatches:d} matching configurations', ],
def presentContent(self, **kwargs: object) -> XMLContent: proc = cast(ShowReport_GET.Processor, kwargs['proc']) jobId = proc.args.jobId job = proc.job tasks = job.getTaskSequence() yield SelfJobsTable.instance.present(**kwargs) yield TaskRunsTable.instance.present(**kwargs) if any(task.canBeAborted() for task in tasks): if any(task.isWaiting() for task in tasks): yield xhtml.p[ pageLink( 'AbortTask', TaskIdArgs(jobId = jobId, taskName = '/all-waiting') )[ 'Abort all waiting tasks' ] ] yield xhtml.p[ pageLink( 'AbortTask', TaskIdArgs(jobId = jobId, taskName = '/all') )[ 'Abort all unfinished tasks' ] ] yield CommentPanel(job.comment).present(**kwargs) yield InputTable.instance.present(**kwargs) yield OutputTable.instance.present(**kwargs) yield ParamTable.instance.present(**kwargs) if not job.hasFinalResult(): # Note: We check hasFinalResult instead of isExecutionFinished # because for postponed inspection it can be useful to know # which Factory PC ran the task. yield TaskRunnerTable.instance.present(**kwargs) notify = job.getParams().get('notify') if notify: notifyMode = job.getParams().get('notify-mode', 'always') protocol, path = notify.split(':', 1) if protocol == 'mailto': if notifyMode == 'onfail': notifyStr = ' (only on warning or error)' elif notifyMode == 'onerror': notifyStr = ' (only on error)' else: notifyStr = '' yield xhtml.p[ 'Notify when job done: ', xhtml.b[ path ], notifyStr ]
def presentContent(self, **kwargs: object) -> XMLContent: proc = cast(ScheduleDetails_GET.Processor, kwargs['proc']) scheduleId = proc.args.id yield xhtml.h3[ 'Details of schedule ', xhtml.b[ scheduleId ], ':' ] yield DetailsTable.instance.present(**kwargs) yield xhtml.p[ xhtml.br.join(( pageLink('ScheduleEdit', proc.args)[ 'Edit this Schedule' ], pageLink('DelSchedule', DeleteArgs(id = scheduleId))[ 'Delete this Schedule' ] )) ]
def presentContent(self, **kwargs: object) -> XMLContent: proc = cast(ScheduleIndex_GET.Processor, kwargs['proc']) yield makeForm(args=proc.args)[ScheduleTable.instance].present( **kwargs) if proc.finishedSchedules: yield xhtml.p[pageLink('DelFinishedSchedules') ['Delete all finished schedules']]
def presentHeaderContent(self, **kwargs: object) -> XMLContent: table = cast(DataTable, kwargs.pop('table')) proc = cast(PageProcessor, kwargs['proc']) content = super().presentHeaderContent(**kwargs) # Is this a column with data attached? keyName = self.keyName if keyName is None: return content sortField = table.sortField if sortField is None or not proc.args.isArgument(sortField): return content # Determine index in current sort order and compute new sort order. sortOrder: List[str] = list(getattr(proc.args, sortField)) index = sortOrder.index(keyName) del sortOrder[index] sortOrder.insert(0, keyName) override: Dict[str, object] = {sortField: sortOrder} tabOffsetField = table.tabOffsetField if tabOffsetField is not None: override[tabOffsetField] = 0 return pageLink(proc.page.name, proc.args.override(**override))( class_='sortorder')[content, ' ', xhtml.span( class_='sortorder')[f'{index + 1:d}']]
def presentContent(self, **kwargs: object) -> XMLContent: proc = cast(Task_GET.Processor, kwargs['proc']) reports = proc.reports active = proc.active presenter = proc.presenter yield xhtml.div(class_='reporttabs')[(xhtml.div( class_='active' if active == label else None)[ pageLink(self.name, proc.args.override( report=label.casefold()))[presentLabel(label)], None if url is None else xhtml. a(href=url, target='_blank', title='Open report in new tab' )[openInNewTabIcon.present( **kwargs)]] for label, url in reports.items())] if presenter is not None: yield presenter.presentBody() elif active == 'Overview': yield self.presentOverview(**kwargs) elif active == 'Data': yield self.presentData(**kwargs) else: yield xhtml.iframe(class_='report', src=reports[active], sandbox=SANDBOX_RULES)
def presentContent(self, **kwargs: object) -> XMLContent: proc = cast(TaskRunnerDetails_GET.Processor, kwargs['proc']) yield xhtml.h3['Details / ', pageLink('TaskRunnerHistory', TaskRunnerIdArgs.subset(proc.args))['History'], ' of Task Runner ', xhtml.b[proc.args.runnerId], ':'] yield DetailsTable.instance.present(**kwargs) yield xhtml.p[xhtml.br.join(self.__presentLinks(proc.taskRunner))]
def presentContent(self, **kwargs: object) -> XMLContent: proc = cast(TaskDetails_GET.Processor, kwargs['proc']) taskDefId = proc.args.id configs = proc.configs yield xhtml.h3['Details of task definition ', xhtml.b[taskDefId], ':'] yield DetailsTable.instance.present(**kwargs) yield xhtml.p[createTaskHistoryLink(taskDefId)] numConfigs = len(configs) yield xhtml.p[ pageLink('TaskEdit', proc.args)['Edit this task definition'], xhtml.br, ('Delete this task definition: not possible, because it is ' 'currently being used by ', str(numConfigs), ' ', pluralize('configuration', numConfigs), '.' ) if configs else pageLink('TaskDelete', DeleteArgs( id=taskDefId))['Delete this task definition']]
def presentCell(self, record: UserAccount, **kwargs: object) -> XMLContent: proc = cast(UserList_GET.Processor, kwargs['proc']) requestUser = proc.user userName = record.getId() if requestUser.name == userName: if requestUser.hasPrivilege('u/mo'): # User has permission to change own password. return pageLink('ChangePassword')['Change'] else: return None else: if requestUser.hasPrivilege('u/m'): # User has permission to reset other users' passwords. return pageLink('ResetPassword', UserIdArgs(user=userName))['Reset'] else: return None
def createTagCell(value: str) -> XML: label = preserveSpaces(value) if value else '(undefined)' if value == tagValue: return xhtml.td(class_='navthis')[label] else: return xhtml.td(class_='navother')[pageLink( formAction, cleanedArgs.override(tagvalue=value, first=0))[label]]
def createTaskRunnerDetailsLink(taskRunnerId: Optional[str]) -> XMLContent: if not taskRunnerId: return '-' elif taskRunnerId == '?': return '?' else: return pageLink( 'TaskRunnerDetails', TaskRunnerIdArgs(runnerId = taskRunnerId) )[ taskRunnerId ]
def presentCell(self, record: Task, **kwargs: object) -> XMLContent: if record.canBeAborted(): proc = cast(PageProcessor, kwargs['proc']) return pageLink( 'AbortTask', TaskIdArgs(jobId=proc.args.jobId, taskName=record.getName()))['Abort'] else: return '-'
def createKeyCell(key: str) -> XML: label = preserveSpaces(key) if key else '(show all)' if key == tagKey: return xhtml.td(class_='navthis')[label] else: return xhtml.td(class_='navother')[pageLink( formAction, cleanedArgs.override(tagkey=key, tagvalue=None, first=0))[label]]
def iterRows(self, **kwargs: object) -> Iterator[XMLContent]: args = cast(CapFilterArgs, getattr(kwargs['proc'], 'args')) active = args.restype for value, name, desc in self.iterOptions(**kwargs): yield row(class_='match' if active == value else None)[ pageLink('Capabilities', args.override(restype=value))[ name ], desc ]
def createConfigDetailsLink(configDB: ConfigDB, configId: str, label: Optional[str] = None ) -> XMLContent: if label is None: label = configId if configId in configDB: return pageLink('ConfigDetails', ConfigIdArgs(configId = configId))[ label ] else: return label
def presentContent(self, **kwargs: object) -> XMLContent: proc = cast(TaskRunnerHistory_GET.Processor, kwargs['proc']) runnerId = proc.args.runnerId yield xhtml.h3[pageLink('TaskRunnerDetails', TaskRunnerIdArgs.subset(proc.args))['Details'], ' / History of Task Runner ', xhtml.b[runnerId], ':'] if proc.reachedJobsLimit: yield xhtml.p[xhtml.i[ f'Only tasks from the last {_jobsLimit:d} jobs are shown.']] yield HistoryTable.instance.present(**kwargs)
def iterRows(self, **kwargs: object) -> Iterator[XMLContent]: proc = cast('ConfigDetails_GET.Processor', kwargs['proc']) config = proc.config for key in proc.project.getTagKeys(): values = config.tags.getTagValues(key) if values: yield key, xhtml[', '].join( pageLink( 'LoadExecute', TagArgs(tagkey = key, tagvalue = value) )[ value ] for value in sorted(values) )
def presentCell(self, record: ResourceBase, **kwargs: object) -> XMLContent: typeName = record.typeName if typeName.startswith('sf.'): for resType in reservedTypes: if resType.name == typeName: pageName = resType.editPage break else: return '-' else: pageName = 'ResourceEdit' return pageLink(pageName, DeleteArgs(id=record.getId()))['Edit']
def presentContent(self, **kwargs: object) -> XMLContent: proc = cast(FrameworkDetails_GET.Processor, kwargs['proc']) frameworkId = proc.args.id children = proc.children numChildren = len(children) deleteFramework = ( 'Delete this framework: not possible, ' 'because it is currently being used by ', str(numChildren), ' ', pluralize('task definition', numChildren), '.' ) if children else pageLink( 'FrameworkDelete', DeleteArgs(id = frameworkId) )[ 'Delete this framework' ] yield xhtml.h3[ 'Details of framework ', xhtml.b[ frameworkId ], ':' ] yield xhtml.div(class_='hgroup wrap')[ DetailsTable.instance, GraphPanel.instance ].present(graph=proc.graph, **kwargs) yield xhtml.p[ pageLink('FrameworkEdit', proc.args)[ 'Edit this framework' ], xhtml.br, deleteFramework ]
def getFormContent(self, proc: EditProcessorBase[ResourceEditArgs, Resource] ) -> XMLContent: args = proc.args if args.id != '': yield xhtml.h3[ 'Resource: ', xhtml.b[ args.id ]] yield vgroup[ CustomResTypeTable.instance, xhtml.p[ 'If none of the listed resource types is appropriate, you can ', pageLink('ResTypeEdit')[ 'create a new resource type' ],'.' ], CapabilitiesPanel.instance, LocatorPanel.instance, CommentPanel.instance ]
def presentContent(self, **kwargs: object) -> XMLContent: proc = cast(ExtractedData_GET.Processor, kwargs['proc']) parentArgs = ReportTaskArgs.subset(proc.args) yield xhtml.p[self.presentTaskFilter(parentArgs)] yield xhtml.p[pageLink('ReportTasks', parentArgs)['Change task filters']] yield makeForm( formId='keys', method='get')[KeysTable.instance, VisualizationTable.instance, xhtml.p[submitButton['Apply']], ].present(**kwargs) yield presentCSVLink( 'ReportTasksCSV', ReportTaskCSVArgs(ReportTaskArgs.subset(proc.args))) if len(proc.tasks) == 0: yield xhtml.p['No tasks match the given filters.'] elif proc.args.vistype is VisualizationType.CHART_BAR: yield visualizeBarCharts(proc) elif proc.args.vistype is VisualizationType.TABLE: yield ExtractedDataTable.instance.present(**kwargs)
def iterRows(self, **kwargs: object) -> Iterator[XMLContent]: proc = cast(ScheduleDetails_GET.Processor, kwargs['proc']) scheduled = proc.scheduled configDB = proc.configDB configId = scheduled.configId if configId is None: yield 'Tag', TagsTable.instance.present(**kwargs) else: yield 'Configuration', ( createConfigDetailsLink(configDB, configId, 'view'), ' or ', pageLink('FastExecute', ConfigIdArgs(configId = configId))[ 'execute' ], f' configuration "{configId}"' ) yield 'Last run', createLastJobLink(scheduled) yield 'Next run', describeNextRun(scheduled) repeat = scheduled.repeat yield 'Repeat', repeat if repeat is ScheduleRepeat.WEEKLY: yield 'Days', ', '.join(stringToListDays(scheduled.dayFlags)) elif repeat is ScheduleRepeat.CONTINUOUSLY: minDelay = scheduled.minDelay yield 'Minimum delay', \ f"{minDelay:d} {pluralize('minute', minDelay)}" elif repeat is ScheduleRepeat.TRIGGERED: yield 'Triggered', 'yes' if scheduled['trigger'] else 'no' yield 'Triggers', xhtml.br.join( sorted(scheduled.tags.getTagValues('sf.trigger')) ) if proc.userDB.showOwners: yield 'Owner', scheduled.owner or '-' yield 'Comment', xhtml.br.join(scheduled.comment.splitlines()) yield row(class_ = getScheduleStatus(configDB, scheduled))[ 'Status', statusDescription(scheduled, configDB) ]
def presentContent(self, **kwargs: object) -> XMLContent: proc = cast(Logout_GET.Processor, kwargs['proc']) return (xhtml.p['You have been logged out.' if proc. loggedOut else 'You were not logged in.'], xhtml.p[pageLink('Login', proc.args)['Log in']])