Esempio n. 1
0
    def _renderTag(self, ctx, key, value, readonly):
        tag = T.invisible()
        ta = T.textarea(name=key, id=render_cssid(key), cols=self.cols, rows=self.rows)[value or ""]
        if readonly:
            ta(class_="readonly", readonly="readonly")
        tag[ta]

        if not readonly:
            try:
                import docutils
            except ImportError:
                raise
            else:
                form = iformal.IForm(ctx)
                srcId = render_cssid(key)
                previewDiv = render_cssid(key, "preview-div")
                frameId = render_cssid(key, "preview-frame")
                targetURL = widgetResourceURLFromContext(ctx, form.name).child(key).child(srcId)
                tag[T.br()]
                onclick = ["return Forms.Util.previewShow('", previewDiv, "', '", frameId, "', '", targetURL, "');"]
                tag[T.button(onclick=onclick)["Preview ..."]]
                tag[
                    T.div(id=previewDiv, class_="preview-hidden")[
                        T.iframe(class_="preview-frame", name=frameId, id=frameId),
                        T.br(),
                        T.button(onclick=["return Forms.Util.previewHide('", previewDiv, "');"])["Close"],
                    ]
                ]

        return tag
Esempio n. 2
0
        def _renderReSTTag(self, ctx, content, key, readonly):
            namer = self._namer(key)

            tag=T.invisible()
            ta=T.textarea(name=namer('content'), id=formal_keytocssid(namer('content')), cols=self.cols, rows=self.rows)[content or '']
            if readonly:
                ta(class_='readonly', readonly='readonly')
            tag[ta]

            if not readonly:
                try:
                    import docutils
                except ImportError:
                    raise
                else:
                    form = iformal.IForm( ctx )
                    srcId = formal_keytocssid(namer('content'))
                    previewDiv = srcId + '-preview-div'
                    frameId = srcId + '-preview-frame'
                    targetURL = formal_widgetResourceURLFromContext(ctx, form.name).child(key).child( srcId )
                    tag[T.br()]
                    tag[T.button(onClick="return Forms.Util.previewShow('%s', '%s', '%s');"%(previewDiv, frameId, targetURL))['Preview ...']]
                    if self.withImagePicker:
                        tag[T.button(onclick=["return Cms.Forms.ImagePicker.popup('",srcId,"','tag')"])['Choose image ...']]

                    tag[T.div(id=previewDiv, class_="preview-hidden")[
                            T.iframe(class_="preview-frame", name=frameId, id=frameId),
                            T.br(),
                            T.button(onClick=["return Forms.Util.previewHide('",previewDiv,"');"])['Close']
                        ]
                    ]

            return tag
Esempio n. 3
0
 def getDescription(self):
     t = []
     for o in getOptionDescription(self.option).split(','):
         t.append(o)
         t.append(T.br())
     optionDescription = T.div[t[:-1]]
     if self.option:
         return [T.strong[self.product.title],T.br(),optionDescription]
     else:
         return T.strong[self.product.title]
    def render_genericCommand(self, ctx: WovenContext, data):

        employees = []
        self.l1 = l1 = List(employees, ["Employee ID", "Name"])
        self.l2 = l2 = List([], ["Entry Type", "Work Location", "Sub Account", "Start Time", "End Time", "Shift Duration", "Daily Total", "Approved", "Denied"])
        self.ltl = ltl = ListToListSelector(l1, l2)
        ltl.mappingReturnsNewElements = True
        ltl.prepare(self)
        ltl.visible = True
        ltl.closeable = False
        ltl.getMappingFor = self.getMappingFor
        ltl.setMappingFor = self.setMappingFor
        l2.setSelectable(False)

        startTime = tags.input(id='startTime', placeholder='Start Time')#[tags.Tag('athena:handler')(event='onchange', handler='timeWindowChanged')]
        endTime = tags.input(id='endTime', placeholder='End Time')
        addTime = [
            tags.input(id='addTime', type='button', value='Add Time Entry')[
                tags.Tag('athena:handler')(event='onclick', handler='addTime')],
            tags.select(id='newTimeType')[
                [tags.option(id=et.getTypeName())[et.getTypeName()] for et in self.entryTypes]
                ]
            ]
        if not IAdministrator(self.employee, None):
            addTime = ''

        self.preprocess([startTime, endTime, addTime])
        return [startTime, endTime, tags.br(), addTime, ltl]
Esempio n. 5
0
	def data_new_root(self, ctx, data):
		"""
		Template function to display the new root form.
		"""
		request = inevow.IRequest(ctx)
		requestData = protocol.OpenIDRequest(request)
		current_root = requestData.get('openid.trust_root', None)
		if(current_root):
			return tags.div(_class="trustable")[[
				tags.small()["click 'approve new root' to verify access to this URL:"],
				tags.br(),
				tags.strong()[current_root],
				tags.input(type="submit", name="submit", value="approve new root"),
			]]
		else:
			return tags.div(_class="trustable")[[
				tags.small()["enter a new root here and click 'approve new root':"],
				tags.br(),
				tags.input(type='text', size="60", name='openid.trust_root', value=''),
				tags.input(type="submit", name="submit", value="approve new root"),
			]]
Esempio n. 6
0
File: widget.py Progetto: bne/squeal
 def renderer(ctx, options):
     # loops through checkbox options and renders
     for n,item in enumerate(options):
         optValue = converter.fromType(iformal.IKey(item).key())
         optLabel = iformal.ILabel(item).label()
         optid = render_cssid(key, n)
         checkbox = T.input(type='checkbox', name=key, value=optValue,
                 id=optid)
         if optValue in values:
             checkbox = checkbox(checked='checked')
         if disabled:
             checkbox = checkbox(class_='disabled', disabled='disabled')
         yield checkbox, T.label(for_=optid)[optLabel], T.br()
Esempio n. 7
0
 def renderer(ctx, options):
     # loops through checkbox options and renders
     for n,item in enumerate(options):
         optValue = iformal.IKey(item).key()
         optLabel = iformal.ILabel(item).label()
         optValue = converter.fromType(optValue)
         optid = render_cssid(key, n)
         checkbox = T.input(type='checkbox', name=key, value=optValue,
                 id=optid)
         if optValue in values:
             checkbox = checkbox(checked='checked')
         if disabled:
             checkbox = checkbox(class_='disabled', disabled='disabled')
         yield checkbox, T.label(for_=optid)[optLabel], T.br()
 def render_genericCommand(self, ctx: WovenContext, data):
     self.l = l = List([], ['', "Employee ID", "Name"])
     l.closeable = False
     l.addRow(SaveList(3, start=1))
     l.prepare(self)
     l.visible = True
     showActive = tags.input(id='showActive', type='checkbox', checked=True)[
         tags.Tag('athena:handler')(handler='refresh', event='onchange')
     ]
     showInactive = tags.input(id='showInactive', type='checkbox')[
         tags.Tag('athena:handler')(handler='refresh', event='onchange')
     ]
     self.preprocess([showActive, showInactive])
     return "Show Active", showActive, tags.br(), "Show Inactive", showInactive, l
    def render_content(self, ctx, data):
        ctx.fillSlots('header_bar', self.anon_header)
        ctx.fillSlots('top_bar', T.div(id=""))
        if isinstance(self.failure.value, errors.PermissionDenied):
            error_text = T.div(
            )[T.br(), T.h3[T.img(src="/image/error.png"),
                           T.span[" hey! this stuff is private"]],
              T.br(),
              T.div()
              ["Sorry.  The contents of this page aren't for public consumption."],
              T.br(),
              T.div()
              ["If you think you should have access to this area you can email us at ",
               T.a(href="mailto:[email protected]")[" [email protected] "],
               " or search our ",
               T.a(href="http://forums.zoto.com")[" forums"], "."]]
        else:
            ## APIError
            ## AsyncStack
            self.request.setResponseCode(http.INTERNAL_SERVER_ERROR)
            if aztk_config.setup.get('site', 'environment') in ('sandbox',
                                                                'development'):
                error_text = T.div()[T.span[self.failure.getErrorMessage()],
                                     T.br(),
                                     T.span[self.failure.getBriefTraceback()]]
            else:
                #error_text = T.div["Internal error"]
                error_text = T.div()[
                 T.br(),
                 T.h3[
                  T.img(src="/image/error.png"),
                  T.span[" something has gone horribly wrong"]
                 ],
                 T.br(),
                 T.div()[
                  "It looks like we are experiencing some technical difficulty displaying items on this page. " \
                  "Please try to refresh the page. "\
                  "If the problem persists contact us and let us know. "
                 ],
                 T.br(),
                 T.div()[
                  "Thanks for your patience. If you have any questions you can email us at ",
                  T.a(href="mailto:[email protected]")[ " [email protected] "],
                  " or search our ",
                  T.a(href="http://forums.zoto.com")[ " forums"],
                  "."
                 ]
                ]

        ctx.fillSlots('main_content',
                      loaders.stan(T.div(id="error_box")[error_text]))
        return ctx.tag
Esempio n. 10
0
    def _renderTag(self, ctx, key, value, readonly):
        tag = T.invisible()
        ta = T.textarea(name=key,
                        id=render_cssid(key),
                        cols=self.cols,
                        rows=self.rows)[value or '']
        if readonly:
            ta(class_='readonly', readonly='readonly')
        tag[ta]

        if not readonly:
            try:
                import docutils
            except ImportError:
                raise
            else:
                form = iformal.IForm(ctx)
                srcId = render_cssid(key)
                previewDiv = render_cssid(key, 'preview-div')
                frameId = render_cssid(key, 'preview-frame')
                targetURL = widgetResourceURLFromContext(
                    ctx, form.name).child(key).child(srcId)
                tag[T.br()]
                onclick = [
                    "return Forms.Util.previewShow('", previewDiv, "', '",
                    frameId, "', '", targetURL, "');"
                ]
                tag[T.button(onclick=onclick)['Preview ...']]
                tag[T.div(id=previewDiv, class_="preview-hidden")[
                    T.iframe(class_="preview-frame", name=frameId, id=frameId),
                    T.br(),
                    T.button(onclick=[
                        "return Forms.Util.previewHide('", previewDiv, "');"
                    ])['Close']]]

        return tag
