def mark_deliv_match(highlighted_text): result = re.sub( r"(?:<[^/][^>]*>)*<.*?DELIVERANCE-MATCH=.*?>(?:</[^>]*>)*", lambda match: r'<b style="background-color: #ff8">%s</b>' % match.group(0), unicode(highlighted_text), re.S, ) return html(result)
def log_description(self, log=None): """ A text description of this rule, for use in log messages and errors """ def linked_item(url, body, source=None, line=None, selector=None): """Creates a link, if we have a log context""" body = html_quote(body) if log is None or url is None: return body link = log.link_to(url, source=source, line=line, selector=selector) return '<a href="%s" target="_blank">%s</a>' % (html_quote(link), body) if log: request_url = log.request.url else: request_url = None parts = ['<%s' % linked_item(self.source_location, self.name, source=True)] if getattr(self, 'content', None): body = 'content="%s"' % html_quote(self.content) if getattr(self, 'content_href', None): if request_url: content_url = urlparse.urljoin(request_url, self.content_href) else: content_url = self.content_href else: content_url = request_url parts.append(linked_item(content_url, body, selector=self.content)) if getattr(self, 'content_href', None): dest = self.content_href if request_url: dest = urlparse.urljoin(request_url, dest) body = 'href="%s"' % html_quote(self.content_href) parts.append(linked_item(dest, body, source=True)) if self.move_supported and not getattr(self, 'move', False): parts.append('move="0"') v = getattr(self, 'nocontent', 'warn') if v != 'warn': parts.append(self.format_error('nocontent', v)) v = getattr(self, 'manycontent', ('warn', None)) if v != ('warn', 'first'): parts.append(self.format_error('manycontent', v)) if getattr(self, 'theme', None): body = 'theme="%s"' % html_quote(self.theme) theme_url = getattr(log, 'theme_url', None) parts.append(linked_item(theme_url, body, selector=self.theme)) v = getattr(self, 'notheme', 'warn') if v != 'warn': parts.append(self.format_error('notheme', v)) v = getattr(self, 'manytheme', ('warn', None)) if v != ('warn', 'first'): parts.append(self.format_error('manytheme', v)) ## FIXME: add source_location return html(' '.join(parts) + ' />')
def rst2html(in_path): try: rst, = glob.glob(os.path.join(in_path, '*.rst')) except ValueError: raise RuntimeError("Found more than one input .rst--not sure which " "one to use.") content = open(rst, 'r').read() settings = { } html_parts = dc.publish_parts(source=content, writer=Writer(), settings_overrides=settings) return tempita.html(html_parts['html_body'].encode('utf-8'))
def highlight(html_code): """Highlights the given code (for use in the template)""" if isinstance(html_code, _Element): html_code = tostring(html_code) return html(pygments_highlight(html_code, HtmlLexer(), HtmlFormatter(noclasses=True)))
def to_json(obj): return tempita.html(json.dumps(obj, sort_keys=True))
def mark_deliv_match(highlighted_text): result = re.sub( r'(?:<[^/][^>]*>)*<.*?DELIVERANCE-MATCH=.*?>(?:</[^>]*>)*', lambda match: r'<b style="background-color: #ff8">%s</b>' % match.group(0), unicode(highlighted_text), re.S) return html(result)
def json(obj): return tempita.html(json.dumps(obj))
def addnbsp(str): return tempita.html(cgi.escape(str).replace(" ", " ").decode("utf-8").encode('ascii', 'xmlcharrefreplace'))
def addbr(str): return tempita.html(cgi.escape(str).replace("\n", "<br />").decode("utf-8").encode('ascii', 'xmlcharrefreplace'))
class SavingLogger(object): """ Logger that saves all its messages locally. """ def __init__(self, request, middleware): self.messages = [] self.middleware = middleware self.request = request # This is writable: self.theme_url = None # Also writable (list of (url, name)) self.edit_urls = [] def message(self, level, el, msg, *args, **kw): """Add one message at the given log level""" if args: msg = msg % args elif kw: msg = msg % kw self.messages.append((level, el, msg)) return msg def debug(self, el, msg, *args, **kw): """Log at the DEBUG level""" return self.message(logging.DEBUG, el, msg, *args, **kw) def info(self, el, msg, *args, **kw): """Log at the INFO level""" return self.message(logging.INFO, el, msg, *args, **kw) def notify(self, el, msg, *args, **kw): """Log at the NOTIFY level""" return self.message(NOTIFY, el, msg, *args, **kw) def warn(self, el, msg, *args, **kw): """Log at the WARN level""" return self.message(logging.WARN, el, msg, *args, **kw) warning = warn def error(self, el, msg, *args, **kw): """Log at the ERROR level""" return self.message(logging.ERROR, el, msg, *args, **kw) def fatal(self, el, msg, *args, **kw): """Log at the FATAL level""" return self.message(logging.FATAL, el, msg, *args, **kw) def finish_request(self, req, resp): """Called by the middleware at the end of the request. This gives the log an opportunity to add information to the page. """ if 'deliv_log' in req.GET and display_logging(req): resp.body += self.format_html_log() resp.cache_expires() return resp log_template = HTMLTemplate( '''\ <H1 style="border-top: 3px dotted #f00">Deliverance Information</h1> <div> {{if log.theme_url}} <a href="{{theme_url}}" target="_blank">theme</a> {{else}} theme: no theme set {{endif}} | <a href="{{unthemed_url}}" target="_blank">unthemed content</a> | <a href="{{content_source}}" target="_blank">content source</a> | <a href="{{content_browse}}" target="_blank">browse content</a> / <a href="{{theme_browse}}" target="_blank">theme</a> {{if log.edit_urls}} | <select onchange="if (this.value) {window.open(this.value, '_blank')}; this.selectedIndex=0;"> <option value="">edit location</option> {{for url, name in log.edit_urls}} <option value="{{url}}">{{name}}</option> {{endfor}} </select> {{endif}} {{if edit_rules}} | <a href="{{edit_rules}}" target="_blank">edit rules</a> {{endif}} </div> {{if log.messages}} {{div}} {{h2}}Log</h2> {{div_inner}} <table> <tr> <th>Level</th><th>Message</th><th>Context</th> </tr> {{for level, level_name, el, message in log.resolved_messages():}} {{py:color, bgcolor = log.color_for_level(level)}} <tr style="color: {{color}}; background-color: {{bgcolor}}; vertical-align: top"> {{td}}{{level_name}}</td> {{td}}{{message}}</td> {{td}}{{log.obj_as_html(el) | html}}</td> </tr> {{endfor}} </table> </div></div> {{else}} {{h2}}No Log Messages</h2> {{endif}} ''', name='deliverance.log.SavingLogger.log_template') tags = dict( h2=html( '<h2 style="color: #000; background-color: #f90; margin-top: 0; ' 'border-bottom: 1px solid #630">'), div=html('<div style="border: 2px solid #000; margin-bottom: 1em">'), div_inner=html('<div style="padding: 0.25em">'), td=html('<td style="margin-bottom: 0.25em; ' 'border-bottom: 1px solid #ddd; padding-right: 0.5em">'), ) def format_html_log(self): """Formats this log object as HTML""" content_source = self.link_to(self.request.url, source=True) content_browse = self.link_to(self.request.url, browse=True) theme_browse = self.link_to(self.theme_url, browse=True) if edit_local_files(self.request.environ): ## FIXME: also test for the local-ness of the file edit_rules = (self.request.environ['deliverance.base_url'] + '/.deliverance/edit_rules') else: edit_rules = None return self.log_template.substitute( log=self, middleware=self.middleware, unthemed_url=self._add_notheme(self.request.url), theme_url=self._add_notheme(self.theme_url), content_source=content_source, content_browse=content_browse, theme_browse=theme_browse, edit_rules=edit_rules, **self.tags) def _add_notheme(self, url): """Adds the necessary query string argument to the URL to suppress theming""" if url is None: return None if '?' in url: url += '&' else: url += '?' return url + 'deliv_notheme' def resolved_messages(self): """ Yields a list of ``(level, level_name, context_el, rendered_message)`` """ for level, el, msg in self.messages: level_name = logging.getLevelName(level) yield level, level_name, el, msg def obj_as_html(self, el): """ Returns the object formatted as HTML. This is used to show the context in log messages. """ ## FIXME: another magic method? if hasattr(el, 'log_description'): return el.log_description(self) elif isinstance(el, _Element): return html_quote(tostring(el)) else: return html_quote(str(el)) def color_for_level(self, level): """ The HTML foreground/background colors for a given level. """ return { logging.DEBUG: ('#666', '#fff'), logging.INFO: ('#333', '#fff'), NOTIFY: ('#000', '#fff'), logging.WARNING: ('#600', '#fff'), logging.ERROR: ('#fff', '#600'), logging.CRITICAL: ('#000', '#f33') }[level] def link_to(self, url, source=False, line=None, selector=None, browse=False): """ Gives a link to the given source view (just routes to `deliverance.middleware.DeliveranceMiddleware.link_to`). """ return self.middleware.link_to(self.request, url, source=source, line=line, selector=selector, browse=browse)
def to_json(obj): return tempita.html(json.dumps(obj, sort_keys=True, default=parse_json))