Beispiel #1
0
    def iterRows(self, **kwargs: Any) -> Iterator[XMLContent]:
        tokens: Iterator[Tuple[TokenType, str]] = kwargs['tokens']

        lineNo = 1
        nodes: List[XMLContent] = []
        for node in _splitLines(tokens):
            if node == '\n':
                yield (xhtml.a(id=f'L{lineNo}'),
                       xhtml.a(href=f'#L{lineNo}')[lineNo]), nodes
                lineNo += 1
                nodes = []
            else:
                nodes.append(node)
        if nodes:
            yield lineNo, nodes
Beispiel #2
0
 def iterOptions(self, **kwargs: object) -> Iterator[Sequence[XMLContent]]:
     yield EmbeddingPolicy.NONE, 'Never'
     yield EmbeddingPolicy.SELF, 'Same site only'
     yield EmbeddingPolicy.CUSTOM, 'Custom: ', (
         textInput(
             name='embedcustom',
             size=69,
             # The onchange event handler is there to make sure the right
             # radio button is activated when text is pasted into the edit
             # box from the context menu (right mouse button).
             onchange=f"form['{self.name}'][2].checked=true"),
         xhtml.br,
         'You can enter one or more site filters, '
         'such as ',
         xhtml.code['https://*.example.com'],
         xhtml.br,
         'This is used as a ',
         xhtml.code['frame-ancestors'],
         ' rule '
         'in the ',
         xhtml.code['Content-Security-Policy'],
         ' header; ',
         xhtml.a(href='https://developer.mozilla.org/en-US/docs'
                 '/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors'
                 )['full documentation at MDN'],
     )
Beispiel #3
0
 def present(self, **kwargs: object) -> XMLNode:
     node = xhtml.a(**self._attributes)[ self._presentContents(**kwargs) ]
     ccURL = cast(Optional[str], kwargs.get('ccURL'))
     if ccURL is None:
         return node
     else:
         return node(href=ccURL + node.attrs['href'])
Beispiel #4
0
 def presentContent(self, **kwargs: object) -> XMLContent:
     yield ResourcesTable.instance.present(**kwargs)
     yield xhtml.p['For help about resources read this section of the ',
                   docLink('/start/user_manual/#resources')['User Manual'],
                   '.']
     yield xhtml.p['Download the ',
                   xhtml.a(href='taskrunner.jar')['Task Runner JAR'], '.']
Beispiel #5
0
    def presentContent(self, **kwargs: object) -> XMLContent:
        proc = cast(BatchExecute_GET.Processor, kwargs['proc'])
        for notice in proc.notices:
            yield xhtml.p(class_='notice')[notice]
        configs = proc.configs
        if configs:
            yield xhtml.h3['Selected configurations:']
            yield BatchConfigTable.instance.present(**kwargs)

            taskSet = proc.taskSet
            if taskSet is None:
                yield xhtml.p['Cannot execute because of conflict.']
            else:
                yield makeForm(args=ParentArgs.subset(proc.args))[
                    BatchInputTable.instance, submitButtons, decoration[
                        xhtml.hr, ParamTable.instance,
                        # Second set of submit buttons after parameter tables.
                        submitButtons],
                    (hiddenInput(name=f'config.{i:d}', value=cfg.getId())
                     for i, cfg in enumerate(configs)), ].present(
                         taskSet=taskSet, **kwargs)
                return
        else:
            yield xhtml.h3['No configurations selected']

        yield xhtml.p[xhtml.a(
            href=proc.args.refererURL or parentPage)['Back to Configurations']]
Beispiel #6
0
    def presentContent(self, **kwargs: object) -> XMLContent:
        proc = cast(ConfigTagsBase.Processor[ArgsT], kwargs['proc'])
        for notice in proc.notices:
            yield xhtml.p(class_='notice')[notice]
        configs = proc.configs
        if configs:
            yield xhtml.h3['Selected Configurations:']
            yield TagConfigTable.instance.present(**kwargs)

            yield xhtml.h3['Common Selection Tags:']
            tagKeys = proc.project.getTagKeys()
            commonTags = getCommonTags(tagKeys,
                                       (config.tags for config in configs))
            yield makeForm(args=ParentArgs.subset(proc.args).override(
                sel={config.getId()
                     for config in configs}
            ))[ConfigTagValueEditTable.instance,
               xhtml.p[actionButtons(Actions)],
               (hiddenInput(name=f'commontags.{index:d}', value=tagName)
                for index, tagKey in enumerate(tagKeys)
                for tagName in commonTags[tagKey])].present(
                    getValues=lambda key: valuesToText(commonTags[key]),
                    **kwargs)
        else:
            yield (xhtml.h3['No configurations selected'],
                   xhtml.p[xhtml.a(href=proc.args.refererURL or parentPage)
                           ['Back to Configurations']])