Esempio n. 11
0
 def render_genericCommand(self, ctx: WovenContext, data):
     ret = [
         tags.select(id='subAccount', style='display:block')[
             [self.getSubs(),
              tags.Tag('athena:handler')(handler='selectSubAccount', event='onchange')]
         ],
         tags.select(id='workLocation', style='display:block')[
             [self.getLocs(),
              tags.Tag('athena:handler')(handler='selectWorkLocation', event='onchange')]
         ],
         tags.br(),
         tags.input(id='password', type='password', placeholder='password'),
         tags.input(id='clockInOut', type='button', value='ClockInOut')[tags.Tag('athena:handler')(event='onclick', handler='clockInOut')]
     ]
     return self.preprocess(ret)
Esempio n. 12
0
    def renderImmutable(self, ctx, key, args, errors):
        if errors:
            value = args.get(key, [''])[0]
        else:
            value = args.get(key)
            if value is None:
                value = ''

        previewValue = ''
        if value:
            previewValue='/content%s?size=200x200'%value

        return T.div()[
            T.img(src=previewValue, class_="preview"), T.br(),
            T.input(type='text', class_="readonly", readonly="readonly", name=key, id=keytocssid(ctx.key), value=value),
            ]
Esempio n. 13
0
    def render(self, ctx, key, args, errors):
        if errors:
            value = args.get(key, [''])[0]
        else:
            value = args.get(key)
            if value is None:
                value = ''

        img = T.invisible()
        if value:
            # TODO: work out how to find '/content' out
            img = T.img(src='/content%s?size=200x200'%value , class_="preview")

        return T.div()[
            img, T.br(),
            T.input(type='text', name=key, id=keytocssid(ctx.key), value=value),
            T.button(onclick=["return Cms.Forms.ImagePicker.popup('",render_cssid(ctx.key),"','url')"])['Choose image ...']
            ]
Esempio n. 14
0
    def renderImmutable(self, ctx, key, args, errors):
        if errors:
            images = args.get(key, [''])[0]
            images = self._parseValue(images)
        else:
            images = iforms.ISequenceConvertible(self.original).fromType(args.get(key))
            if images is None:
                images = []

        imgs = T.invisible()

        for image in images:
            imgs[ T.img(src='/artwork/system/assets/%s/mainImage?size=100x100'%image , class_="preview") ]

        return T.div()[
            imgs, T.br(),
            T.textarea(class_="readonly", readonly="readonly", name=key, id=keytocssid(ctx.key))['\n'.join(images)],
            ]
    def render_genericCommand(self, ctx: WovenContext, data):

        locations = []
        self.l1 = l1 = List(locations, ["Work Location"])
        self.l2 = l2 = List([], ["Entry Type", "Employee", "Sub Account", "Start Time", "End Time", "Shift Duration", "Daily Total", "Approved", "Denied"])
        self.ltl = ltl = ListToListSelector(l1, l2)
        ltl.mappingReturnsNewElements = True
        ltl.prepare(self)
        ltl.visible = True
        ltl.closeable = False
        ltl.getMappingFor = self.getMappingFor
        ltl.setMappingFor = self.setMappingFor
        l2.setSelectable(False)

        startTime = tags.input(id='startTime', placeholder='Start Time')#[tags.Tag('athena:handler')(event='onchange', handler='timeWindowChanged')]
        endTime = tags.input(id='endTime', placeholder='End Time')

        self.preprocess([startTime, endTime])
        return [startTime, endTime, tags.br(), ltl]
Esempio n. 16
0
    def decorator(self, request, tag):
        if self.ob.decorators:
            decorators = [ast_pp.pp(dec) for dec in self.ob.decorators]
        else:
            decorators = []

        if self.ob.kind == "Class Method" \
               and 'classmethod' not in decorators:
            decorators.append('classmethod')
        elif self.ob.kind == "Static Method" \
                 and 'staticmethod' not in decorators:
            decorators.append('staticmethod')

        if decorators:
            decorator = [('@' + dec, tags.br()) for dec in decorators]
        else:
            decorator = ()

        return decorator
Esempio n. 17
0
    def decorator(self, request, tag):
        if self.ob.decorators:
            decorators = [ast_pp.pp(dec) for dec in self.ob.decorators]
        else:
            decorators = []

        if self.ob.kind == "Class Method" \
               and 'classmethod' not in decorators:
            decorators.append('classmethod')
        elif self.ob.kind == "Static Method" \
                 and 'staticmethod' not in decorators:
            decorators.append('staticmethod')

        if decorators:
            decorator = [('@' + dec, tags.br()) for dec in decorators]
        else:
            decorator = ()

        return decorator
Esempio n. 18
0
    def render_row(self, ctx, data):
        name, (target, metadata) = data
        name = name.encode("utf-8")
        assert not isinstance(name, unicode)
        nameurl = urllib.quote(name, safe="") # encode any slashes too

        root = get_root(ctx)
        here = "%s/uri/%s/" % (root, urllib.quote(self.node.get_uri()))
        if self.node.is_unknown() or self.node.is_readonly():
            unlink = "-"
            rename = "-"
        else:
            # this creates a button which will cause our _POST_unlink method
            # to be invoked, which unlinks the file and then redirects the
            # browser back to this directory
            unlink = T.form(action=here, method="post")[
                T.input(type='hidden', name='t', value='unlink'),
                T.input(type='hidden', name='name', value=name),
                T.input(type='hidden', name='when_done', value="."),
                T.input(type='submit', value='unlink', name="unlink"),
                ]

            rename = T.form(action=here, method="get")[
                T.input(type='hidden', name='t', value='rename-form'),
                T.input(type='hidden', name='name', value=name),
                T.input(type='hidden', name='when_done', value="."),
                T.input(type='submit', value='rename/relink', name="rename"),
                ]

        ctx.fillSlots("unlink", unlink)
        ctx.fillSlots("rename", rename)

        times = []
        linkcrtime = metadata.get('tahoe', {}).get("linkcrtime")
        if linkcrtime is not None:
            times.append("lcr: " + time_format.iso_local(linkcrtime))
        else:
            # For backwards-compatibility with links last modified by Tahoe < 1.4.0:
            if "ctime" in metadata:
                ctime = time_format.iso_local(metadata["ctime"])
                times.append("c: " + ctime)
        linkmotime = metadata.get('tahoe', {}).get("linkmotime")
        if linkmotime is not None:
            if times:
                times.append(T.br())
            times.append("lmo: " + time_format.iso_local(linkmotime))
        else:
            # For backwards-compatibility with links last modified by Tahoe < 1.4.0:
            if "mtime" in metadata:
                mtime = time_format.iso_local(metadata["mtime"])
                if times:
                    times.append(T.br())
                times.append("m: " + mtime)
        ctx.fillSlots("times", times)

        assert IFilesystemNode.providedBy(target), target
        target_uri = target.get_uri() or ""
        quoted_uri = urllib.quote(target_uri, safe="") # escape slashes too

        if IMutableFileNode.providedBy(target):
            # to prevent javascript in displayed .html files from stealing a
            # secret directory URI from the URL, send the browser to a URI-based
            # page that doesn't know about the directory at all
            dlurl = "%s/file/%s/@@named=/%s" % (root, quoted_uri, nameurl)

            ctx.fillSlots("filename", T.a(href=dlurl)[name])
            ctx.fillSlots("type", "SSK")

            ctx.fillSlots("size", "?")

            info_link = "%s/uri/%s?t=info" % (root, quoted_uri)

        elif IImmutableFileNode.providedBy(target):
            dlurl = "%s/file/%s/@@named=/%s" % (root, quoted_uri, nameurl)

            ctx.fillSlots("filename", T.a(href=dlurl)[name])
            ctx.fillSlots("type", "FILE")

            ctx.fillSlots("size", target.get_size())

            info_link = "%s/uri/%s?t=info" % (root, quoted_uri)

        elif IDirectoryNode.providedBy(target):
            # directory
            uri_link = "%s/uri/%s/" % (root, urllib.quote(target_uri))
            ctx.fillSlots("filename", T.a(href=uri_link)[name])
            if not target.is_mutable():
                dirtype = "DIR-IMM"
            elif target.is_readonly():
                dirtype = "DIR-RO"
            else:
                dirtype = "DIR"
            ctx.fillSlots("type", dirtype)
            ctx.fillSlots("size", "-")
            info_link = "%s/uri/%s/?t=info" % (root, quoted_uri)

        elif isinstance(target, ProhibitedNode):
            ctx.fillSlots("filename", T.strike[name])
            if IDirectoryNode.providedBy(target.wrapped_node):
                blacklisted_type = "DIR-BLACKLISTED"
            else:
                blacklisted_type = "BLACKLISTED"
            ctx.fillSlots("type", blacklisted_type)
            ctx.fillSlots("size", "-")
            info_link = None
            ctx.fillSlots("info", ["Access Prohibited:", T.br, target.reason])

        else:
            # unknown
            ctx.fillSlots("filename", name)
            if target.get_write_uri() is not None:
                unknowntype = "?"
            elif not self.node.is_mutable() or target.is_alleged_immutable():
                unknowntype = "?-IMM"
            else:
                unknowntype = "?-RO"
            ctx.fillSlots("type", unknowntype)
            ctx.fillSlots("size", "-")
            # use a directory-relative info link, so we can extract both the
            # writecap and the readcap
            info_link = "%s?t=info" % urllib.quote(name)

        if info_link:
            ctx.fillSlots("info", T.a(href=info_link)["More Info"])

        return ctx.tag
