def render_POST(self, request): uri = request.args.get('uri', []) if not uri or not tahoeRegex.match(uri[0]): return self.render_GET(request) ext = request.args.get('ext', []) b64uri = base64.urlsafe_b64encode(uri[0]) extension = '' if ext and ext[0]: extension = '.' + ext[0].lstrip('.') if uri[0] not in self.shortdb: while True: short = crockford.b32encode(os.urandom(9)).lower() if short not in self.shortdb: break self.shortdb[short] = uri[0] self.shortdb[uri[0]] = short self.shortdb.sync() else: short = self.shortdb[uri[0]] if request.args.get('api', []): return '/' + short + extension body = tags.p(tags.a('long url', href=b64uri + extension), '; ', tags.a('medium url', href='/' + uri[0] + extension), '; ', tags.a('short url', href=short + extension)) return renderElement(request, body)
def render_POST(self, request): uri = request.args.get('uri', []) if not uri or not tahoeRegex.match(uri[0]): return self.render_GET(request) ext = request.args.get('ext', []) b64uri = base64.urlsafe_b64encode(uri[0]) extension = '' if ext and ext[0]: extension = '.' + ext[0].lstrip('.') if uri[0] not in self.shortdb: while True: short = crockford.b32encode(os.urandom(9)).lower() if short not in self.shortdb: break self.shortdb[short] = uri[0] self.shortdb[uri[0]] = short self.shortdb.sync() else: short = self.shortdb[uri[0]] if request.args.get('api', []): return '/' + short + extension body = tags.p( tags.a('long url', href=b64uri + extension), '; ', tags.a('medium url', href='/' + uri[0] + extension), '; ', tags.a('short url', href=short + extension)) return renderElement(request, body)
def links(self, request, tag): ds = self.root.edits(self.ob) therange = range(len(ds)) rev = therange[self.rev] ul = tags.ul() for i in therange: li = tags.li() if i: u = URLPath.fromRequest(request) u = u.sibling('diff') u.query = urllib.urlencode({ 'ob': self.ob.fullName(), 'revA': i-1, 'revB': i, }) li(tags.a(href=str(u))("(diff)")) else: li("(diff)") li(" - ") if i == len(ds) - 1: label = "Latest" else: label = str(i) if i == rev: li(label) else: u = URLPath.fromRequest(request) u.query = urllib.urlencode({ 'rev': str(i), 'ob': self.ob.fullName(), }) li(tags.a(href=str(u))(label)) li(' - ' + ds[i].user + '/' + ds[i].time) ul(li) return tag(ul)
def render_feed(feed): feed_title = feed[u'feed'][u'title'] feed_link = feed[u'feed'][u'link'] return tags.table( tags.tr(tags.th(tags.a(feed_title, href=feed_link))))([ tags.tr( tags.td(tags.a(entry[u'title'], href=entry[u'link']))) for entry in feed[u'entries'] ])
def builder_row(self, bn, req, branches, num_builds): status = self.getStatus(req) builder = status.getBuilder(bn) state = builder.getState()[0] if state == 'building': state = 'idle' row = tags.tr() builderLink = path_to_builder(req, builder) row(tags.td(class_="box %s" % (state, ))(tags.a(href=builderLink)(bn))) builds = sorted([ build for build in builder.getCurrentBuilds() if set(map_branches(branches)) & builder._getBuildBranches(build) ], key=lambda build: build.getNumber(), reverse=True) builds.extend( builder.generateFinishedBuilds(map_branches(branches), num_builds=num_builds)) if builds: for b in builds: url = path_to_build(req, b) try: label = b.getProperty("got_revision") except KeyError: label = None # Label should never be "None", but sometimes # buildbot has disgusting bugs. if not label or label == "None" or len(str(label)) > 20: label = "#%d" % b.getNumber() if b.isFinished(): text = b.getText() else: when = b.getETA() if when: text = [ "%s" % (formatInterval(when), ), "%s" % (time.strftime( "%H:%M:%S", time.localtime(time.time() + when)), ) ] else: text = [] row( tags.td(align="center", bgcolor=_backgroundColors[b.getResults()], class_=("LastBuild box ", build_get_class(b)))([ (element, tags.br) for element in [tags.a(href=url)(label)] + text ])) else: row(tags.td(class_="LastBuild box")("no build")) return row
def getAuthedLink(self, account): return tags.span(tags.a(tags.span(account.getDisplayName(), class_="persona-link-text"), href="/members/account", class_="account-link"), " | ", tags.a(tags.span("Sign out", class_="persona-link-text"), href="#logout", id="persona-logout-link"), id="member-links")
def getAuthedLink(self, account): return tags.span( tags.a( tags.span( account.getDisplayName(), class_="persona-link-text"), href="/members/account", class_="account-link"), " | ", tags.a( tags.span("Sign out", class_="persona-link-text"), href="#logout", id="persona-logout-link"), id="member-links")
def builder_row(self, bn, req, branches, num_builds): status = self.getStatus(req) builder = status.getBuilder(bn) state = builder.getState()[0] if state == 'building': state = 'idle' row = tags.tr() builderLink = path_to_builder(req, builder) row(tags.td(class_="box %s" % (state,)) (tags.a(href=builderLink)(bn))) builds = sorted([ build for build in builder.getCurrentBuilds() if set(map_branches(branches)) & builder._getBuildBranches(build) ], key=lambda build: build.getNumber(), reverse=True) builds.extend(builder.generateFinishedBuilds( map_branches(branches), num_builds=num_builds)) if builds: for b in builds: url = path_to_build(req, b) try: label = b.getProperty("got_revision") except KeyError: label = None # Label should never be "None", but sometimes # buildbot has disgusting bugs. if not label or label == "None" or len(str(label)) > 20: label = "#%d" % b.getNumber() if b.isFinished(): text = b.getText() else: when = b.getETA() if when: text = [ "%s" % (formatInterval(when),), "%s" % (time.strftime( "%H:%M:%S", time.localtime(time.time() + when)),) ] else: text = [] row(tags.td( align="center", bgcolor=_backgroundColors[b.getResults()], class_=("LastBuild box ", build_get_class(b)))([ (element, tags.br) for element in [tags.a(href=url)(label)] + text])) else: row(tags.td(class_="LastBuild box")("no build")) return row
def footer_right(self, request, tag): """ '(c) 2014-2016 ', tags.a('Open Hive', href='http://open-hive.org/'), ' and ', tags.a('Hiveeyes', href='https://hiveeyes.org/docs/system/'), '. ', """ return tag(tags.p( 'Powered by ', tags.a('Kotori', href='https://getkotori.org/'), ', ', tags.a('InfluxDB', href='https://github.com/influxdata/influxdb'), ', ', tags.a('dygraphs', href='http://dygraphs.com/'), ' and ', tags.a('DataTables', href='https://datatables.net/'), '.' ))
def maybeShortenList(system, label, lst, idbase): lst2 = [] for name in lst: o = system.allobjects.get(name) if o is None or o.isVisible: lst2.append(name) lst = lst2 if not lst: return None def one(item): if item in system.allobjects: return taglink(system.allobjects[item]) else: return item def commasep(items): r = [] for item in items: r.append(one(item)) r.append(', ') del r[-1] return r p = [label] if len(lst) <= 5 or not system.options.htmlshortenlists: p.extend(commasep(lst)) else: p.extend(commasep(lst[:3])) q = [', '] q.extend(commasep(lst[3:])) q.append( tags.span(class_='showIfJS') [' ', tags.a(href="#", onclick="showAndHide('%s');" % idbase, class_="jslink")['(hide last %d again)' % len(lst[3:])]]) p.append(tags.span(id=idbase, class_='hideIfJS')[q]) p.append( tags.span( id=idbase + 'Link', class_='showIfJS')[' ', tags.a(href="#", onclick="hideAndShow('%s');" % idbase, class_="jslink")['... and %d more' % len(lst[3:])]]) return p
def getSignInLink(self): return tags.span(tags.a(tags.span("Persona Sign-in", class_="persona-link-text"), href="#login", id="persona-login-link", class_="persona-button dark"), id="persona-login")
def checkTagAttributeSerialization( self, wrapTag: Callable[[Tag], Flattenable]) -> None: """ Common implementation of L{test_serializedAttributeWithTag} and L{test_serializedAttributeWithDeferredTag}. @param wrapTag: A 1-argument callable that wraps around the attribute's value so other tests can customize it. @type wrapTag: callable taking L{Tag} and returning something flattenable """ innerTag = tags.a('<>&"') outerTag = tags.img(src=wrapTag(innerTag)) outer = self.assertFlattensImmediately( outerTag, b'<img src="<a>&lt;&gt;&amp;"</a>" />', ) inner = self.assertFlattensImmediately(innerTag, b'<a><>&"</a>') # Since the above quoting is somewhat tricky, validate it by making sure # that the main use-case for tag-within-attribute is supported here: if # we serialize a tag, it is quoted *such that it can be parsed out again # as a tag*. self.assertXMLEqual(XML(outer).attrib["src"], inner)
def getSignInLink(self): return tags.span( tags.a( tags.span("Persona Sign-in", class_="persona-link-text"), href="#login", id="persona-login-link", class_="persona-button dark"), id="persona-login")
def generateTabsAndContent(results): """ results is a dictionary whose keys are normalized ASCII chars and whose values are the original (possible unicode) chars that map to the ASCII ones. """ tabs = [] contents = [] for asciiLetter in sorted(results.keys()): if not asciiLetter: continue for letter in sorted(results[asciiLetter]): tab = tags.li( tags.a(letter.upper(), href="#l%s" % letter, **{"data-toggle": "tab"})) tabs.append(tab) content = tags.div(tags.p("holding content"), class_="tab-pane", id="l%s" % letter) contents.append(content) return tags.div(tags.ul(tabs, class_="nav nav-tabs"), tags.div(contents, class_="tab-content"), class_="tabbable tabs-left")
def getCopyright(self): year = meta.startingYear thisYear = datetime.now().year mailTo = "mailto:%s" % config.salesEmail if thisYear > year: year = "%s - %s" % (year, thisYear) return ("© %s " % year, tags.a(meta.author, href=mailTo))
async def _events(self, request: IRequest, tag: Tag, reverse_order: bool = False) -> KleinRenderable: if reverse_order: def order(i: Iterable) -> Iterable: return reversed(sorted(i)) else: def order(i: Iterable) -> Iterable: return sorted(i) authorizationsForUser = partial( self.config.authProvider.authorizationsForUser, request.user) relevantAuthorizations = (Authorization.readIncidents | Authorization.writeIncidentReports) eventIDs = order([ event.id for event in await self.config.store.events() if relevantAuthorizations & await authorizationsForUser(event) ]) if eventIDs: eventPage = self.config.urls.viewEvent.asText() return (tag.clone()(tags.a(eventID, href=eventPage.replace( "<eventID>", eventID))) for eventID in eventIDs) else: return tag("No events found.")
def extras(self) -> List["Flattenable"]: r = super().extras() sourceHref = util.srclink(self.ob) source: "Flattenable" if sourceHref: source = (" ", tags.a("(source)", href=sourceHref, class_="sourceLink")) else: source = tags.transparent r.append( tags.p( tags.code(tags.span("class", class_='py-keyword'), " ", tags.span(self.ob.name, class_='py-defname'), self.classSignature(), ":", source))) scs = sorted(self.ob.subclasses, key=objects_order) if not scs: return r p = assembleList(self.ob.system, "Known subclasses: ", [o.fullName() for o in scs], "moreSubclasses", self.page_url) if p is not None: r.append(tags.p(p)) return r
def generateTabsAndContent(results): """ results is a dictionary whose keys are normalized ASCII chars and whose values are the original (possible unicode) chars that map to the ASCII ones. """ tabs = [] contents = [] for asciiLetter in sorted(results.keys()): if not asciiLetter: continue for letter in sorted(results[asciiLetter]): tab = tags.li( tags.a( letter.upper(), href="#l%s" % letter, **{"data-toggle": "tab"}) ) tabs.append(tab) content = tags.div( tags.p("holding content"), class_="tab-pane", id="l%s" % letter) contents.append(content) return tags.div( tags.ul(tabs, class_="nav nav-tabs"), tags.div(contents, class_="tab-content"), class_="tabbable tabs-left")
def formatPrincipals(principals): """ Format a list of principals into some twisted.web.template DOM objects. """ def recordKey(principal): try: record = principal.record except AttributeError: try: record = principal.parent.record except: return None return (record.recordType, record.shortNames[0]) def describe(principal): if hasattr(principal, "record"): return " - %s" % (principal.record.fullName,) else: return "" return formatList( tags.a(href=principal.principalURL())( str(principal), describe(principal) ) for principal in sorted(principals, key=recordKey) )
def formatPrincipals(principals): """ Format a list of principals into some twisted.web.template DOM objects. """ def recordKey(principal): try: record = principal.record except AttributeError: try: record = principal.parent.record except: return None try: shortName = record.shortNames[0] except AttributeError: shortName = u"" return (record.recordType, shortName) def describe(principal): if hasattr(principal, "record"): return " - %s" % (principal.record.displayName, ) else: return "" return formatList( tags.a( href=principal.principalURL())(str(principal), describe(principal)) for principal in sorted(principals, key=recordKey))
def plugin(self, request, tag): plugins = [] for name in self.plugins.keys(): plugins.append( tags.li( tags.a(name.title(), href='%s/%s' % (self.factory.name, name)))) return tag(tags.h2("Plugins"), tags.ul(*plugins))
def hist(self, data, request): u = URLPath.fromRequest(request) u = u.sibling('diff') u.query = urllib.urlencode({ 'ob': data.obj.fullName(), 'rev': data.rev, }) return tags.a(href=str(u))("(hist)")
def _render_si_link(self, req, storage_index): si_s = base32.b2a(storage_index) ophandle = req.prepath[-1] target = "%s/operations/%s/%s" % (get_root(req), ophandle, si_s) output = get_arg(req, "output") if output: target = target + "?output=%s" % output return tags.a(si_s, href=target)
def extras(self): r = super().extras() sourceHref = util.srclink(self.ob) if sourceHref: r.append(tags.a("(source)", href=sourceHref, class_="sourceLink")) return r
def _showDirectory(self, request, dirinfo): children = dirinfo[1]['children'] body = tags.ul(*[ tags.li(tags.a(name + ('/' if info[0] == 'dirnode' else ''), href='/' + info[1]['ro_uri'])) for name, info in children.iteritems() ]) renderElement(request, body)
def _render_si_link(self, req, storage_index): si_s = str(base32.b2a(storage_index), "utf-8") ophandle = str(req.prepath[-1], "utf-8") target = "%s/operations/%s/%s" % (get_root(req), ophandle, si_s) output = get_arg(req, "output") if output: target = target + "?output=" + str(output, "utf-8") return tags.a(si_s, href=target)
def mirror(self, request, tag): if 'mirror' in request.var and request.var['mirror'] != '': url = "https://%s.%s%s" % (request.var['onion'], request.var['mirror'], request.var['path']) return [ "This page is accessible also on the following random mirror: " ], tags.a(href=url, title=url)(request.var['mirror']) return ""
def stanForOb(self, ob, summary=False): current_docstring = self.currentDocstringForObject(ob) if summary: return epydoc2stan.doc2stan( ob.doctarget, summary=True, docstring=current_docstring)[0] r = [tags.div(epydoc2stan.doc2stan(ob.doctarget, docstring=current_docstring)[0]), tags.a(href="edit?ob="+ob.fullName())("Edit"), " "] if ob.doctarget in self.editsbyob: r.append(tags.a(href="history?ob="+ob.fullName())( "View docstring history (", str(len(self.editsbyob[ob.doctarget])), " versions)")) else: r.append(tags.span(class_='undocumented')("No edits yet.")) return r
def filename_link(f): if len(f) > 0: t = tags.a(f) t.attributes[ 'href'] = 'http://www.scewpt.com/' + self.broadcast_dict[ 'file_dest'] + "_" + f return t else: return f
def _showDirectory(self, request, dirinfo): children = dirinfo[1]['children'] body = tags.ul(*[ tags.li( tags.a(name + ('/' if info[0] == 'dirnode' else ''), href='/' + info[1]['ro_uri'])) for name, info in children.iteritems() ]) renderElement(request, body)
def _handle_name(self, identifier: str) -> Tag: url = self.linker.resolve_identifier(identifier) tag: Tag if url is None: tag = tags.transparent(identifier) else: tag = tags.a(identifier, href=url, class_='code') return tag
def lineno(self, request, tag): if not self.has_lineno_col: return () if hasattr(self.child, 'linenumber'): line = str(self.child.linenumber) if self.child.sourceHref: line = tags.a(href=self.child.sourceHref)(line) return tag.clear()(line) else: return ()
def getDropdown(self, title, url, cssClass): elements = [] if title == "About": links = urls.aboutDropDown for text, url, type in links: if type == const.DIVIDER: element = tags.li(class_="divider") elif type == const.HEADER: element = tags.li(text, class_="nav-header") else: element = tags.li(tags.a(text, href=url)) elements.append(element) return tags.li(tags.a(title, tags.b(class_="caret"), href="#", class_="dropdown-toggle", **{"data-toggle": "dropdown"}), tags.ul(elements, class_="dropdown-menu"), class_=cssClass)
def getDropdown(self, title, url, cssClass): elements = [] if title == "About": links = urls.aboutDropDown for text, url, type in links: if type == const.DIVIDER: element = tags.li(class_="divider") elif type == const.HEADER: element = tags.li(text, class_="nav-header") else: element = tags.li(tags.a(text, href=url)) elements.append(element) return tags.li( tags.a( title, tags.b(class_="caret"), href="#", class_="dropdown-toggle", **{"data-toggle": "dropdown"}), tags.ul(elements, class_="dropdown-menu"), class_=cssClass)
def dictionaries(self, request, tag): """ """ elements = [] for dictionary in const.dictionaries: name = utils.getDictionaryName(dictionary) url = const.urls["dictionary"].replace( const.urlParams["dictionary"], dictionary) elements.append(tags.li(tags.a(name, href=url))) return tag(elements)
def linkTag(self, time, arrowDirection, hidden=False): style = LINK_STYLE if hidden: style += ' visibility: hidden;' return tags.a(style=style, href="?time=%s" % (time.asDatetime().strftime('%Y-%m-%d'), ))(tags.img( border="0", src="static/%s-arrow.png" % (arrowDirection, ), ))
def from_dashboard(cls, dashboard): url = '/%s' % (dashboard.config['name']) if 'share_id' in dashboard.config: shared_url = '/shared/%s' % dashboard.config['share_id'] shared_url_tag = tags.a(shared_url, href=shared_url) else: shared_url_tag = '' return cls(dashboard.config['title'], url, shared_url_tag)
def maybeShortenList(system, label, lst, idbase): lst2 = [] for name in lst: o = system.allobjects.get(name) if o is None or o.isVisible: lst2.append(name) lst = lst2 if not lst: return None def one(item): if item in system.allobjects: return taglink(system.allobjects[item]) else: return item def commasep(items): r = [] for item in items: r.append(one(item)) r.append(', ') del r[-1] return r p = [label] if len(lst) <= 5 or not system.options.htmlshortenlists: p.extend(commasep(lst)) else: p.extend(commasep(lst[:3])) q = [', '] q.extend(commasep(lst[3:])) q.append(tags.span(class_='showIfJS')[ ' ', tags.a(href="#", onclick="showAndHide('%s');"%idbase, class_="jslink") ['(hide last %d again)'%len(lst[3:])]]) p.append(tags.span(id=idbase, class_='hideIfJS')[q]) p.append(tags.span(id=idbase+'Link', class_='showIfJS')[ ' ', tags.a(href="#", onclick="hideAndShow('%s');"%idbase, class_="jslink") ['... and %d more'%len(lst[3:])]]) return p
def taglink(o: model.Documentable, label: Optional[str] = None) -> Tag: if not o.isVisible: o.system.msg("html", "don't link to %s" % o.fullName()) if label is None: label = o.fullName() # Create a link to the object, with a "data-type" attribute which says what # kind of object it is (class, etc). This helps doc2dash figure out what it # is. ret: Tag = tags.a(href=o.url, class_="code", **{"data-type": o.kind})(label) return ret
def dictionaries(self, request, tag): """ """ elements = [] for dictionary in const.dictionaries: name = utils.getDictionaryName(dictionary) url = const.urls["dictionary"].replace( const.urlParams["dictionary"], dictionary) elements.append( tags.li(tags.a(name, href=url))) return tag(elements)
def letterlinks(self, request, tag): letterlinks = [] for initial in sorted(self.initials): if initial == self.my_letter: letterlinks.append(initial) else: letterlinks.append(tags.a(href='#' + initial)(initial)) letterlinks.append(' - ') if letterlinks: del letterlinks[-1] return tag(letterlinks)
def letterlinks(self, request, tag): letterlinks = [] for initial in sorted(self.initials): if initial == self.my_letter: letterlinks.append(initial) else: letterlinks.append(tags.a(href='#'+initial)(initial)) letterlinks.append(' - ') if letterlinks: del letterlinks[-1] return tag(letterlinks)
def render_GET(self, request): applications = [] for app in self.registry.applications.values(): link = tags.a(tags.tt(app.name), ' at ', tags.tt(app.path.path), href=app.name) applications.append(tags.li(link)) body = tags.body( tags.p('Here are your applications:'), tags.ul(*applications)) return renderElement(request, body)
def getLinks(self, request): elements = [] for text, url, type in self.navLinks: cssClass = "" if self.isInSection(request, url): cssClass = "active" if type == const.DROPDOWN: cssClass += " dropdown" element = self.getDropdown(text, url, cssClass) else: element = tags.li(tags.a(text, href=url), class_=cssClass) elements.append(element) return elements
def test_serializedAttributeWithTagWithAttribute(self): """ Similar to L{test_serializedAttributeWithTag}, but for the additional complexity where the tag which is the attribute value itself has an attribute value which contains bytes which require substitution. """ flattened = self.assertFlattensImmediately( tags.img(src=tags.a(href='<>&"')), '<img src="<a href=' ""&lt;&gt;&amp;&quot;">" '</a>" />', ) # As in checkTagAttributeSerialization, belt-and-suspenders: self.assertXMLEqual(XML(flattened).attrib["src"], '<a href="<>&""></a>')
def navLinks(self, request, tag): """ """ currentPath = request.path links = const.topNavLinks elements = [] for text, url in links: cssClass = "" if url == currentPath: cssClass = "active" elements.append( tags.li(tags.a(text, href=url), class_=cssClass), ) return tag(elements)
def getLinks(self, request): elements = [] for text, url, type in self.sidebarLinks: if type == const.DIVIDER: continue if type == const.HEADER: elements.append( tags.li(text, class_="nav-header")) continue cssClass = "" if self.isInSubSection(request, url): cssClass = "active" elements.append( tags.li(tags.a(text, href=url), class_=cssClass)) return elements
def subclassesFrom(hostsystem, cls, anchors): r = tags.li() name = cls.fullName() if name not in anchors: r(tags.a(name=name)) anchors.add(name) r(taglink(cls), ' - ', epydoc2stan.doc2stan(cls, summary=True)[0]) scs = [sc for sc in cls.subclasses if sc.system is hostsystem and ' ' not in sc.fullName() and sc.isVisible] if len(scs) > 0: ul = tags.ul() for sc in sorted(scs, key=_lckey): ul(subclassesFrom(hostsystem, sc, anchors)) r(ul) return r
def taglink(o, label=None): if not o.isVisible: o.system.warning("html", "don't link to %s"%o.fullName()) if label is None: label = o.fullName() if o.documentation_location == model.DocLocation.PARENT_PAGE: p = o.parent if isinstance(p, model.Module) and p.name == '__init__': p = p.parent linktext = link(p) + '#' + urllib.quote(o.name) elif o.documentation_location == model.DocLocation.OWN_PAGE: linktext = link(o) else: raise AssertionError( "Unknown documentation_location: %s" % o.documentation_location) return tags.a(href=linktext)(label)
def taglink(o, label=None): if not o.isVisible: o.system.warning("html", "don't link to %s"%o.fullName()) if label is None: label = o.fullName() if o.documentation_location == model.DocLocation.PARENT_PAGE: p = o.parent if isinstance(p, model.Module) and p.name == '__init__': p = p.parent linktext = link(p) + '#' + urllib.quote(o.name) elif o.documentation_location == model.DocLocation.OWN_PAGE: linktext = link(o) else: raise AssertionError( "Unknown documentation_location: %s" % o.documentation_location) # Create a link to the object, with a "data-type" attribute which says what # kind of object it is (class, etc). This helps doc2dash figure out what it # is. return tags.a(href=linktext, class_="code", **{"data-type":o.kind})(label)
def tags(self, tag): first = self.store.findFirst(Post, Post.thread == self) if first is None: return tag(u"Empty thread") else: subject = u"%s - %s [" % (first.author, self.subject) link = tags.a("Reply", href="#") header = tags.header(subject, link, "]") post = first.tags(tags.div) # Retrieve posts and reverse them twice, to avoid having to get # the length of the table. others = self.store.query(Post, Post.thread == self, limit=4, sort=Post.number.descending) posts = [p.tags(tags.div) for p in others if p is not first] posts.reverse() return tag(header, post, *posts)
def checkTagAttributeSerialization(self, wrapTag): """ Common implementation of L{test_serializedAttributeWithTag} and L{test_serializedAttributeWithDeferredTag}. @param wrapTag: A 1-argument callable that wraps around the attribute's value so other tests can customize it. @param wrapTag: callable taking L{Tag} and returning something flattenable """ innerTag = tags.a('<>&"') outerTag = tags.img(src=wrapTag(innerTag)) outer = self.assertFlattensImmediately( outerTag, '<img src="<a>&lt;&gt;&amp;"</a>" />' ) inner = self.assertFlattensImmediately(innerTag, '<a><>&"</a>') # Since the above quoting is somewhat tricky, validate it by making sure # that the main use-case for tag-within-attribute is supported here: if # we serialize a tag, it is quoted *such that it can be parsed out again # as a tag*. self.assertXMLEqual(XML(outer).attrib["src"], inner)
def renderHTML(self, details, organizer, attendees, canceled): """ Render HTML message part based on invitation details and a flag indicating whether the message is a cancellation. @return: html text (C{str}, representing utf-8 encoded bytes)). """ orgCN, orgEmail = organizer # TODO: htmlAttendees needs to be a separate element with a separate # template fragment. Luckily that fragment is the same regardless # of the rest of the template. htmlAttendees = [] first = True for cn, mailto in attendees: if not first: htmlAttendees.append(u", ") else: first = False if mailto: if not cn: cn = mailto htmlAttendees.append( tags.a(href="mailto:%s" % (mailto,))(cn) ) else: htmlAttendees.append(cn) details['htmlAttendees'] = htmlAttendees # TODO: htmlOrganizer is also some HTML that requires additional # template stuff, and once again, it's just a 'mailto:'. # tags.a(href="mailto:"+email)[cn] if orgEmail: details['htmlOrganizer'] = tags.a(href="mailto:%s" % (orgEmail,))( orgCN) else: details['htmlOrganizer'] = orgCN templateDir = config.Scheduling.iMIP.MailTemplatesDirectory.rstrip("/") templateName = "cancel.html" if canceled else "invite.html" templatePath = os.path.join(templateDir, templateName) if not os.path.exists(templatePath): # Fall back to built-in simple templates: if canceled: htmlTemplate = htmlCancelTemplate else: htmlTemplate = htmlInviteTemplate else: # HTML template file exists with open(templatePath) as templateFile: htmlTemplate = templateFile.read() class EmailElement(Element): loader = StringFormatTemplateLoader(lambda : StringIO(htmlTemplate), "email") @renderer def email(self, request, tag): return tag.fillSlots(**details) textCollector = [] flattenString(None, EmailElement()).addCallback(textCollector.append) htmlText = textCollector[0] return htmlText
app = Klein() myStyle = Plating( tags=tags.html( tags.head(tags.title(slot("pageTitle"))), tags.body(tags.h1(slot("pageTitle"), Class="titleHeading"), tags.div(slot(Plating.CONTENT))) ), defaults={"pageTitle": "Places & Foods"} ) @myStyle.routed( app.route("/"), tags.div( tags.h2("Sample Places:"), tags.ul([tags.li(tags.a(href=["/places/", place])(place)) for place in ["new york", "san francisco", "shanghai"]]), tags.h2("Sample Foods:"), tags.ul([tags.li(tags.a(href=["/foods/", food])(food)) for food in ["hamburgers", "cheeseburgers", "hot dogs"]]), )) def root(request): return {} @myStyle.routed(app.route("/foods/<food>"), tags.table(border="2", style="color: blue")( tags.tr(tags.td("Name:"), tags.td(slot("name"))), tags.tr(tags.td("Deliciousness:"), tags.td(slot("rating"), " stars")), tags.tr(tags.td("Carbs:"), tags.td(slot("carbohydrates")))))