Beispiel #7
0
def pageLink(
        page: str,
        args: Optional[PageArgs] = None,
        **kwargs: str
        ) -> XMLNode:
    '''Creates a hyperlink to another page.
    '''
    return xhtml.a(href=pageURL(page, args, **kwargs))
Beispiel #8
0
    def renderTableOfContents(self, arg: str) -> XMLContent:
        if arg:
            raise ValueError('"toc" does not take any arguments')

        yield xhtml.h2['Table of Contents']
        yield xhtml.dl(class_='toc')[((xhtml.dt[xhtml.a(
            href=url)[extracted.title]], extracted.abstract)
                                      for url, extracted in self.__toc)]
Beispiel #9
0
 def presentContent(self, **kwargs: object) -> XMLContent:
     proc = cast(ConfigTags_POST.Processor, kwargs['proc'])
     if proc.notices:
         yield super().presentContent(**kwargs)
     else:
         yield xhtml.p['The tags have been updated successfully.']
         yield xhtml.p[xhtml.a(href=proc.args.refererURL or parentPage)
                       ['Back to Configurations']]
Beispiel #10
0
    def backToReferer(self, args: ArgsT) -> XMLNode:
        refererName = args.refererName
        if refererName is None:
            # No referer, fall back to page hierarchy.
            return self.backToParent(args)

        return xhtml.p[xhtml.a(href=args.refererURL)[
            'Back to ',
            self.getPageInfo(refererName)['description']]]
Beispiel #11
0
def presentSubcommands(ctx: Context,
                       parent: MultiCommand) -> Iterator[XMLContent]:
    prefix = ''.join(f'{word}-' for word in rootPath(ctx.parent, parent))
    yield xhtml.dl[(xhtml.dt[xhtml.code[xhtml.a(
        href=f'#{prefix}{command.name}')[command.name]]] +
                    xhtml.dd[command.get_short_help_str(limit=1000)]
                    for command in iterCommands(ctx, parent))]
    for command in iterCommands(ctx, parent):
        yield from presentCommand(ctx, command)
Beispiel #12
0
def formatLocator(product: Product, locator: Optional[str],
                  finishedTask: bool) -> XMLContent:
    if locator is None:
        return 'unavailable' if finishedTask else 'not yet'
    elif product.getType() is ProductType.URL:
        return xhtml.a(href=locator)[locator]
    elif product.getType() is ProductType.TOKEN:
        return 'token was produced'
    else:
        return locator
Beispiel #13
0
    def presentCell(self, record: Job, **kwargs: object) -> XMLContent:
        table = cast(JobsTable, kwargs['table'])
        if table.descriptionLink:
            yield xhtml.a(href=createJobURL(
                record.getId()), )[record.getDescription()]
        else:
            yield record.getDescription()

        scheduleDB: ScheduleDB = getattr(kwargs['proc'], 'scheduleDB')
        scheduleId = record.getScheduledBy()
        if scheduleId is not None:
            schedule = scheduleDB.get(scheduleId)
            if schedule is None:
                icon = _scheduleIconGray
                url = None
            else:
                icon = _scheduleIcon
                url = createScheduleDetailsURL(scheduleId)
            yield xhtml.a(href=url, title=scheduleId,
                          class_='jobicon')[icon.present(**kwargs)]
Beispiel #14
0
 def createCell(taskName: Optional[str],
                tasks: Optional[Sequence[Task]], beginTime: int,
                endTime: int) -> XMLContent:
     if tasks is None:
         return ''
     bar = createStatusBar(tasks, length=0)
     if taskName is None:
         return bar
     url = makeURL(taskName, beginTime, endTime)
     return cell(onclick=f"document.location='{url}'")[xhtml.a(
         href=url)[bar]]
Beispiel #15
0
def maybeLink(url: Optional[str]) -> XMLSubscriptable:
    '''Creates a hyperlink if the URL is not None, otherwise returns the label
    as an XML tree.
    '''
    # Note: Use an "if" statement because mypy doesn't combine the types
    #       in the way we need when a conditional expression is used.
    #         https://github.com/python/mypy/issues/5392
    if url is None:
        return xhtml
    else:
        return xhtml.a(href = url)