Esempio n. 19
0
    def render_row(self, ctx, data):
        name, (target, metadata) = data
        name = name.encode("utf-8")
        assert not isinstance(name, unicode)
        nameurl = urllib.quote(name, safe="") # encode any slashes too

        root = get_root(ctx)
        here = "%s/uri/%s/" % (root, urllib.quote(self.node.get_uri()))
        if self.node.is_unknown() or self.node.is_readonly():
            unlink = "-"
            rename = "-"
        else:
            # this creates a button which will cause our _POST_unlink method
            # to be invoked, which unlinks the file and then redirects the
            # browser back to this directory
            unlink = T.form(action=here, method="post")[
                T.input(type='hidden', name='t', value='unlink'),
                T.input(type='hidden', name='name', value=name),
                T.input(type='hidden', name='when_done', value="."),
                T.input(type='submit', _class='btn', value='unlink', name="unlink"),
                ]

            rename = T.form(action=here, method="get")[
                T.input(type='hidden', name='t', value='rename-form'),
                T.input(type='hidden', name='name', value=name),
                T.input(type='hidden', name='when_done', value="."),
                T.input(type='submit', _class='btn', value='rename/relink', name="rename"),
                ]

        ctx.fillSlots("unlink", unlink)
        ctx.fillSlots("rename", rename)

        times = []
        linkcrtime = metadata.get('tahoe', {}).get("linkcrtime")
        if linkcrtime is not None:
            times.append("lcr: " + render_time(linkcrtime))
        else:
            # For backwards-compatibility with links last modified by Tahoe < 1.4.0:
            if "ctime" in metadata:
                ctime = render_time(metadata["ctime"])
                times.append("c: " + ctime)
        linkmotime = metadata.get('tahoe', {}).get("linkmotime")
        if linkmotime is not None:
            if times:
                times.append(T.br())
            times.append("lmo: " + render_time(linkmotime))
        else:
            # For backwards-compatibility with links last modified by Tahoe < 1.4.0:
            if "mtime" in metadata:
                mtime = render_time(metadata["mtime"])
                if times:
                    times.append(T.br())
                times.append("m: " + mtime)
        ctx.fillSlots("times", times)

        assert IFilesystemNode.providedBy(target), target
        target_uri = target.get_uri() or ""
        quoted_uri = urllib.quote(target_uri, safe="") # escape slashes too

        if IMutableFileNode.providedBy(target):
            # to prevent javascript in displayed .html files from stealing a
            # secret directory URI from the URL, send the browser to a URI-based
            # page that doesn't know about the directory at all
            dlurl = "%s/file/%s/@@named=/%s" % (root, quoted_uri, nameurl)

            ctx.fillSlots("filename", T.a(href=dlurl, rel="noreferrer")[name])
            ctx.fillSlots("type", "SSK")

            ctx.fillSlots("size", "?")

            info_link = "%s/uri/%s?t=info" % (root, quoted_uri)

        elif IImmutableFileNode.providedBy(target):
            dlurl = "%s/file/%s/@@named=/%s" % (root, quoted_uri, nameurl)

            ctx.fillSlots("filename", T.a(href=dlurl, rel="noreferrer")[name])
            ctx.fillSlots("type", "FILE")

            ctx.fillSlots("size", target.get_size())

            info_link = "%s/uri/%s?t=info" % (root, quoted_uri)

        elif IDirectoryNode.providedBy(target):
            # directory
            uri_link = "%s/uri/%s/" % (root, urllib.quote(target_uri))
            ctx.fillSlots("filename", T.a(href=uri_link)[name])
            if not target.is_mutable():
                dirtype = "DIR-IMM"
            elif target.is_readonly():
                dirtype = "DIR-RO"
            else:
                dirtype = "DIR"
            ctx.fillSlots("type", dirtype)
            ctx.fillSlots("size", "-")
            info_link = "%s/uri/%s/?t=info" % (root, quoted_uri)

        elif isinstance(target, ProhibitedNode):
            ctx.fillSlots("filename", T.strike[name])
            if IDirectoryNode.providedBy(target.wrapped_node):
                blacklisted_type = "DIR-BLACKLISTED"
            else:
                blacklisted_type = "BLACKLISTED"
            ctx.fillSlots("type", blacklisted_type)
            ctx.fillSlots("size", "-")
            info_link = None
            ctx.fillSlots("info", ["Access Prohibited:", T.br, target.reason])

        else:
            # unknown
            ctx.fillSlots("filename", name)
            if target.get_write_uri() is not None:
                unknowntype = "?"
            elif not self.node.is_mutable() or target.is_alleged_immutable():
                unknowntype = "?-IMM"
            else:
                unknowntype = "?-RO"
            ctx.fillSlots("type", unknowntype)
            ctx.fillSlots("size", "-")
            # use a directory-relative info link, so we can extract both the
            # writecap and the readcap
            info_link = "%s?t=info" % urllib.quote(name)

        if info_link:
            ctx.fillSlots("info", T.a(href=info_link)["More Info"])

        return ctx.tag
Esempio n. 20
0
 def test_emptySingletonTag(self):
     """
     L{Tag} instances which are allowed to be self-closing are flattened
     that way.
     """
     self.assertStringEqual(self.flatten(br()), "<br />")
Esempio n. 21
0
    def render(self, ctx, key, args, errors):

        if errors:
            images = args.get(key, [''])[0]
            images = self._parseValue(images)
        else:
            images = iforms.ISequenceConvertible(self.original).fromType(args.get(key))
            if images is None:
                images = []

        imgs = T.ul(id="artwork_list_"+keytocssid(ctx.key))

        for image in images:
            imgs[ T.li(id='item_%s'%image)[
                T.img(src='/artwork/system/assets/%s/mainImage?size=100x100'%image , class_="preview"),
                T.a(onClick='delete_item(%s);'%image)['delete']
            ] ]

        return T.div()[
            imgs, T.br(),
            T.textarea(name=key, id=keytocssid(ctx.key))['\n'.join(images)], T.br(),
            T.button(onclick="return ArtworkPicker('%s')"%keytocssid(ctx.key))['Choose artwork ...'],
            T.script(type="text/javascript")[
            T.xml("""
            function ArtworkPicker(elementId, type) {
                var url = '/artwork/system/assets/artworkbrowser';
                url = url + '?searchOwningId='+elementId+'&searchType='+type;
                var popup = window.open(url, 'ArtworkPicker', 'height=500,width=900,resizable,scrollbars');
                popup.focus();
                return false;
            }
            function imageListChanged(sortable) {
              var items = MochiKit.Sortable.Sortable.serialize(sortable).split('&');
              var newOrder=[];
              for(i=0;i<items.length;i++){
                var item = items[i];
                var id = item.split('=')[1];
                newOrder.push(id);
              }
              var ta=document.getElementById('%(key)s');
              ta.value='';
              for(i=0;i<newOrder.length;i++) {
                ta.value=ta.value+'\\n'+newOrder[i];
              }
            }

            function itemAdded() {
              MochiKit.Sortable.Sortable.create('artwork_list_%(key)s',{onUpdate:imageListChanged});
            }

            function delete_item(delete_id) {
              var element=document.getElementById('item_'+delete_id);
              removeElement(element);
              var ta=document.getElementById('%(key)s');
              var ids = ta.value.split('\\n');

              ta.value='';
              for(i=0;i<ids.length;i++) {
                id = ids[i];
                if(delete_id==id) {
                  continue;
                } 
                ta.value=ta.value+'\\n'+id;
              }
            }
            function setup() {
                connect('artwork_list_%(key)s', 'itemAdded', itemAdded); 
                signal('artwork_list_%(key)s', 'itemAdded');
            }
            setup();
            """%{'key': keytocssid(ctx.key)})
            ]
            ]
Esempio n. 22
0
class zoto_base_page(rend.Page):
    app = None
    log = None
    server_host_number = 0
    require_ssl = False
    tpl_path = '%s/web/templates' % aztk_config.aztk_root
    default_color = aztk_config.services.get('servers.httpserver',
                                             'default_color')

    docFactory = loaders.xmlfile(os.path.join(tpl_path, 'main_template.xml'))

    render_i18n = i18nrender()

    color_options = [
        'white_blue', 'white_gold', 'white_green', 'white_grey',
        'white_orange', 'white_pink', 'white_purple', 'white_ou', 'black_blue',
        'black_gold', 'black_green', 'black_grey', 'black_orange',
        'black_pink', 'black_purple'
    ]

    anon_header = loaders.stan(T.invisible[T.div(
        id="header_bar")[T.a(id="logo", href="/", title="Zoto Logo"),
                         T.div(id="main_links")[T.span(id="auth_holder"), ],
                         T.br(clear="right")]])

    global_css_includes = ["zoto_layout.css", "zoto_font.css"]
    local_css_includes = []
    global_js_includes = [
        "lang.js", "mochikit.js", "third_party/xmlrpc.js",
        "third_party/swfobject.js", "detect.lib.js", "core.js"
    ]
    """
		"utils.js",
		"zoto.lib.js",
		"modal.lib.js",
		"permissions.lib.js",
		"menu_box.lib.js",
		"zoto_auth.lib.js",
		"language.lib.js",
		"select_box.lib.js",
		"user_bar.lib.js",
		"tab_bar.lib.js",
		"contact_form.lib.js",
		"user_settings.lib.js", 
		"contacts.lib.js",
		"pagination.lib.js",
		"help_modal.lib.js",
		"upload_modal.lib.js",
		"publish.lib.js",
		"timer.lib.js",
		"color.lib.js"
	]
	"""
    local_js_includes = []

    global_feed_includes = []
    local_feed_includes = []

    page_manager_js = None

    def __init__(self, *args, **kwargs):
        rend.Page.__init__(self, *args, **kwargs)
        self.remember(
            I18NConfig(domain='zoto',
                       localeDir='%s/servers/site_root/i18n/' %
                       aztk_config.aztk_root), inevow.II18NConfig)
        self.domain = self.app.servers.httpserver._cfg_site_domain

    def _draw_header_bar(self, ctx):
        ctx.fillSlots('header_bar', self.anon_header)

    def _draw_top_bar(self, ctx):
        ctx.fillSlots('top_bar', T.div(id="top_bar"))

    def _draw_main_content(self, ctx):
        ctx.fillSlots('main_content', T.div(id="manager_hook"))

    def _get_browse_username(self, ctx):
        return "anonymous"

    def _get_browse_userid(self, ctx):
        return 0

    def _get_auth_username(self, ctx):
        request = inevow.IRequest(ctx)
        auth_hash = request.getCookie('auth_hash')
        if auth_hash:
            return auth_hash.split(':')[0]
        else:
            return "anonymous"

    def _get_auth_userid(self, ctx):
        request = inevow.IRequest(ctx)
        auth_hash = request.getCookie('auth_hash')
        if auth_hash:
            return int(auth_hash.split(':')[1])
        else:
            return None

    def _get_last_username(self, ctx):
        request = inevow.IRequest(ctx)
        return request.getCookie('last_username')

    def get_site_version(self):
        return self.app.servers.httpserver._cfg_site_version

    def renderHTTP(self, ctx):

        ### TODO: this code can be replaced with cookie logic.
        lang = ctx.arg('lang')
        if lang is not None:
            self.log.debug("setting alternate language: %s" % lang)
            ctx.remember([lang], inevow.ILanguages)

        ## self.log.debug("checking ssl: %s" % self.require_ssl)
        request = inevow.IRequest(ctx)

        if self.require_ssl and not request.isSecure():
            new_url = request.URLPath().secure()
            return redirectTo(new_url, request)
        else:
            return rend.Page.renderHTTP(self, ctx)

    def _get_color_option(self, ctx):
        request = inevow.IRequest(ctx)
        color_option = request.getCookie('zoto_color')
        if color_option not in self.color_options:
            color_option = self.default_color
        return color_option

    def make_js_path(self, file):
        # we use the server_host_number to build a hostname of www1 to www4
        self.server_host_number = self.server_host_number + 1
        host_num = (self.server_host_number % 4) + 1
        js_host = "http://www%s.%s" % (
            host_num, self.app.servers.httpserver._cfg_site_domain)
        #return "%s/js/%s/%s" % (js_host, self.get_site_version(), file)
        return "/js/%s/%s" % (self.get_site_version(), file)

    def make_css_path(self, file):
        # we use the server_host_number to build a hostname of www1 to www4
        self.server_host_number = self.server_host_number + 1
        host_num = (self.server_host_number % 4) + 1
        css_host = "http://www%s.%s" % (
            host_num, self.app.servers.httpserver._cfg_site_domain)
        #return "%s/css/%s/%s" % (css_host, self.get_site_version(), file)
        return "/css/%s/%s" % (self.get_site_version(), file)

    def render_head_tag(self, ctx, data):
        ctx.fillSlots('meta_tags', "")

        ## CSS
        stylesheets = []
        color_option = self._get_color_option(ctx)
        global_css_includes = self.global_css_includes + [
            'zoto_%s.css' % color_option
        ]
        for file in global_css_includes + self.local_css_includes:
            stylesheets += [
                T.link(type="text/css",
                       rel="stylesheet",
                       href=self.make_css_path(file)), '\n'
            ]
        ctx.fillSlots('css_includes', loaders.stan(T.invisible[stylesheets]))

        ## alternate links - rss, atom, etc.
        feed_links = []
        for feed_url in self.global_feed_includes + self.local_feed_includes:
            feed_links += [
                T.link(type="application/%s+xml" % feed_url['type'],
                       rel="alternate",
                       href=feed_url['uri']), '\n'
            ]
        ctx.fillSlots('feed_includes', loaders.stan(T.invisible[feed_links]))

        ## Javascript
        scripts = []
        if aztk_config.setup.get('site',
                                 'environment') in ["sandbox", "development"]:
            for script in self.global_js_includes + self.local_js_includes:
                if script == "core.js":
                    for script in js.core_js.scripts:
                        scripts += [
                            T.script(type="text/javascript",
                                     src=self.make_js_path(script)), '\n'
                        ]
                elif script == "site.js":
                    for script in js.site_js.scripts:
                        scripts += [
                            T.script(type="text/javascript",
                                     src=self.make_js_path(script)), '\n'
                        ]
                elif script == "managers.js":
                    for script in js.managers_js.scripts:
                        scripts += [
                            T.script(type="text/javascript",
                                     src=self.make_js_path(script)), '\n'
                        ]
                elif script == "mochikit.js":
                    scripts += [
                        T.script(type="text/javascript",
                                 src=self.make_js_path(
                                     "third_party/MochiKit/MochiKit.js")),
                        '\n',
                        T.script(type="text/javascript",
                                 src=self.make_js_path(
                                     "third_party/MochiKit/DragAndDrop.js")),
                        '\n',
                        T.script(type="text/javascript",
                                 src=self.make_js_path(
                                     "third_party/MochiKit/Sortable.js")), '\n'
                    ]
                else:
                    scripts += [
                        T.script(type="text/javascript",
                                 src=self.make_js_path(script)), '\n'
                    ]
            if self.page_manager_js:
                scripts += [
                    T.script(type="text/javascript",
                             src=self.make_js_path(self.page_manager_js)), '\n'
                ]
            ctx.fillSlots('js_includes', loaders.stan(T.invisible[scripts]))
        else:
            for script in self.global_js_includes + self.local_js_includes:
                if script == "mochikit.js":
                    scripts += [
                        T.script(
                            type="text/javascript",
                            src=self.make_js_path(
                                "third_party/MochiKit/packed/MochiKit.js")),
                        '\n'
                    ]
                else:
                    scripts += [
                        T.script(type="text/javascript",
                                 src=self.make_js_path(script)), '\n'
                    ]
            if self.page_manager_js:
                scripts += [
                    T.script(type="text/javascript",
                             src=self.make_js_path(self.page_manager_js)), '\n'
                ]
            ctx.fillSlots('js_includes', loaders.stan(T.invisible[scripts]))

        return ctx

    def render_domain_name(self, ctx, data):
        return self.app.cfg_setup.get('site', "domain")

    def render_js_zapi_key(self, ctx, data):
        return '5d4a65c46a072a4542a816f2f28bd01a'

    def render_js_browse_username(self, ctx, data):
        return self._get_browse_username(ctx)

    def render_js_color_option(self, ctx, data):
        return self._get_color_option(ctx)

    def render_footer(self, ctx, data):
        ctx.fillSlots(
            'blog_path',
            T.a(href="http://blog.%s/" %
                self.app.servers.httpserver._cfg_site_domain)["blog"])
        ctx.fillSlots(
            'blog_path',
            T.a(href="http://blog.%s/" %
                self.app.servers.httpserver._cfg_site_domain)["blog"])
        return ctx

    def render_noscript_meta(self, ctx, data):
        return ctx.tag[T.meta(
            **{
                'http-equiv':
                "refresh",
                'content':
                "1; URL=http://notice.%s/?op=js" %
                self.app.servers.httpserver._cfg_site_domain
            })]

    def render_copyright(self, ctx, data):
        return ctx.tag['Copyright ', entities.copy, ' ',
                       datetime.date.today().year,
                       ' Zoto, Inc. All rights reserved.']

    def render_title(self, ctx, data):
        ### TODO: we need to return fancier stuff here, and consolodate what is in the mainhomepage python file in /zoto/aztk/servers/site_root/dyn_pages/
        # return ctx.tag["Zoto 3.0 Preview - Served from %s" % socket.gethostname()]
        return ctx.tag["Zoto 3.0 - Photo Sharing"]

    def render_header_div_thing(self, ctx, data):
        return ""
        """
		return ctx.tag[loaders.stan(
			T.div(id="header_bar_thing")
		)]
		"""

    def render_content(self, ctx, data):
        self._draw_header_bar(ctx)
        self._draw_top_bar(ctx)
        self._draw_main_content(ctx)
        return ctx.tag