Beispiel #16
0
 def presentHeader(self, **kwargs: object) -> XMLContent:
     proc = cast(ProcT, kwargs['proc'])
     ccURL = cast(str, kwargs['ccURL'])
     userName = proc.user.name
     return xhtml.div(class_='titlebar')[
         xhtml.div(class_='title')[self.__title(proc)],
         xhtml.div(class_='info')[xhtml.a(
             href=ccURL +
             self.loginURL(**kwargs))['log in'] if userName is None else
                                  (createUserDetailsLink(userName).present(
                                      **kwargs), ' \u2013 ',
                                   xhtml.a(href=ccURL +
                                           logoutURL(proc.req))['log out']),
                                  xhtml.br,
                                  formatTime(getTime())],
         xhtml.div(
             class_='logo'
         )[xhtml.a(href=ccURL +
                   'About', title=f'SoftFab {VERSION}')[_logoIcon.present(
                       **kwargs)]]]
Beispiel #17
0
    def __presentLinkButton(self, button: LinkBarButton,
                            **kwargs: object) -> XMLNode:
        iconStyle = ['navicon']
        iconModifier = button.modifier
        if iconModifier is not IconModifier.NONE:
            iconStyle.append(self.__iconModifierStyle[button.modifier])

        return xhtml.div(class_='navthis' if button.active else None)[xhtml.a(
            href=button.url)[xhtml.span(
                class_=' '.join(iconStyle))[button.icon.present(**kwargs)],
                             xhtml.span(class_='navlabel')[button.label]]]
Beispiel #18
0
 def presentContent(self, **kwargs: object) -> XMLContent:
     proc = cast(AddUser_POST.Processor, kwargs['proc'])
     yield xhtml.p[ xhtml.b[
         f'User "{proc.args.user}" has been added successfully.'
         ] ]
     yield presentSetPasswordURL(proc.args.user, proc.token)
     yield xhtml.hr
     yield xhtml.p[
         'You can use the form below to add another user, or ',
         xhtml.a(href = self.getCancelURL(proc.args))[
             'go back to the users overview page'
             ], '.'
         ]
     yield self.presentForm(RoleArgs(role=UIRoleNames.USER), **kwargs)
Beispiel #19
0
def presentCommand(ctx: Context, command: Command) -> Iterator[XMLContent]:
    options = []
    arguments = []
    for param in command.params:
        if isinstance(param, Option):
            options.append(param)
        elif isinstance(param, Argument):
            arguments.append(param)

    words = rootPath(ctx, command)
    title: List[XMLContent] = ['softfab']
    title += words
    title += [presentParameter(arg) for arg in arguments]
    yield xhtml.h3[xhtml.code[xhtml[' '].join(title)],
                   xhtml.a(id='-'.join(words))]
    yield from presentHelpBlocks(command)
    yield presentOptions(ctx, options)
    if isinstance(command, MultiCommand):
        yield from presentSubcommands(Context(command, ctx), command)
Beispiel #20
0
 def presentContent(self, **kwargs: object) -> XMLContent:
     descriptions: Sequence[Tuple[str, str, XMLContent]] = (
         ('Project', 'ProjectEdit',
          'Change overall settings, such as the project name '
          'and the list of targets.'),
         ('Design', 'Design',
          'Model the build and test process of your project: '
          'define products, frameworks, tasks and resources.'),
         ('Users', 'UserList', 'Add new users, change user passwords or '
          'change user roles.'),
         ('Notifications', 'Notifications',
          'Configure ways to stay informed of the current status '
          'of your project.'),
         ('About', 'About',
          'Look up version information of your SoftFab installation '
          'and web browser.'),
     )
     return xhtml.dl(class_='toc')[((xhtml.dt[xhtml.a(href=url)[name]],
                                     xhtml.dd[descr])
                                    for name, url, descr in descriptions)]
Beispiel #21
0
 def presentContent(self, **kwargs: object) -> XMLContent:
     yield xhtml.p['Password set successfully.']
     yield xhtml.p['You can now ',
                   xhtml.a(href=self.loginURL(**kwargs))['log in'],
                   ' with your new password.']