Esempio n. 23
0
    def render_events(self, ctx, data):
        if not self.download_status.storage_index:
            return
        srt = self.short_relative_time
        l = T.div()
        
        t = T.table(align="left", class_="status-download-events")
        t[T.tr[T.th["serverid"], T.th["sent"], T.th["received"],
               T.th["shnums"], T.th["RTT"]]]
        dyhb_events = []
        for serverid,requests in self.download_status.dyhb_requests.iteritems():
            for req in requests:
                dyhb_events.append( (serverid,) + req )
        dyhb_events.sort(key=lambda req: req[1])
        for d_ev in dyhb_events:
            (serverid, sent, shnums, received) = d_ev
            serverid_s = idlib.shortnodeid_b2a(serverid)
            rtt = None
            if received is not None:
                rtt = received - sent
            if not shnums:
                shnums = ["-"]
            t[T.tr(style="background: %s" % self.color(serverid))[
                [T.td[serverid_s], T.td[srt(sent)], T.td[srt(received)],
                 T.td[",".join([str(shnum) for shnum in shnums])],
                 T.td[self.render_time(None, rtt)],
                 ]]]
        
        l[T.h2["DYHB Requests:"], t]
        l[T.br(clear="all")]
        
        t = T.table(align="left",class_="status-download-events")
        t[T.tr[T.th["range"], T.th["start"], T.th["finish"], T.th["got"],
               T.th["time"], T.th["decrypttime"], T.th["pausedtime"],
               T.th["speed"]]]
        for r_ev in self.download_status.read_events:
            (start, length, requesttime, finishtime, bytes, decrypt, paused) = r_ev
            if finishtime is not None:
                rtt = finishtime - requesttime - paused
                speed = self.render_rate(None, compute_rate(bytes, rtt))
                rtt = self.render_time(None, rtt)
                decrypt = self.render_time(None, decrypt)
                paused = self.render_time(None, paused)
            else:
                speed, rtt, decrypt, paused = "","","",""
            t[T.tr[T.td["[%d:+%d]" % (start, length)],
                   T.td[srt(requesttime)], T.td[srt(finishtime)],
                   T.td[bytes], T.td[rtt], T.td[decrypt], T.td[paused],
                   T.td[speed],
                   ]]
        
        l[T.h2["Read Events:"], t]
        l[T.br(clear="all")]
        
        t = T.table(align="left",class_="status-download-events")
        t[T.tr[T.th["type"], T.th["segnum"], T.th["when"], T.th["range"],
               T.th["decodetime"], T.th["segtime"], T.th["speed"]]]
        reqtime = (None, None)
        for s_ev in self.download_status.segment_events:
            (etype, segnum, when, segstart, seglen, decodetime) = s_ev
            if etype == "request":
                t[T.tr[T.td["request"],
                    T.td["seg%d" % segnum],
                    T.td[srt(when)],
                    T.td["-"],
                    T.td["-"],
                    T.td["-"],
                    T.td["-"]]]
                    
                reqtime = (segnum, when)
            elif etype == "delivery":
                if reqtime[0] == segnum:
                    segtime = when - reqtime[1]
                    speed = self.render_rate(None, compute_rate(seglen, segtime))
                    segtime = self.render_time(None, segtime)
                else:
                    segtime, speed = "", ""
                t[T.tr[T.td["delivery"], T.td["seg%d" % segnum],
                       T.td[srt(when)],
                       T.td["[%d:+%d]" % (segstart, seglen)],
                       T.td[self.render_time(None,decodetime)],
                       T.td[segtime], T.td[speed]]]
            elif etype == "error":
                t[T.tr[T.td["error"], T.td["seg%d" % segnum]]]
                
        l[T.h2["Segment Events:"], t]
        l[T.br(clear="all")]

        t = T.table(align="left",class_="status-download-events")
        t[T.tr[T.th["serverid"], T.th["shnum"], T.th["range"],
               T.th["txtime"], T.th["rxtime"], T.th["received"], T.th["RTT"]]]
        reqtime = (None, None)
        request_events = []
        for serverid,requests in self.download_status.requests.iteritems():
            for req in requests:
                request_events.append( (serverid,) + req )
        request_events.sort(key=lambda req: (req[4],req[1]))
        for r_ev in request_events:
            (peerid, shnum, start, length, sent, receivedlen, received) = r_ev
            rtt = None
            if received is not None:
                rtt = received - sent
            peerid_s = idlib.shortnodeid_b2a(peerid)
            t[T.tr(style="background: %s" % self.color(peerid))[
                T.td[peerid_s], T.td[shnum],
                T.td["[%d:+%d]" % (start, length)],
                T.td[srt(sent)], T.td[srt(received)], T.td[receivedlen],
                T.td[self.render_time(None, rtt)],
                ]]
                
        l[T.h2["Requests:"], t]
        l[T.br(clear="all")]

        return l
	def render_content(self, ctx, data):
		ctx.fillSlots('header_bar', self.anon_header)
		ctx.fillSlots('top_bar', T.div(id=""))
		if isinstance(self.failure.value, errors.PermissionDenied):
			error_text = T.div()[
				T.br(),
				T.h3[
					T.img(src="/image/error.png"),
					T.span[" hey! this stuff is private"]
				],
				T.br(),
				T.div()[
					"Sorry.  The contents of this page aren't for public consumption."
				],
				T.br(),
				T.div()[
					"If you think you should have access to this area you can email us at ",
					T.a(href="mailto:[email protected]")[ " [email protected] "],
					" or search our ",
					T.a(href="http://forums.zoto.com")[ " forums"],
					"."
				]
			]
		else:
			## APIError
			## AsyncStack
			self.request.setResponseCode(http.INTERNAL_SERVER_ERROR)
			if aztk_config.setup.get('site', 'environment') in ('sandbox', 'development'):
				error_text = T.div()[
					T.span[self.failure.getErrorMessage()],
					T.br(),
					T.span[self.failure.getBriefTraceback()]
				]
			else:
				#error_text = T.div["Internal error"]
				error_text = T.div()[
					T.br(),
					T.h3[
						T.img(src="/image/error.png"),
						T.span[" something has gone horribly wrong"]
					],
					T.br(),
					T.div()[
						"It looks like we are experiencing some technical difficulty displaying items on this page. " \
						"Please try to refresh the page. "\
						"If the problem persists contact us and let us know. "					
					],
					T.br(),
					T.div()[
						"Thanks for your patience. If you have any questions you can email us at ",
						T.a(href="mailto:[email protected]")[ " [email protected] "],
						" or search our ",
						T.a(href="http://forums.zoto.com")[ " forums"],
						"."
					]
				]

		ctx.fillSlots('main_content', loaders.stan(
			T.div(id="error_box")[
				error_text
			]

		))
		return ctx.tag
 def test_emptySingletonTag(self):
     """
     L{Tag} instances which are allowed to be self-closing are flattened
     that way.
     """
     self.assertStringEqual(self.flatten(br()), "<br />")
Esempio n. 26
0
def testXbuild_grid(argsdict, request=None):
    start_time = clock()
    one_week = 60 * 60 * 24 * 7
    one_week_ago = start_time - one_week

    max_results = (int(argsdict['max_results']) if
                   ('max_results' in argsdict
                    and argsdict['max_results'] != '') else 128)
    if max_results < 1:
        print 'Max results must be at least 1'
        sys.exit(1)

    countdown = max_results

    test_cases = (None if
                  ('test_cases' not in argsdict or argsdict['test_cases']
                   == None or argsdict['test_cases'] == '') else
                  (compile(argsdict['test_cases']) if
                   ('case' in argsdict and argsdict['case']) else compile(
                       argsdict['test_cases'], IGNORECASE)))

    exclude_cases = (None if ('exclude_cases' not in argsdict
                              or argsdict['exclude_cases'] == None
                              or argsdict['exclude_cases'] == '') else
                     (compile(argsdict['exclude_cases']) if
                      ('case' in argsdict and argsdict['case']) else compile(
                          argsdict['exclude_cases'], IGNORECASE)))

    results_by_build = {}
    results = []
    tests = set()
    build_ids = []

    mongo = src.bvtlib.mongodb.get_autotest()
    branch = argsdict['branch'] if 'branch' in argsdict else 'master'
    builds_query = {'branch': branch}

    force = 'force' in argsdict and argsdict['force']
    sort_columns = argsdict[
        'sort_columns'] if 'sort_columns' in argsdict else 'alphabetic'

    total_fails_by_test = {}
    total_passes_by_test = {}
    day_results = {}
    latest_year = None
    latest_yday = None
    day_fails = 0
    day_passes = 0

    for build in mongo.builds.find(builds_query).sort([('tag_time', DESCENDING)
                                                       ]):
        build_id = build['_id']
        build_time = (build['tag_time'] if 'tag_time' in build else
                      (['timestamp'] if 'timestamp' in build else None))
        successes_for_build = {}
        failures_for_build = {}
        results_query = {'build': build_id}
        interesting = False
        for result in mongo.results.find(results_query):
            if 'infrastructure_problem' not in result or result[
                    'infrastructure_problem'] == False:
                if 'test_case' in result:
                    test_case = result['test_case']
                    if (test_case != None and
                        (test_cases == None or test_cases.search(test_case))
                            and (exclude_cases == None
                                 or not exclude_cases.search(test_case))
                            and (force or 'experiments.py' not in test_case)):
                        if 'failure' in result and result['failure'] != '':
                            result_details = result['failure']
                            interesting = True
                            if test_case in failures_for_build:
                                failures_for_build[test_case].append(
                                    result_details)
                            else:
                                failures_for_build[test_case] = [
                                    result_details
                                ]
                            if test_case in total_fails_by_test:
                                total_fails_by_test[test_case] += 1
                            else:
                                total_fails_by_test[test_case] = 1
                            day_fails += 1
                        else:
                            if 'end_time' in result:
                                interesting = True
                                if test_case in successes_for_build:
                                    successes_for_build[test_case].append(
                                        result)
                                else:
                                    successes_for_build[test_case] = [result]
                                if test_case in total_passes_by_test:
                                    total_passes_by_test[test_case] += 1
                                else:
                                    total_passes_by_test[test_case] = 1
                                day_passes += 1
        if interesting:
            results_for_build = (build_time, successes_for_build,
                                 failures_for_build)
            gmt = gmtime(float(build_time))
            if ((gmt.tm_year != latest_year) or (gmt.tm_yday != latest_yday)):
                latest_year = gmt.tm_year
                latest_yday = gmt.tm_yday
                date_text = strftime('%Y-%m-%d', gmt)
                day_results[date_text] = (': ' + repr(day_passes) +
                                          ' passed, ' + repr(day_fails) +
                                          ' failed')
                day_fails = 0
                day_passes = 0
            results.append(results_for_build)
            results_by_build[build_id] = results_for_build
            build_ids.append(build_id)
            countdown -= 1
            if countdown == 0:
                break
        tests.update(failures_for_build.keys())
        tests.update(successes_for_build)
        if countdown == 0:
            break

    # convert from set to list
    test_names = [test for test in tests]

    if sort_columns == 'ratio':
        sort_text = 'Columns are sorted by decreasing ratio of fails.'
        ratios = {}
        for test in test_names:
            passes = total_passes_by_test[
                test] if test in total_passes_by_test else 0
            fails = total_fails_by_test[
                test] if test in total_fails_by_test else 0
            ratios[test] = -1 if (passes == 0
                                  and fails == 0) else fails / (passes + fails)
        test_names = [
            name for name, count in sorted(
                ratios.iteritems(), key=itemgetter(1), reverse=True)
        ]
    elif sort_columns == 'frequency':
        sort_text = 'Columns are sorted by decreasing number of fails.'
        frequencies = {}
        for test in test_names:
            frequencies[test] = total_fails_by_test[
                test] if test in total_fails_by_test else 0
        test_names = [
            name for name, count in sorted(
                frequencies.iteritems(), key=itemgetter(1), reverse=True)
        ]
    elif sort_columns == 'alphabetic':
        sort_text = 'Columns are sorted alphabetically by test case description.'
        test_names.sort()
    else:
        sort_text = 'Columns are not sorted, as an unknown sort type "' + repr(
            sort_columns) + '" was specified.'

    column_number = 1
    column_numbers = {}
    column_names = [th['Test case']]
    column_keys = []
    test_labels = {}

    for test_name in test_names:
        test_label = test_name.replace(' ', '_')
        column_numbers[test_name] = column_number
        column_heading = th[a(href="#" + test_label,
                              title=test_name)[repr(column_number)]]
        column_names.append(column_heading)
        column_keys.append(li[a(name=test_label)[a(
            href="http://autotest/results?reverse=1&test_case=" +
            test_name)[test_name]]])
        test_labels[test_name] = test_label
        column_number += 1

    rows = [column_names]

    latest_year = None
    latest_yday = None
    column_count = 1 + len(column_names)
    build_number_pattern = compile('.+-([0-9]+)-.+')

    day_heading_style = {'colspan': column_count, 'class': 'day_heading'}
    for build_id in build_ids:
        (build_time, successes, failures) = results_by_build[build_id]
        try:
            build_number_match = build_number_pattern.match(build_id)
            build_number_string = build_number_match.group(
                1) if build_number_match else build_id
            gmt = gmtime(float(build_time))
            if ((gmt.tm_year != latest_year) or (gmt.tm_yday != latest_yday)):
                latest_year = gmt.tm_year
                latest_yday = gmt.tm_yday
                raw_date_text = strftime('%Y-%m-%d', gmt)
                date_text = raw_date_text
                if float(build_time) >= one_week_ago:
                    date_text += strftime(' (%A)', gmt)
                if day_results[raw_date_text] != None:
                    date_text += day_results[raw_date_text]
                rows.append([tr[th(**day_heading_style)[date_text]]])
            cells = [
                th(title=(build_id + '\n' +
                          asctime(gmt)))[a(href="http://autotest/build/" +
                                           build_id)[build_number_string],
                                         br(),
                                         strftime('%H:%M:%S', gmt)]
            ]
        except TypeError:
            gmt = None
            cells = [th[a(href="http://autotest/build/" + build_id)[build_id]]]
        for test in test_names:
            success_count = len(successes[test]) if test in successes else 0
            this_test_failures = failures[test] if test in failures else None
            fail_count = len(
                this_test_failures) if this_test_failures != None else 0
            some_passed = success_count > 0
            some_failed = fail_count > 0
            no_results = not (some_passed or some_failed)

            if proportionate_colour:
                colour = white if no_results else rgb_string(
                    fail_count, success_count, 0, intensity=0.5)
            else:
                several_failed = fail_count > 1
                colour = (amber if some_passed and some_failed else
                          (white if no_results else
                           ((green if success_count > 1 else pale_green
                             ) if not some_failed else
                            (red if several_failed else pale_red))))

            cell_hover_text = test + ': ' + repr(success_count) + (
                ' pass' if success_count == 1 else ' passes')
            if some_failed:
                # collect up identical error messages so we can just give a count instead of repeating them
                fail_detail_counts = {}
                for x in this_test_failures:
                    fail_detail_counts[x] = fail_detail_counts[
                        x] + 1 if x in fail_detail_counts else 1

                details = [
                    repr(count) + ": " +
                    # display commonest error messages first
                    message for message, count in sorted(
                        fail_detail_counts.iteritems(),
                        key=itemgetter(1),
                        reverse=True) if message != None
                ]

                cell_hover_text = cell_hover_text + '\nFailures:\n' + (
                    '\n'.join(details))
            cell_text = [
                div(align='left')[repr(success_count)],
                div(align='right')[repr(fail_count)]
            ]
            if some_passed or some_failed:
                cells.append(
                    td(bgcolor=colour)[a(href="results?build=" + build_id +
                                         "&test_case=" + test,
                                         title=cell_hover_text)[cell_text]])
            else:
                cells.append(td[' '])
        rows.append([tr[cells]])

    passes_row = [th['Passes']]
    fails_row = [th['Fails']]

    for test_name in test_names:
        pass_count = total_passes_by_test[
            test_name] if test_name in total_passes_by_test else 0
        fail_count = total_fails_by_test[
            test_name] if test_name in total_fails_by_test else 0
        total = pass_count + fail_count
        colour_string = 'white' if total == 0 else rgb_string(
            fail_count, pass_count, 0, intensity=0.5)
        passes_row.append(td(bgcolor=colour_string)[repr(pass_count)])
        fails_row.append(td(bgcolor=colour_string)[repr(fail_count)])

    rows.insert(1, tr[fails_row])
    rows.insert(1, tr[passes_row])

    column_key = [ol[column_keys]]
    table_grid = [
        table(border='true',
              style="border-collapse: collapse",
              align="center",
              width="96%")[rows]
    ]

    title_text = 'BVT results grid for ' + branch

    if ('test_cases' in argsdict and argsdict['test_cases'] != None
            and argsdict['test_cases'] != ''):
        title_text += ' matching "' + argsdict['test_cases'] + '"'
    if ('exclude_cases' in argsdict and argsdict['exclude_cases'] != None
            and argsdict['exclude_cases'] != ''):
        title_text += ' excluding "' + argsdict['exclude_cases'] + '"'

    if request != None:
        requery_form = [
            table(
                align="center", width="96%", bgcolor="#f0f0f0"
            )[tr()
              [td()['Branch: ',
                    stan_input(name='branch', value=branch)['']],
               td(
               )['Test cases: ',
                 stan_input(name='test_cases',
                            value=(
                                argsdict['test_cases'] if 'test_cases' in
                                argsdict else ''))[''], " ",
                 'Excluded cases: ',
                 stan_input(name='exclude_cases',
                            value=(
                                argsdict['exclude_cases'] if 'exclude_cases' in
                                argsdict else ''))[''], " ",
                 'Case-significant search',
                 stan_input(type='checkbox', name='case')['']],
               td()['Include malformed results:',
                    stan_input(type='checkbox', name='force')['']]],
              tr()[td()['Columns sort order: ',
                        stan_input(type='radio',
                                   name='sort_columns',
                                   value='alphabetic',
                                   **({
                                       'checked': 1
                                   } if sort_columns == 'alphabetic' else {}
                                      ))['alphabetic'], " ",
                        stan_input(type='radio',
                                   name='sort_columns',
                                   value='frequency',
                                   **({
                                       'checked': 1
                                   } if sort_columns == 'frequency' else {}
                                      ))['frequency'], " ",
                        stan_input(type='radio',
                                   name='sort_columns',
                                   value='ratio',
                                   **({
                                       'checked': 1
                                   } if sort_columns == 'ratio' else {}
                                      ))['ratio']],
                   td()['Max results:',
                        stan_input(name='max_results', value=max_results)['']],
                   td()[stan_input(type='submit')]]]
        ]
    else:
        requery_form = None

    page_contents = [title[title_text], h1[title_text]]
    page_contents += [
        p[key_text], p[sort_text], table_grid, h2['column key'], p[sort_text],
        column_key
    ]

    if not proportionate_colour:
        page_contents += [h2['cell key'], key_table]

    page_contents += [hr(), div(align='right')['produced at ', asctime()]]

    return str(nevow.flat.flatten(page_contents)), str(
        nevow.flat.flatten(requery_form))