Beispiel #22
0
    def iterRows(self, **kwargs: object) -> Iterator[XMLContent]:
        proc = cast(TaskMatrix_GET.Processor, kwargs['proc'])
        configId = proc.args.config
        beginWeek = proc.beginWeek
        endWeek = proc.endWeek
        taskData = proc.taskData
        tasksByName = proc.tasksByName
        tasksByDay = proc.tasksByDay
        allTasks = proc.allTasks

        # Show names for task runs that were created in the selected week.
        taskNames = set(tasksByName)
        # Add names of tasks in the filtered configuration, to make it explicit
        # when they didn't run.
        if configId:
            try:
                config = proc.configDB[configId]
            except KeyError:
                pass
            else:
                taskNames.update(config.iterTaskNames())

        def makeURL(taskName: str, beginTime: int, endTime: int) -> str:
            if taskName is None:
                # TODO: The links which match all tasks are currently disabled,
                #       but are also no longer accepted by ReportTasks.
                taskName = '*'
            return pageURL(
                'ReportTasks',
                ReportTaskArgs(task=[taskName],
                               ctabove=beginTime,
                               ctbelow=endTime))

        def createCell(taskName: Optional[str],
                       tasks: Optional[Sequence[Task]], beginTime: int,
                       endTime: int) -> XMLContent:
            if tasks is None:
                return ''
            bar = createStatusBar(tasks, length=0)
            if taskName is None:
                return bar
            url = makeURL(taskName, beginTime, endTime)
            return cell(onclick=f"document.location='{url}'")[xhtml.a(
                href=url)[bar]]

        def iterCells(
                taskName: Optional[str], rowHeader: XMLContent,
                weekTasks: Iterable[Optional[Sequence[Task]]],
                totalTasks: Optional[Sequence[Task]]) -> Iterator[XMLContent]:
            # pylint: disable=stop-iteration-return
            # https://github.com/PyCQA/pylint/issues/2158

            yield rowHeader

            dayStartGen = iterDays(beginWeek)
            todayStart = next(dayStartGen)
            for tasks in weekTasks:
                tomorrowStart = next(dayStartGen)
                yield createCell(taskName, tasks, todayStart, tomorrowStart)
                todayStart = tomorrowStart

            yield cell(class_='rightalign')[str(len(totalTasks)
                                                ) if totalTasks else '']
            yield createCell(taskName, totalTasks, beginWeek, endWeek)

        if len(taskNames) == 0:
            yield iterCells(None, xhtml.i['No Tasks'], tasksByDay, allTasks)
        else:
            for taskName in sorted(taskNames):
                yield iterCells(
                    taskName,
                    xhtml.a(
                        href=makeURL(taskName, beginWeek, endWeek))[taskName],
                    (taskDict.get(taskName) for taskDict in taskData),
                    tasksByName.get(taskName))

        def presentTotals() -> Iterator[XMLContent]:
            yield xhtml.b['Total']
            for tasks in tasksByDay:
                yield cell(
                    class_='rightalign')[str(len(tasks)) if tasks else '']
            yield ''
            yield ''

        yield presentTotals()
        yield iterCells(None, xhtml.b['All Tasks'], tasksByDay, allTasks)
Beispiel #23
0
 def linkTab(tab: int, text: str) -> XMLNode:
     return xhtml.td(class_='navother')[xhtml.a(href=pageURL(
         proc.page.name,
         proc.args.override(**{tabOffsetField: tab * recordsPerPage})),
                                                class_='nav')[text]]
Beispiel #24
0
 def presentLink(
         self,  # pylint: disable=unused-argument
         record: DBRecord,
         **kwargs: object) -> XMLSubscriptable:
     return xhtml.a(href=self.__urlBase + escapeURL(record.getId()))
Beispiel #25
0
 def presentContent(self, **kwargs: object) -> XMLContent:
     return (
         xhtml.p[ 'The page you requested was not found on this server.' ],
         xhtml.p[ xhtml.a(href = 'Home')[ 'Back to Home' ] ]
         )
Beispiel #26
0
 def __presentFooter(self, proc: PageProcessor, name: str) -> XMLContent:
     return xhtml.div(class_='export')['export: ', xhtml[', '].join(
         xhtml.a(
             href=proc.subItemRelURL(f'{name}.{fmt.ext}'),
             title=fmt.description,
         )[fmt.ext] for fmt in GraphFormat)]
Beispiel #27
0
 def backToSelf(self) -> XMLNode:
     url = self.name
     return xhtml.p[xhtml.a(href=url)['Back to ', self.description]]
Beispiel #28
0
 def backToParent(self, args: Optional[ArgsT]) -> XMLNode:
     parentName = self.getPageInfo()['parents'][-1]
     parentURL = self.getPageURL(parentName, args)
     return xhtml.p[xhtml.a(
         href=parentURL)['Back to ',
                         self.getPageInfo(parentName)['description']]]
Beispiel #29
0
def docLink(path: str) -> XMLNode:
    '''Creates a hyperlink to a documentation page.
    '''
    assert path.startswith('/'), path
    return xhtml.a(href='docs' + path, target='_blank')