Esempio n. 27
0
    def render_events(self, ctx, data):
        if not self.download_status.storage_index:
            return
        srt = self.short_relative_time
        l = T.div()

        t = T.table(align="left", class_="status-download-events")
        t[T.tr[T.th["serverid"], T.th["sent"], T.th["received"],
               T.th["shnums"], T.th["RTT"]]]
        for d_ev in self.download_status.dyhb_requests:
            server = d_ev["server"]
            sent = d_ev["start_time"]
            shnums = d_ev["response_shnums"]
            received = d_ev["finish_time"]
            rtt = None
            if received is not None:
                rtt = received - sent
            if not shnums:
                shnums = ["-"]
            t[T.tr(style="background: %s" % self.color(server))[
                [T.td[server.get_name()], T.td[srt(sent)], T.td[srt(received)],
                 T.td[",".join([str(shnum) for shnum in shnums])],
                 T.td[self.render_time(None, rtt)],
                 ]]]

        l[T.h2["DYHB Requests:"], t]
        l[T.br(clear="all")]

        t = T.table(align="left",class_="status-download-events")
        t[T.tr[T.th["range"], T.th["start"], T.th["finish"], T.th["got"],
               T.th["time"], T.th["decrypttime"], T.th["pausedtime"],
               T.th["speed"]]]
        for r_ev in self.download_status.read_events:
            start = r_ev["start"]
            length = r_ev["length"]
            bytes = r_ev["bytes_returned"]
            decrypt_time = ""
            if bytes:
                decrypt_time = self._rate_and_time(bytes, r_ev["decrypt_time"])
            speed, rtt = "",""
            if r_ev["finish_time"] is not None:
                rtt = r_ev["finish_time"] - r_ev["start_time"] - r_ev["paused_time"]
                speed = self.render_rate(None, compute_rate(bytes, rtt))
                rtt = self.render_time(None, rtt)
            paused = self.render_time(None, r_ev["paused_time"])

            t[T.tr[T.td["[%d:+%d]" % (start, length)],
                   T.td[srt(r_ev["start_time"])], T.td[srt(r_ev["finish_time"])],
                   T.td[bytes], T.td[rtt],
                   T.td[decrypt_time], T.td[paused],
                   T.td[speed],
                   ]]

        l[T.h2["Read Events:"], t]
        l[T.br(clear="all")]

        t = T.table(align="left",class_="status-download-events")
        t[T.tr[T.th["segnum"], T.th["start"], T.th["active"], T.th["finish"],
               T.th["range"],
               T.th["decodetime"], T.th["segtime"], T.th["speed"]]]
        for s_ev in self.download_status.segment_events:
            range_s = "-"
            segtime_s = "-"
            speed = "-"
            decode_time = "-"
            if s_ev["finish_time"] is not None:
                if s_ev["success"]:
                    segtime = s_ev["finish_time"] - s_ev["active_time"]
                    segtime_s = self.render_time(None, segtime)
                    seglen = s_ev["segment_length"]
                    range_s = "[%d:+%d]" % (s_ev["segment_start"], seglen)
                    speed = self.render_rate(None, compute_rate(seglen, segtime))
                    decode_time = self._rate_and_time(seglen, s_ev["decode_time"])
                else:
                    # error
                    range_s = "error"
            else:
                # not finished yet
                pass

            t[T.tr[T.td["seg%d" % s_ev["segment_number"]],
                   T.td[srt(s_ev["start_time"])],
                   T.td[srt(s_ev["active_time"])],
                   T.td[srt(s_ev["finish_time"])],
                   T.td[range_s],
                   T.td[decode_time],
                   T.td[segtime_s], T.td[speed]]]

        l[T.h2["Segment Events:"], t]
        l[T.br(clear="all")]
        t = T.table(align="left",class_="status-download-events")
        t[T.tr[T.th["serverid"], T.th["shnum"], T.th["range"],
               T.th["txtime"], T.th["rxtime"],
               T.th["received"], T.th["RTT"]]]
        for r_ev in self.download_status.block_requests:
            server = r_ev["server"]
            rtt = None
            if r_ev["finish_time"] is not None:
                rtt = r_ev["finish_time"] - r_ev["start_time"]
            color = self.color(server)
            t[T.tr(style="background: %s" % color)[
                T.td[server.get_name()], T.td[r_ev["shnum"]],
                T.td["[%d:+%d]" % (r_ev["start"], r_ev["length"])],
                T.td[srt(r_ev["start_time"])], T.td[srt(r_ev["finish_time"])],
                T.td[r_ev["response_length"] or ""],
                T.td[self.render_time(None, rtt)],
                ]]

        l[T.h2["Requests:"], t]
        l[T.br(clear="all")]

        return l
Esempio n. 28
0
 def render_address(self, ctx, data):
     tag = ctx.tag.clear()
     if data is None:
         return tag[ '-' ]
     else:
         return tag[ [(l,T.br()) for l in data.splitlines()] ]
Esempio n. 29
0
    def render_events(self, ctx, data):
        if not self.download_status.storage_index:
            return
        srt = self.short_relative_time
        l = T.div()

        t = T.table(align="left", class_="status-download-events")
        t[T.tr[T.th["serverid"], T.th["sent"], T.th["received"],
               T.th["shnums"], T.th["RTT"]]]
        for d_ev in self.download_status.dyhb_requests:
            server = d_ev["server"]
            sent = d_ev["start_time"]
            shnums = d_ev["response_shnums"]
            received = d_ev["finish_time"]
            rtt = None
            if received is not None:
                rtt = received - sent
            if not shnums:
                shnums = ["-"]
            t[T.tr(style="background: %s" % self.color(server))[[
                T.td[server.get_name()],
                T.td[srt(sent)],
                T.td[srt(received)],
                T.td[",".join([str(shnum) for shnum in shnums])],
                T.td[self.render_time(None, rtt)],
            ]]]

        l[T.h2["DYHB Requests:"], t]
        l[T.br(clear="all")]

        t = T.table(align="left", class_="status-download-events")
        t[T.tr[T.th["range"], T.th["start"], T.th["finish"], T.th["got"],
               T.th["time"], T.th["decrypttime"], T.th["pausedtime"],
               T.th["speed"]]]
        for r_ev in self.download_status.read_events:
            start = r_ev["start"]
            length = r_ev["length"]
            bytes = r_ev["bytes_returned"]
            decrypt_time = ""
            if bytes:
                decrypt_time = self._rate_and_time(bytes, r_ev["decrypt_time"])
            speed, rtt = "", ""
            if r_ev["finish_time"] is not None:
                rtt = r_ev["finish_time"] - r_ev["start_time"] - r_ev[
                    "paused_time"]
                speed = self.render_rate(None, compute_rate(bytes, rtt))
                rtt = self.render_time(None, rtt)
            paused = self.render_time(None, r_ev["paused_time"])

            t[T.tr[T.td["[%d:+%d]" % (start, length)],
                   T.td[srt(r_ev["start_time"])],
                   T.td[srt(r_ev["finish_time"])], T.td[bytes], T.td[rtt],
                   T.td[decrypt_time], T.td[paused], T.td[speed], ]]

        l[T.h2["Read Events:"], t]
        l[T.br(clear="all")]

        t = T.table(align="left", class_="status-download-events")
        t[T.tr[T.th["segnum"], T.th["start"], T.th["active"], T.th["finish"],
               T.th["range"], T.th["decodetime"], T.th["segtime"],
               T.th["speed"]]]
        for s_ev in self.download_status.segment_events:
            range_s = "-"
            segtime_s = "-"
            speed = "-"
            decode_time = "-"
            if s_ev["finish_time"] is not None:
                if s_ev["success"]:
                    segtime = s_ev["finish_time"] - s_ev["active_time"]
                    segtime_s = self.render_time(None, segtime)
                    seglen = s_ev["segment_length"]
                    range_s = "[%d:+%d]" % (s_ev["segment_start"], seglen)
                    speed = self.render_rate(None,
                                             compute_rate(seglen, segtime))
                    decode_time = self._rate_and_time(seglen,
                                                      s_ev["decode_time"])
                else:
                    # error
                    range_s = "error"
            else:
                # not finished yet
                pass

            t[T.tr[T.td["seg%d" % s_ev["segment_number"]],
                   T.td[srt(s_ev["start_time"])],
                   T.td[srt(s_ev["active_time"])],
                   T.td[srt(s_ev["finish_time"])], T.td[range_s],
                   T.td[decode_time], T.td[segtime_s], T.td[speed]]]

        l[T.h2["Segment Events:"], t]
        l[T.br(clear="all")]
        t = T.table(align="left", class_="status-download-events")
        t[T.tr[T.th["serverid"], T.th["shnum"], T.th["range"], T.th["txtime"],
               T.th["rxtime"], T.th["received"], T.th["RTT"]]]
        for r_ev in self.download_status.block_requests:
            server = r_ev["server"]
            rtt = None
            if r_ev["finish_time"] is not None:
                rtt = r_ev["finish_time"] - r_ev["start_time"]
            color = self.color(server)
            t[T.tr(style="background: %s" %
                   color)[T.td[server.get_name()], T.td[r_ev["shnum"]],
                          T.td["[%d:+%d]" % (r_ev["start"], r_ev["length"])],
                          T.td[srt(r_ev["start_time"])],
                          T.td[srt(r_ev["finish_time"])],
                          T.td[r_ev["response_length"]
                               or ""], T.td[self.render_time(None, rtt)], ]]

        l[T.h2["Requests:"], t]
        l[T.br(clear="all")]

        return l
Esempio n. 30
0
File: grid.py Progetto: dickon/bvt
def testXbuild_grid(argsdict, request=None):
    start_time = clock()
    one_week = 60 * 60 * 24 * 7
    one_week_ago = start_time - one_week

    max_results = (int(argsdict['max_results'])
                   if ('max_results' in argsdict and argsdict['max_results'] != '')
                   else 128)
    if max_results < 1:
        print 'Max results must be at least 1'
        sys.exit(1)

    countdown = max_results

    test_cases = (None if ('test_cases' not in argsdict
                           or argsdict['test_cases'] == None
                           or argsdict['test_cases'] == '')
                  else (compile(argsdict['test_cases']) if ('case' in argsdict and argsdict['case'])
                        else compile(argsdict['test_cases'], IGNORECASE)))

    exclude_cases = (None if ('exclude_cases' not in argsdict
                              or argsdict['exclude_cases'] == None
                              or argsdict['exclude_cases'] == '')
                     else (compile(argsdict['exclude_cases']) if ('case' in argsdict and argsdict['case'])
                           else compile(argsdict['exclude_cases'], IGNORECASE)))

    results_by_build = {}
    results = []
    tests = set()
    build_ids = []

    mongo = bvtlib.mongodb.get_autotest()
    branch = argsdict['branch'] if 'branch' in argsdict else 'master'
    builds_query = {'branch': branch}

    force = 'force' in argsdict and argsdict['force']
    sort_columns = argsdict['sort_columns'] if 'sort_columns' in argsdict else 'alphabetic'

    total_fails_by_test = {}
    total_passes_by_test = {}
    day_results = {}
    latest_year = None
    latest_yday = None
    day_fails = 0
    day_passes = 0

    for build in mongo.builds.find(builds_query).sort([('tag_time', DESCENDING)]):
        build_id = build['_id']
        build_time = (build['tag_time'] if 'tag_time' in build
                      else (['timestamp'] if 'timestamp' in build
                            else None))
        successes_for_build = {}
        failures_for_build = {}
        results_query={'build': build_id}
        interesting = False
        for result in mongo.results.find(results_query):
            if 'infrastructure_problem' not in result or result['infrastructure_problem'] == False:
                if 'test_case' in result:
                    test_case = result['test_case']
                    if (test_case != None
                        and (test_cases == None
                             or test_cases.search(test_case))
                        and (exclude_cases == None
                             or not exclude_cases.search(test_case))
                        and (force or 'experiments.py' not in test_case)):
                        if 'failure' in result and result['failure'] != '':
                            result_details = result['failure']
                            interesting = True
                            if test_case in failures_for_build:
                                failures_for_build[test_case].append(result_details)
                            else:
                                failures_for_build[test_case] = [ result_details ]
                            if test_case in total_fails_by_test:
                                total_fails_by_test[test_case] += 1
                            else:
                                total_fails_by_test[test_case] = 1
                            day_fails += 1
                        else:
                            if 'end_time' in result:
                                interesting = True
                                if test_case in successes_for_build:
                                    successes_for_build[test_case].append(result)
                                else:
                                    successes_for_build[test_case] = [ result ]
                                if test_case in total_passes_by_test:
                                    total_passes_by_test[test_case] += 1
                                else:
                                    total_passes_by_test[test_case] = 1
                                day_passes += 1
        if interesting:
            results_for_build = (build_time, successes_for_build, failures_for_build)
            gmt = gmtime(float(build_time))
            if ((gmt.tm_year != latest_year) or (gmt.tm_yday != latest_yday)):
                latest_year = gmt.tm_year
                latest_yday = gmt.tm_yday
                date_text = strftime('%Y-%m-%d', gmt)
                day_results[date_text] = (': ' + repr(day_passes) + ' passed, ' + repr(day_fails) + ' failed')
                day_fails = 0
                day_passes = 0
            results.append(results_for_build)
            results_by_build[build_id] = results_for_build
            build_ids.append(build_id)
            countdown -= 1
            if countdown == 0:
                break
        tests.update(failures_for_build.keys())
        tests.update(successes_for_build)
        if countdown == 0:
            break

    # convert from set to list
    test_names = [ test for test in tests ]

    if sort_columns == 'ratio':
        sort_text = 'Columns are sorted by decreasing ratio of fails.'
        ratios = {}
        for test in test_names:
            passes = total_passes_by_test[test] if test in total_passes_by_test else 0
            fails = total_fails_by_test[test] if test in total_fails_by_test else 0
            ratios[test] = -1 if (passes == 0 and fails == 0) else fails / (passes + fails)
        test_names = [ name for name, count in sorted(ratios.iteritems(),
                                                      key = itemgetter(1),
                                                      reverse=True) ]
    elif sort_columns == 'frequency':
        sort_text = 'Columns are sorted by decreasing number of fails.'
        frequencies = {}
        for test in test_names:
            frequencies[test] = total_fails_by_test[test] if test in total_fails_by_test else 0
        test_names = [ name for name, count in sorted(frequencies.iteritems(),
                                                      key = itemgetter(1),
                                                      reverse=True) ]
    elif sort_columns == 'alphabetic':
        sort_text = 'Columns are sorted alphabetically by test case description.'
        test_names.sort()
    else:
        sort_text = 'Columns are not sorted, as an unknown sort type "' + repr(sort_columns) + '" was specified.'

    column_number = 1
    column_numbers = {}
    column_names = [th['Test case']]
    column_keys = []
    test_labels = {}
    
    for test_name in test_names:
        test_label = test_name.replace(' ', '_')
        column_numbers[test_name] = column_number
        column_heading = th[a(href="#"+test_label, title=test_name)
                            [repr(column_number)]]
        column_names.append(column_heading)
        column_keys.append(li[a(name=test_label)
                              [a(href="http://autotest/results?reverse=1&test_case="+test_name)
                               [test_name]]])
        test_labels[test_name] = test_label
        column_number += 1

    rows = [column_names]

    latest_year = None
    latest_yday = None
    column_count = 1 + len(column_names)
    build_number_pattern = compile('.+-([0-9]+)-.+')

    day_heading_style = {'colspan':column_count, 'class':'day_heading'}
    for build_id in build_ids:
        (build_time, successes, failures) = results_by_build[build_id]
        try:
            build_number_match = build_number_pattern.match(build_id)
            build_number_string = build_number_match.group(1) if build_number_match else build_id
            gmt = gmtime(float(build_time))
            if ((gmt.tm_year != latest_year) or (gmt.tm_yday != latest_yday)):
                latest_year = gmt.tm_year
                latest_yday = gmt.tm_yday
                raw_date_text = strftime('%Y-%m-%d', gmt)
                date_text = raw_date_text
                if float(build_time) >= one_week_ago:
                    date_text += strftime(' (%A)', gmt)
                if day_results[raw_date_text] != None:
                    date_text += day_results[raw_date_text]
                rows.append([tr[th(**day_heading_style)[date_text]]])
            cells = [th(title=(build_id + '\n' + asctime(gmt)))[
                    a(href="http://autotest/build/"+build_id)[build_number_string], br(), strftime('%H:%M:%S', gmt)
                    ]]
        except TypeError:
            gmt = None
            cells = [th[a(href="http://autotest/build/"+build_id)[build_id]]]
        for test in test_names:
            success_count = len(successes[test]) if test in successes else 0
            this_test_failures = failures[test] if test in failures else None
            fail_count = len(this_test_failures) if this_test_failures != None else 0
            some_passed = success_count > 0
            some_failed = fail_count > 0
            no_results = not (some_passed or some_failed)

            if proportionate_colour:
                colour = white if no_results else rgb_string(fail_count, success_count, 0, intensity=0.5)
            else:
                several_failed = fail_count > 1
                colour = (amber if some_passed and some_failed
                          else (white if no_results
                                else ((green if success_count > 1 else pale_green) if not some_failed
                                      else (red if several_failed
                                            else pale_red))))


            cell_hover_text = test + ': ' + repr(success_count) + (' pass' if success_count == 1 else ' passes')
            if some_failed:
                # collect up identical error messages so we can just give a count instead of repeating them
                fail_detail_counts = {}
                for x in this_test_failures:
                    fail_detail_counts[x] = fail_detail_counts[x] + 1 if x in fail_detail_counts else 1

                details = [ repr(count) + ": " +
                            # display commonest error messages first
                            message for message, count in sorted(fail_detail_counts.iteritems(),
                                                                 key = itemgetter(1),
                                                                 reverse=True) if message != None]

                cell_hover_text = cell_hover_text + '\nFailures:\n' + ('\n'.join(details))
            cell_text = [div(align='left')[repr(success_count)], div(align='right')[repr(fail_count)]]
            if some_passed or some_failed:
                cells.append(td(bgcolor=colour)
                             [a(href="results?build="+build_id+"&test_case="+test,
                                title=cell_hover_text)[cell_text]])
            else:
                cells.append(td[' '])
        rows.append([tr[cells]])

    passes_row = [th['Passes']]
    fails_row = [th['Fails']]

    for test_name in test_names:
        pass_count = total_passes_by_test[test_name] if test_name in total_passes_by_test else 0
        fail_count = total_fails_by_test[test_name] if test_name in total_fails_by_test else 0
        total = pass_count + fail_count
        colour_string = 'white' if total == 0 else rgb_string(fail_count, pass_count, 0, intensity=0.5)
        passes_row.append(td(bgcolor=colour_string)[repr(pass_count)])
        fails_row.append(td(bgcolor=colour_string)[repr(fail_count)])

    rows.insert(1, tr[fails_row])
    rows.insert(1, tr[passes_row])

    column_key = [ol[column_keys]]
    table_grid = [table(border='true', style="border-collapse: collapse", align="center", width="96%")[rows]]

    title_text = 'BVT results grid for '+branch

    if ('test_cases' in argsdict
        and argsdict['test_cases'] != None
        and argsdict['test_cases'] != ''):
        title_text += ' matching "' + argsdict['test_cases'] + '"'
    if ('exclude_cases' in argsdict
        and argsdict['exclude_cases'] != None
        and argsdict['exclude_cases'] != ''):
        title_text += ' excluding "' + argsdict['exclude_cases'] + '"'

    if request != None:
        requery_form = [ table(align="center",
                               width="96%",
                               bgcolor="#f0f0f0")[
                tr()[td()['Branch: ', stan_input(name='branch',
                                                 value=branch)['']],
                     td()['Test cases: ', stan_input(name='test_cases',
                                                     value=(argsdict['test_cases']
                                                            if 'test_cases' in argsdict
                                                            else ''))[''],
                          " ",
                          'Excluded cases: ', stan_input(name='exclude_cases',
                                                         value=(argsdict['exclude_cases']
                                                                if 'exclude_cases' in argsdict
                                                                else ''))[''],
                          " ",
                          'Case-significant search', stan_input(type='checkbox',
                                     name='case')['']],
                     td()['Include malformed results:', stan_input(type='checkbox',
                                                                   name='force')['']]],
                tr()[td()['Columns sort order: ',
                          stan_input(type='radio',
                                     name='sort_columns',
                                     value='alphabetic',
                                     ** ({'checked':1} if sort_columns == 'alphabetic' else {}))['alphabetic'],
                          " ",
                          stan_input(type='radio',
                                     name='sort_columns',
                                     value='frequency',
                                     ** ({'checked':1} if sort_columns == 'frequency' else {}))['frequency'],
                          " ",
                          stan_input(type='radio',
                                     name='sort_columns',
                                     value='ratio',
                                     ** ({'checked':1} if sort_columns == 'ratio' else {}))['ratio']],
                     td()['Max results:', stan_input(name='max_results',
                                                     value=max_results)['']],
                     td()[stan_input(type='submit')]]]]
    else:
        requery_form = None

    page_contents = [title[title_text],
                     h1[title_text]]
    page_contents += [p[key_text],
                      p[sort_text],
                      table_grid,
                      h2['column key'],
                      p[sort_text],
                      column_key]

    if not proportionate_colour:
        page_contents += [h2['cell key'],
                          key_table]

    page_contents += [hr(),
                      div(align = 'right')['produced at ', asctime()]]

    return str(nevow.flat.flatten(page_contents)), str(nevow.flat.flatten(requery_form))