def setup_smileys_replacement(document_tree, base_url, emoticons_map=DEFAULT_EMOTICONS_MAP, html_class='emoticons'): """ Setup the document for emoticons replacement. :param document_tree: The document tree instance to be setup. :param emoticons_map: A tuple of tuple with two values ``(emoticon_text, emoticon_filename)``. :param base_url: The base URL for all emoticon images. Can also be a callable for dynamic paths. :param html_class: The HTML class to be assigned to each emoticons img tag (optional). """ assert document_tree, "Document tree is mandatory." assert document_tree.is_root, "Document tree must be a root tree node instance." assert base_url, "Base URL is mandatory." # Craft the emoticons regex emoticons_regex = r'(^|\s+)(?P<emoticon>%s)(\s+|$)' % '|'.join([re.escape(escape_html(e)) for e, _ in emoticons_map]) emoticons_regex = re.compile(emoticons_regex) # Turn emoticons map into a dictionary # Note: use escape_html(k) as key because at rendering, when the ``do_smileys_replacement`` routine is called # emoticons are already HTML-encoded. As we need to inject HTML code for img, we can't do the replacement when # the emoticons are in plain text. emoticons_map = {escape_html(k): v for k, v in emoticons_map} # Helper method to turn ``base_url`` into a callable if necessary def build_url(filename): return urljoin(base_url, filename) # Store all emoticons related options document_tree.attrs[EMOTICONS_MAP_ATTR_NAME] = emoticons_map document_tree.attrs[EMOTICONS_REGEX_ATTR_NAME] = emoticons_regex document_tree.attrs[EMOTICONS_BASE_URL_ATTR_NAME] = build_url if isinstance(base_url, str) else base_url document_tree.attrs[EMOTICONS_HTML_CLASS_ATTR_NAME] = html_class
def format_html_par(self, leading_html, message_html, trailer_html, record): """ Wraps the given leading HTML code and the given message HTML code into an HTML `<p>` element that will represent the main part of the log record. Both `leading_html` and `message_html` arguments are assumed to be already properly HTML-escaped. """ css_par_style = self._find_which_from_level(record.levelno, self.css_par_styles) css_message_style = self._find_which_from_level( record.levelno, self.css_message_styles) if leading_html: final_separator = self._find_which_from_level( record.levelno, self.leading_final_separators) else: final_separator = '' return \ ('''<p style="margin:0pt;{css_par_style_html}">{leading_html}{maybe_leading_separator}''' '''<span style="{css_message_style_html}">{message_html}</span>{trailer_html}</p>\n''').format( css_par_style_html=escape_html(css_par_style), leading_html=leading_html, maybe_leading_separator=final_separator, css_message_style_html=escape_html(css_message_style), message_html=message_html, trailer_html=trailer_html )
def render_error_html(self, inner_html, html_error_template, **kwargs): """ Callback function for rendering HTML when the node is erroneous. :param inner_html: The inner HTML of this tree node. :param html_error_template: The HTML template for rendering the erroneous parts of the output. :param kwargs: Extra keyword arguments for rendering. :return The rendered HTML of this node. """ output_html = [] if self.source_open_tag: output_html.append( html_error_template.format(error_message=self.error_message, source=escape_html( self.source_open_tag))) inner_content = inner_html or escape_html(self.get_raw_content()) if inner_content: output_html.append(inner_content) if self.source_close_tag: output_html.append( html_error_template.format(error_message=self.error_message, source=escape_html( self.source_close_tag))) return '\n'.join(output_html)
def format_html_leading_multiprocessid(self, record): p = multiprocessing.current_process() if p is None: return "" if p.name == 'MainProcess': # we are the main process -- don't display anything here return "" m = self.rx_process_name.match(p.name) if m is not None: if callable(self.rx_process_format): return escape_html(self.rx_process_format(m)) return escape_html(m.expand(self.rx_process_format)) return escape_html(p.name)
def format_html_leading_time(self, record): """ Return the formatted time corresponding to the time the log record was emitted. Returns an empty string if :py:attr:`use_time` is `False`. This method is meant to be a possible leading part in :py:attr:`leading_parts`. """ if self.use_time: return '''<span style="{css_time_html}">{asctime_html}</span>'''.format( css_time_html=escape_html(self.css_time), asctime_html=escape_html(record.asctime), ) return ""
async def _apply_msg_format(self, sender: 'u.User', content: MessageEventContent ) -> None: if not isinstance(content, TextMessageEventContent) or content.format != Format.HTML: content.format = Format.HTML content.formatted_body = escape_html(content.body).replace("\n", "<br/>") tpl = (self.get_config(f"message_formats.[{content.msgtype.value}]") or "<b>$sender_displayname</b>: $message") displayname = await self.get_displayname(sender) tpl_args = dict(sender_mxid=sender.mxid, sender_username=sender.mxid_localpart, sender_displayname=escape_html(displayname), message=content.formatted_body, body=content.body, formatted_body=content.formatted_body) content.formatted_body = Template(tpl).safe_substitute(tpl_args)
def get_footnote_backref_id(self, footnote_id): """ Get the footnote back-reference ID (HTML escaped). :param footnote_id: The raw footnote ID. :return: The footnote back-reference ID. """ return escape_html(self.footnote_id_html_format_backref.format(footnote_id))
def render_html(self, inner_html, **kwargs): """ Callback function for rendering HTML. :param inner_html: The inner HTML of this tree node. :param kwargs: Extra keyword arguments for rendering. :return The rendered HTML of this node. """ # Get the image source link src_link = self.get_image_src_link() # Get the alternative text alt_text = self.get_alt_text() extra_attrs = ' alt="{}"'.format(escape_html(alt_text)) if alt_text else '' # Get the image width img_width = self.get_img_width() if img_width: extra_attrs += ' width="{}"'.format(img_width) # Get the image height img_height = self.get_img_height() if img_height: extra_attrs += ' height="{}"'.format(img_height) # Render the image return self.html_render_template.format(src_link=src_link, extra_args=extra_attrs)
def __str__(self): reported_count = len(self.reported_by) reported_list = ', '.join( [str(reporter) for reporter in self.reported_by][:3]) + ( ' and %d others' % (reported_count - 3) if reported_count > 3 else '') params = { 'id': self.id, 'phone_nr': self.phone_nr, 'account_nr': self.account_nr, 'bank_name': self.bank_name, 'remark': self.remark, 'reported_by': reported_list, 'added_by': self.added_by } s = ("<b>Distributor #{id}</b>\n" "<b>[</b>{account_nr}<b>]</b>\n" "Updated: {phone_nr}\n" "_____________________\n" "Dealership:\n {bank_name}\n" "<b>==></b> {remark}\n" "Voted by: {reported_by}\n" "Owner: {added_by}").format( **{k: escape_html(str(v)) for (k, v) in params.items()} ) print(s) return s
def block_code(self, text, lang): if not lang: return '\n<pre><code>%s</code></pre>\n' % \ escape_html(text.strip()) lexer = lexers.get_lexer_by_name(lang, stripall=True) formatter = pygments.formatters.HtmlFormatter(cssclass='source') return pygments.highlight(text, lexer, formatter)
def __str__(self): reported_count = len(self.reported_by) reported_list = ', '.join( [str(reporter) for reporter in self.reported_by][:3]) + ( ' and %d others' % (reported_count - 3) if reported_count > 3 else '') params = { 'id': self.id, 'phone_nr': self.phone_nr, 'account_nr': self.account_nr, 'bank_name': self.bank_name, 'remark': self.remark, 'reported_by': reported_list, 'added_by': self.added_by } s = ("<b>Verified Member: C#{id}</b>\n" "<b>Cellular:</b> {phone_nr}\n" "Telegram ID: {account_nr}\n" "Name: {bank_name}\n" "DNA: {remark}\n" "Voted by: {reported_by}\n").format( **{k: escape_html(str(v)) for (k, v) in params.items()} ) print(s) return s
def render_html(self, inner_html, force_rel_nofollow=True, **kwargs): """ Callback function for rendering HTML. :param inner_html: The inner HTML of this tree node. :param force_rel_nofollow: If set to ``True``, all links in the rendered HTML will have the attribute "rel=nofollow" to avoid search engines to scrawl them (default ``True``). :param kwargs: Extra keyword arguments for rendering. :return The rendered HTML of this node. """ # Handle force_rel_nofollow extra_attrs = ' rel="nofollow"' if force_rel_nofollow or self.get_nofollow_flag( ) else '' # Add title if specified link_title = self.get_title_link() if link_title: extra_attrs += ' title="{}"'.format(escape_html(link_title)) # Get the target URL target_url = self.get_target_link() # Render the link if not target_url: return inner_html if self.is_url_inside_tag_content(): inner_html = target_url return self.html_render_template.format(src_link=target_url, extra_args=extra_attrs, inner_html=inner_html)
def get_footnote_ref_id(self, footnote_id): """ Get the footnote reference ID (HTML escaped). :param footnote_id: The raw footnote ID. :return: The footnote reference ID. """ return escape_html(self.footnote_id_html_format.format(footnote_id))
def _recursive_render_titles_html(title_groups, output, li_class_name, a_class_name, ul_class_name): """ Recursive helper for HTML rendering of titles summary. :param title_groups: List of two elements: ``[title, subtitles (another list)]``. :param output: The output list of HTML elements. :param li_class_name: The CSS class name for the ``li`` element. :param a_class_name: The CSS class name for the ``a`` element. :param ul_class_name: The CSS class name for the ``ul`` element. """ li_class = ' class="{}"'.format(li_class_name) if li_class_name else '' a_class = ' class="{}"'.format(a_class_name) if a_class_name else '' ul_class = ' class="{}"'.format(ul_class_name) if ul_class_name else '' # Process all titles for title, subtitles in title_groups: # Get the title ID title_id = title.get_permalink_slug() # Output the HTML list element for this title output.append('<li{}>'.format(li_class)) output.append('<a href="#{title_id}"{extra}>{title}</a>'.format(title_id=title_id, extra=a_class, title=escape_html(title.get_raw_content()))) if subtitles: output.append('<ul{}>'.format(ul_class)) _recursive_render_titles_html(subtitles, output, li_class_name, a_class_name, ul_class_name) output.append('</ul>') output.append('</li>')
def get_serialstation(update: Update, _: CallbackContext) -> None: """Generate a link to SerialStation and YouTube for given game""" text_part = update.message.text[0:4].upper() num_part = update.message.text[-5:] serial_station_url = 'https://serialstation.com/titles/{0}/{1}'.format( text_part, num_part) resp = requests.get(serial_station_url) if resp.status_code != 200: message = escape_markdown( 'SerialStation error, response code: {0}'.format(resp.status_code)) else: html_soup = BeautifulSoup(resp.content, 'html.parser') for header in html_soup.find_all('h1'): title = header.contents[0].strip() break escaped_title = escape_html(title).replace(' ', '+') message = escape_markdown( '{0}-{1}\n{2}\n\nhttps://serialstation.com/titles/{0}/{1}\n\nhttps://www.youtube.com/results?search_query={3}' .format(text_part, num_part, title, escaped_title), version=2) update.message.reply_markdown_v2(message, quote=False)
def run(self): document = self.state.document env = document.settings.env try: text = env.config.docopt_docstrings[self.arguments[0]] if not isinstance(text, str): msg = "Wrong data type for literal include. Found %s, must be str." % type( text) return [document.reporter.error(msg, line=self.lineno)] lines = [] for line in text.strip("\n").splitlines(): line = escape_html(line) line = re.sub(bold_markdown_re, bold_rendered_markdown_placeholder, line) if line.startswith((" ", "\t")): lines.append(line) else: lines.append('<strong>%s</strong>' % line if line else "") text = "\n".join(lines) retnode = nodes.raw("", container % text, format='html') set_source_info(self, retnode) retnode["classes"] += self.options.get("class", []) self.add_name(retnode) return [retnode] except Exception as err: return [document.reporter.error(str(err), line=self.lineno)]
def __str__(self): reported_count = len(self.reported_by) reported_list = ', '.join( [str(reporter) for reporter in self.reported_by][:3]) + ( ' and %d others' % (reported_count - 3) if reported_count > 3 else '') params = { 'id': self.id, 'phone_nr': self.phone_nr, 'account_nr': self.account_nr, 'bank_name': self.bank_name, 'remark': self.remark, 'reported_by': reported_list, 'added_by': self.added_by } s = ("<b>Report #{id}</b>\n" "Phone Nr.: {phone_nr}\n" "Bank Account Nr.: {account_nr}\n" "Bank Account Name: {bank_name}\n" "Admin remark: {remark}\n" "Reported by: {reported_by}\n" "Added by: {added_by}").format( **{k: escape_html(str(v)) for (k, v) in params.items()} ) print(s) return s
def __str__(self): reported_count = len(self.reported_by) reported_list = ', '.join([ str(reporter) for reporter in self.reported_by ][:3]) + (' and %d others' % (reported_count - 3) if reported_count > 3 else '') params = { 'id': self.id, 'phone_nr': self.phone_nr, 'account_nr': self.account_nr, 'bank_name': self.bank_name, 'remark': self.remark, 'reported_by': reported_list, 'added_by': self.added_by } s = ("<b>Report #{id}</b>\n" "Phone Nr.: {phone_nr}\n" "Bank Account Nr.: {account_nr}\n" "Bank Account Name: {bank_name}\n" "Admin remark: {remark}\n" "Reported by: {reported_by}\n" "Added by: {added_by}").format( **{k: escape_html(str(v)) for (k, v) in params.items()}) print(s) return s
def test_do_smileys_replacement_no_css_class(self): """ Test the ``do_smileys_replacement`` function. """ root_tree_node = RootTreeNode() setup_smileys_replacement(root_tree_node, '/smiley/', html_class='') for smiley, filename in DEFAULT_EMOTICONS_MAP: smiley = escape_html(smiley) output = do_smileys_replacement(root_tree_node, 'Foo %s bar' % smiley) self.assertEqual('Foo <img src="/smiley/%s" alt="%s"> bar' % (filename, smiley), output)
def format_html_leading_loggername(self, record): """ Get the logger name, if it is not one of the boring "standard names" (see :py:attr:`standard_names`). This method is meant to be a possible leading part in :py:attr:`leading_parts`. """ if record.name not in self.standard_names: return '[' + escape_html(record.name) + ']' return ""
async def _apply_emote_format(self, sender: 'u.User', content: TextMessageEventContent) -> None: if content.format != Format.HTML: content.format = Format.HTML content.formatted_body = escape_html(content.body).replace("\n", "<br/>") tpl = self.get_config("emote_format") puppet = p.Puppet.get(sender.tgid) content.formatted_body = Template(tpl).safe_substitute( dict(sender_mxid=sender.mxid, sender_username=sender.mxid_localpart, sender_displayname=escape_html(await self.get_displayname(sender)), mention=f"<a href='https://matrix.to/#/{puppet.mxid}'>{puppet.displayname}</a>", username=sender.username, displayname=puppet.displayname, body=content.body, formatted_body=content.formatted_body)) content.msgtype = MessageType.TEXT
async def _locked_vote_poll(event: events.CallbackQuery.Event) -> None: global current_vote if not current_vote or current_vote['poll'] != event.message_id: await event.answer('That poll is closed.') return try: await bot( GetParticipantRequest(channel=current_vote["chat"], user_id=event.input_sender)) except UserNotParticipantError: await event.answer('You\'re not participating in the chat.') return weight, displayname = WEIGHTS.get(event.sender_id, (DEFAULT_WEIGHT, None)) if weight == 0: await event.answer('You don\'t have the permission to vote.') return if event.data == b'addsticker/-': weight = -weight displayname = displayname or escape_html( (await event.get_sender()).first_name) try: existing = current_vote['votes'][event.sender_id] if existing.weight == weight: await event.answer(f'You already voted {weight}') return except KeyError: pass current_vote['votes'][event.sender_id] = VoteData( weight=weight, displayname=displayname) scores = calculate_scores() current_vote['score'] = scores.sum if abs(scores.sum) >= VOTES_REQUIRED: current_vote_status.set() accepted = await _locked_finish_poll() res = 'accepted' if accepted else 'rejected' await event.answer(f'Successfully voted {fancy_round(weight)},' f' which made the sticker be {res} \U0001f389') else: await bot.edit_message( current_vote['chat'], current_vote['poll'], POLL_TEMPLATE.format_map(get_template_data()), buttons=[ Button.inline(f'{UP} ({scores.yes_count})', UP_DAT), Button.inline(f'{DOWN} ({scores.no_count})', DOWN_DAT) ], parse_mode='html') await event.answer(f'Successfully voted {weight}')
def render_html(self, inner_html, **kwargs): """ Callback function for rendering HTML. :param inner_html: The inner HTML of this tree node. :param kwargs: Extra keyword arguments for rendering. :return The rendered HTML of this node. """ abbr_title = self.get_acronym_title() if not abbr_title: return inner_html return self.html_render_template.format(title=escape_html(abbr_title), inner_html=inner_html)
def render_html(self, inner_html, **kwargs): """ Callback function for rendering HTML. :param inner_html: The inner HTML of this tree node. :param kwargs: Extra keyword arguments for rendering. :return The rendered HTML of this node. """ content = self.content content = unescape_html_entities(content) content = escape_html(content) return content
def repr_htmlsafe(t): """Repr a value and html-escape the result. If an error is thrown by the repr, show a placeholder. """ try: r = repr(t) except Exception: r = "(Error Displaying {})".format(type(t).__name__) return escape_html(str(r), quote=True)
def mention_html(user_id, name): """ Args: user_id (:obj:`int`) The user's id which you want to mention. name (:obj:`str`) The name the mention is showing. Returns: :obj:`str`: The inline mention for the user as html. """ if isinstance(user_id, int): return '<a href="tg://user?id={}">{}</a>'.format(user_id, escape_html(name))
def test_do_smileys_replacement_no_css_class(self): """ Test the ``do_smileys_replacement`` function. """ root_tree_node = RootTreeNode() setup_smileys_replacement(root_tree_node, '/smiley/', html_class='') for smiley, filename in DEFAULT_EMOTICONS_MAP: smiley = escape_html(smiley) output = do_smileys_replacement(root_tree_node, 'Foo %s bar' % smiley) self.assertEqual( 'Foo <img src="/smiley/%s" alt="%s"> bar' % (filename, smiley), output)
def ansi_to_html(val): # Split us up by ANSI escape sequences. We want to catch not only the # standard color codes, but also things like sgr0. Hence this lame check. # Note that Python 2.6 doesn't have a flag param to re.split, so we have to # compile it first. reg = re.compile( """ ( # Capture \x1b # Escape [^m]* # Zero or more non-'m's m # Literal m terminates the sequence \x0f? # HACK: A ctrl-o - this is how tmux' sgr0 ends ) # End capture """, re.VERBOSE, ) separated = reg.split(val) # We have to HTML escape the text and convert ANSI escapes into HTML # Collect it all into this array result = [] span_open = False # Text is at even indexes, escape sequences at odd indexes for i in range(len(separated)): component = separated[i] if i % 2 == 0: # It's text, possibly empty # Clean up other ANSI junk result.append(escape_html(strip_ansi(component))) else: # It's an escape sequence. Close the previous escape. span_open = append_html_for_ansi_escape(component, result, span_open) # Close final escape if span_open: result.append("</span>") # Remove empty elements result = [x for x in result if x] # Clean up empty spans, the nasty way idx = len(result) - 1 while idx >= 1: if result[idx] == "</span>" and result[idx - 1].startswith("<span"): # Empty span, delete these two result[idx - 1:idx + 1] = [] idx = idx - 1 idx = idx - 1 return "".join(result)
def ansi_to_html(val): # Split us up by ANSI escape sequences. We want to catch not only the # standard color codes, but also things like sgr0. Hence this lame check. # Note that Python 2.6 doesn't have a flag param to re.split, so we have to # compile it first. reg = re.compile( """ ( # Capture \x1b # Escape [^m]* # Zero or more non-'m's m # Literal m terminates the sequence \x0f? # HACK: A ctrl-o - this is how tmux' sgr0 ends ) # End capture """, re.VERBOSE, ) separated = reg.split(val) # We have to HTML escape the text and convert ANSI escapes into HTML # Collect it all into this array result = [] span_open = False # Text is at even indexes, escape sequences at odd indexes for i in range(len(separated)): component = separated[i] if i % 2 == 0: # It's text, possibly empty # Clean up other ANSI junk result.append(escape_html(strip_ansi(component))) else: # It's an escape sequence. Close the previous escape. span_open = append_html_for_ansi_escape(component, result, span_open) # Close final escape if span_open: result.append("</span>") # Remove empty elements result = [x for x in result if x] # Clean up empty spans, the nasty way idx = len(result) - 1 while idx >= 1: if result[idx] == "</span>" and result[idx - 1].startswith("<span"): # Empty span, delete these two result[idx - 1 : idx + 1] = [] idx = idx - 1 idx = idx - 1 return "".join(result)
def render_error_html(self, inner_html, html_error_template, **kwargs): """ Callback function for rendering HTML when the node is erroneous. :param inner_html: The inner HTML of this tree node. :param html_error_template: The HTML template for rendering the erroneous parts of the output. :param kwargs: Extra keyword arguments for rendering. :return The rendered HTML of this node. """ output_html = [] if self.source_open_tag: output_html.append(html_error_template.format(error_message=self.error_message, source=escape_html(self.source_open_tag))) inner_content = inner_html or escape_html(self.get_raw_content()) if inner_content: output_html.append(inner_content) if self.source_close_tag: output_html.append(html_error_template.format(error_message=self.error_message, source=escape_html(self.source_close_tag))) return '\n'.join(output_html)
def add_tag(self, name, text, classes, ids, attributes, void = False, escape = True, inline_text = False): attributes = attributes or {} cls = ' '.join(self.combine_attribute('class', classes, attributes)) if cls: attributes['class'] = cls id = '_'.join(self.combine_attribute('id', ids, attributes)) if id: attributes['id'] = id attributes_list = [] for k, v in attributes.items(): if v is False: continue elif v is True: attributes_list.append(' {}'.format(k)) elif k == 'data' and isinstance(v, dict): for suffix, value in v.items(): attributes_list.append(' data-{}={!r}'.format(suffix.replace('_', '-'), escape_html(str(value)))) else: attributes_list.append(' {}={!r}'.format(k, escape_html(str(v)))) attributes_string = ''.join(attributes_list) # place holder for open tag self.text.append(None) open_tag = self.indented('<{}{}>'.format(name, attributes_string)) close_tag = '</{}>'.format(name) if inline_text: if escape: text = escape_html(str(text)) text = self.indent_text(text).lstrip() self.text[-1] = '{}{}{}'.format(open_tag, text, close_tag) elif void or name in self.VOID_ELEMENTS: self.text[-1] = self.indented('<{}{}>'.format(name, attributes_string)) return open_tag, close_tag
def setup_smileys_replacement(document_tree, base_url, emoticons_map=DEFAULT_EMOTICONS_MAP, html_class='emoticons'): """ Setup the document for emoticons replacement. :param document_tree: The document tree instance to be setup. :param emoticons_map: A tuple of tuple with two values ``(emoticon_text, emoticon_filename)``. :param base_url: The base URL for all emoticon images. Can also be a callable for dynamic paths. :param html_class: The HTML class to be assigned to each emoticons img tag (optional). """ assert document_tree, "Document tree is mandatory." assert document_tree.is_root, "Document tree must be a root tree node instance." assert base_url, "Base URL is mandatory." # Craft the emoticons regex emoticon_rules = '|'.join( [re.escape(escape_html(e)) for e, _ in emoticons_map]) emoticons_regex = r'(^|\s+)(?P<emoticon>{rules})(\s+|$)'.format( rules=emoticon_rules) emoticons_regex = re.compile(emoticons_regex) # Turn emoticons map into a dictionary # Note: use escape_html(k) as key because at rendering, when the ``do_smileys_replacement`` routine is called # emoticons are already HTML-encoded. As we need to inject HTML code for img, we can't do the replacement when # the emoticons are in plain text. emoticons_map = {escape_html(k): v for k, v in emoticons_map} # Helper method to turn ``base_url`` into a callable if necessary def build_url(filename): return urljoin(base_url, filename) # Store all emoticons related options document_tree.attrs[EMOTICONS_MAP_ATTR_NAME] = emoticons_map document_tree.attrs[EMOTICONS_REGEX_ATTR_NAME] = emoticons_regex document_tree.attrs[ EMOTICONS_BASE_URL_ATTR_NAME] = build_url if isinstance( base_url, str) else base_url document_tree.attrs[EMOTICONS_HTML_CLASS_ATTR_NAME] = html_class
def render_html(self, inner_html, **kwargs): """ Callback function for rendering HTML. :param inner_html: The inner HTML of this tree node. :param kwargs: Extra keyword arguments for rendering. :return The rendered HTML of this node. """ permalink_slug = self.get_permalink_slug() if permalink_slug: return self.html_render_template.format(title_tagname=self.html_tagname, slug_id=escape_html(permalink_slug), inner_html=inner_html) else: return self.html_render_no_permalink_template.format(title_tagname=self.html_tagname, inner_html=inner_html)
async def _get_state_change_message(self, event: str, user: '******', **kwargs: Any) -> Optional[str]: tpl = self.get_config(f"state_event_formats.{event}") if len(tpl) == 0: # Empty format means they don't want the message return None displayname = await self.get_displayname(user) tpl_args = { "mxid": user.mxid, "username": user.mxid_localpart, "displayname": escape_html(displayname), **kwargs, } return Template(tpl).safe_substitute(tpl_args)
def render_html(self, inner_html, **kwargs): """ Callback function for rendering HTML. :param inner_html: The inner HTML of this tree node. :param kwargs: Extra keyword arguments for rendering. :return The rendered HTML of this node. """ # Get the alert variables alert_type = self.get_alert_type() alert_title = self.get_alert_title() alert_html_template = self.get_alert_html_template(alert_type, alert_title) # Render the alert return alert_html_template.format( type=alert_type, title=escape_html(alert_title), inner_html=inner_html.strip() )
def render_html(self, inner_html, force_rel_nofollow=True, **kwargs): """ Callback function for rendering HTML. :param inner_html: The inner HTML of this tree node. :param force_rel_nofollow: If set to ``True``, all links in the rendered HTML will have the atribute "rel=nofollow" to avoid search engines to scrawl them (default ``True``). :param kwargs: Extra keyword arguments for rendering. :return The rendered HTML of this node. """ # Get the author name author_name = self.get_quote_author_name() if author_name: # Craft author name citation author_html = self.html_render_template_author_name.format( author_name=escape_html(author_name)) # Craft source link if any, and handle force_rel_nofollow src_link = self.get_quote_link() if src_link: extra_attrs = ' rel="nofollow"' if force_rel_nofollow else '' author_html = self.html_render_template_author_link.format( src_link=src_link, extra_args=extra_attrs, author_name=author_html) # Get and craft the source date src_date = self.get_quote_date() if src_date is not None: src_date_html = self.html_render_template_date.format( src_date_iso=src_date.isoformat(), src_date=src_date.strftime(self.datetime_format)) else: src_date_html = '' # Craft the final HTML extra_html = self.html_render_template_footer.format( author_name=author_html, src_date=src_date_html) else: extra_html = '' # Render the quote return self.html_render_template.format(inner_html=inner_html, footer_html=extra_html)
def render_html(self, inner_html, **kwargs): """ Callback function for rendering HTML. :param inner_html: The inner HTML of this tree node. :param kwargs: Extra keyword arguments for rendering. :return The rendered HTML of this node. """ # Get the alert variables alert_type = self.get_alert_type() alert_title = self.get_alert_title() alert_html_template = self.get_alert_html_template( alert_type, alert_title) # Render the alert return alert_html_template.format(type=alert_type, title=escape_html(alert_title), inner_html=inner_html.strip())
def format_html(self, record): """ Return the full HTML code for this log record (including any possible exception information and stack trace). We obtain the "leading" and "trailer" parts with :py:meth:`format_html_leading()` and :py:meth:`format_html_trailer()` and feed that along with the record message to :py:meth:`format_html_par()`. Additionally we append the results of :py:meth:`format_html_exception()` and/or :py:meth:`format_html_stacktrace()`, if appropriate. """ s = self.format_html_par(self.format_html_leading(record), escape_html(record.message), self.format_html_trailer(record), record) if record.exc_text: s += self.format_html_exception(record) if record.stack_info: s += self.format_html_stacktrace(record) return s
def render_html(self, inner_html, force_rel_nofollow=True, **kwargs): """ Callback function for rendering HTML. :param inner_html: The inner HTML of this tree node. :param force_rel_nofollow: If set to ``True``, all links in the rendered HTML will have the atribute "rel=nofollow" to avoid search engines to scrawl them (default ``True``). :param kwargs: Extra keyword arguments for rendering. :return The rendered HTML of this node. """ # Get the author name author_name = self.get_quote_author_name() if author_name: # Craft author name citation author_html = self.html_render_template_author_name.format(author_name=escape_html(author_name)) # Craft source link if any, and handle force_rel_nofollow src_link = self.get_quote_link() if src_link: extra_attrs = ' rel="nofollow"' if force_rel_nofollow else '' author_html = self.html_render_template_author_link.format(src_link=src_link, extra_args=extra_attrs, author_name=author_html) # Get and craft the source date src_date = self.get_quote_date() if src_date is not None: src_date_html = self.html_render_template_date.format(src_date_iso=src_date.isoformat(), src_date=src_date.strftime(self.datetime_format)) else: src_date_html = '' # Craft the final HTML extra_html = self.html_render_template_footer.format(author_name=author_html, src_date=src_date_html) else: extra_html = '' # Render the quote return self.html_render_template.format(inner_html=inner_html, footer_html=extra_html)
def format_html_stacktrace(self, record): return '''<pre style="margin-top:0.5em;{css_stacktrace_html}">{formatted_stacktrace_html}</pre>\n'''.format( css_stacktrace_html=escape_html(self.css_stacktrace), formatted_stacktrace_html=escape_html( self.formatStack(record.stack_info)), )
def sanitize_url(url, default_scheme='http', allowed_schemes=('http', 'https', 'ftp', 'ftps', 'mailto'), encode_html_entities=True, force_default_scheme=False, force_remove_scheme=False, fix_non_local_urls=True, absolute_base_url=''): """ Sanitize the given URL. Avoid XSS by filtering-out forbidden protocol and characters. Allowed protocols by default are: ``http``, ``https``, ``ftp``, ``ftps`` and ``mailto``. If no protocol scheme is specified, all non-local URL will be tied to the default scheme. :param url: The user-supplied URL to be sanitized. :param default_scheme: The default scheme to use (default to ``http``). :param allowed_schemes: The list of allowed schemes (see defaults above). :param encode_html_entities: If set to ``True``, the output URL will be encoded to avoid raw HTML entities (default is ``True``). :param force_default_scheme: Set to ``True`` to force the default scheme to be used in all case (default is``False``). :param force_remove_scheme: Set to ``True`` to remove the scheme if set (default is ``False``). N.B. The ``force_default_scheme`` and ``force_remove_scheme`` are mutually exclusive for obvious reasons. :param fix_non_local_urls: Set to ``True`` to fix non local URL with netloc in path (default is ``True``). Example: with ``fix_non_local_urls`` set to ``True``, ``google.com`` will become ``http://google.com/``. :param absolute_base_url: The base URL for the relative-to-absolute conversion. If set, relative URLs will be expanded as absolute URLs using the given base URL. Example: with ``absolute_base_url`` set to ``http://example.com/``, ``/forum/`` will become ``http://example.com/forum/``. :return: The sanitized URL as string, or an empty string if erroneous. """ assert default_scheme, "A default scheme is mandatory to avoid XSS." assert len(allowed_schemes) > 0, "You need to allow at least one scheme to get a result." assert not (force_default_scheme and force_remove_scheme), "You cannot force the default scheme and also force-remove the scheme." # Shortcut for empty string if not url: return '' # Remove dangerous stuff url = URL_CHARSET_SUB.sub('', url) # Split the URL try: scheme, netloc, path, query, fragment = urlsplit(url) except ValueError: # Handle malformed URL return '' # Check the scheme against the white list if scheme and scheme not in allowed_schemes: return '' # Detect and fix non local URL without // at beginning (not supported by ``urlsplit``) if not netloc and path and not path.startswith('/') and fix_non_local_urls: parts = path.split('/', 1) if len(parts) == 2: netloc, path = parts else: netloc = parts[0] path = '' # Add scheme to any non-local URL if required if (not scheme and netloc) or force_default_scheme: scheme = default_scheme # Remove the scheme if requested if force_remove_scheme: scheme = '' # Build the final URL if netloc or not absolute_base_url: result = urlunsplit((scheme, netloc, path, query, fragment)) else: result = urlunsplit(('', '', path, query, fragment)) result = urljoin(absolute_base_url, result) # Escape HTML if requested if encode_html_entities: result = escape_html(result) # Return the sanitized URL return result
def format_html_exception(self, record): return '''<pre style="margin-top:0.5em;{css_exception_html}">{exc_text_html}</pre>\n'''.format( css_exception_html=escape_html(self.css_exception), exc_text_html=escape_html(record.exc_text), )
def add_text(self, text, escape = True): if escape: text = escape_html(str(text)) self.text.append(self.indent_text(text))
def parse(self): for line in self.lines: line = line.rstrip('\n') if not line: # TODO: better paragraphe code using <p> if not self.was_empty: self.buf.append('<br/>') self.was_empty = True else: self.was_empty = False m = LINE_CMD.match(line) if m: cmd = m.group(1) args = m.group(2) if cmd == 'nf': if not self.keep_spaces: self.buf.append('<pre>') self.keep_spaces = True self.next_is_h4 = False elif cmd == 'fi' or cmd == 'br': # not sure about br if self.keep_spaces: self.buf.append('</pre>') self.keep_spaces = False self.next_is_h4 = False elif cmd == 'sp': if args: n = int(args) else: n = 1 for _ in range(n): self.buf.append('<br/>') self.next_is_h4 = False else: if self.keep_spaces: delim = '' else: delim = ' ' args = self.parse_text(args, self.keep_spaces) if cmd == 'TH': if self.keep_spaces: self.buf.append('</pre>') self.keep_spaces = False self.title = args[0] self.section = args[1] self.extras = args[2:] self.buf.append('<h1>') self.buf.append(escape_html(self.title)) self.buf.append('</h1>') self.next_is_h4 = False elif cmd == 'SH': if self.keep_spaces: self.buf.append('</pre>') self.keep_spaces = False self.buf.append('<h2>') self.buf.append(delim.join(args)) self.buf.append('</h2>') self.next_is_h4 = False elif cmd == 'SS': if self.keep_spaces: self.buf.append('</pre>') self.keep_spaces = False self.buf.append('<h3>') self.buf.append(delim.join(args)) self.buf.append('</h3>') self.next_is_h4 = False elif cmd == 'B': if self.next_is_h4: self.next_is_h4 = False if self.keep_spaces: self.buf.append('</pre>') self.keep_spaces = False self.buf.append('<h4>') self.buf.append(delim.join(args)) self.buf.append('</h4>') else: self.buf.append('<strong>') self.buf.append(delim.join(args)) self.buf.append('</strong>') elif cmd == 'BI': if self.next_is_h4: self.next_is_h4 = False if self.keep_spaces: self.buf.append('</pre>') self.keep_spaces = False self.buf.append('<h4>') self.alternate(args, None, 'I', '') self.buf.append('</h4>') else: self.alternate(args, 'B', 'I', '' if self.keep_spaces else ' ') elif cmd == 'BR': if self.next_is_h4: self.next_is_h4 = False if self.keep_spaces: self.buf.append('</pre>') self.keep_spaces = False self.buf.append('<h4>') self.alternate(args, None, 'R', '') self.buf.append('</h4>') else: for i in range(0, len(args), 2): pair = args[i:i+2] if len(pair) > 1: first, second = pair m1 = WORD.match(strip_html(first)) m2 = SECTION.match(strip_html(second)) is_link = m1 and m2 if is_link: self.buf.append('<a href="%s">' % escape_html(self.url.format( title=m1.group(1), section=m2.group(1) ))) self.buf.append(FONT_TO_BEGIN['B']) self.buf.append(first) self.buf.append(FONT_TO_END['B']) self.buf.append(FONT_TO_BEGIN['R']) self.buf.append(second) self.buf.append(FONT_TO_END['R']) if is_link: self.buf.append('</a>') else: self.buf.append(FONT_TO_BEGIN['B']) self.buf.append(pair[0]) self.buf.append(FONT_TO_END['B']) elif cmd == 'PP': # TODO: better paragraphe code using <p> self.buf.append('<br/>') elif cmd == 'TP': self.next_is_h4 = True else: raise ValueError("command not supported: .%s" % cmd) # TODO: line command else: words = self.parse_text(line, self.keep_spaces) if self.keep_spaces: delim = '' else: delim = ' ' for i, word in enumerate(words): m = LINK.match(strip_html(word)) if m: words[i] = '<a href="%s">%s</a>' % ( escape_html(self.url.format( title=m.group(1), section=m.group(2) )), word) self.buf.append(delim.join(words)) self.next_is_h4 = False self.buf.append("\n")
def parse_text(self, text, keep_spaces=False): if not keep_spaces: text = text.strip() buf = [] elems = [] fmt_stack = [] i = 0 while i < len(text): m = INLINE.search(text, i) if not m: buf.append(escape_html(text[i:])) break if i != m.start(): buf.append(escape_html(text[i:m.start()])) if m.group(1): font = m.group(1) do_fmt(font, buf, fmt_stack) elif m.group(2): font = m.group(2) do_fmt(font, buf, fmt_stack) elif m.group(3): ch = m.group(3) if ch == '-': buf.append('—') elif ch == '.': buf.append('.') elif ch == '~': buf.append(' ') elif m.group(4): ch = m.group(4) if ch == "dq": buf.append('"') elif ch == "rs": buf.append('\\') elif ch == "cq": buf.append("'") else: raise ValueError("not supported: \\(%s" % ch) elif m.group(5): s = m.group(5) buf.append(escape_html(s)) elif m.group(6): url = m.group(6) esc_url = escape_html(url) buf.append('<a href="%s">%s</a>' % (esc_url, esc_url)) elif m.group(7): # spaces if keep_spaces: buf.append(m.group(7)) elems.append(''.join(buf)) buf = [] elif m.group(8): # comment pass i = m.end() if buf: elems.append(''.join(buf)) return elems
def block_code(code, language): html = "<pre><code" html += " data-language=\"{0}\">".format(language) if language else ">" html += escape_html(code) html += "</code></pre>" return html
def render_html(self, inner_html, force_rel_nofollow=True, **kwargs): """ Callback function for rendering HTML. :param inner_html: The inner HTML of this tree node. :param force_rel_nofollow: If set to ``True``, all links in the rendered HTML will have the atribute "rel=nofollow" to avoid search engines to scrawl them (default ``True``). :param kwargs: Extra keyword arguments for rendering. :return The rendered HTML of this node. """ # Get figure ID figure_id = self.get_figure_id() # Handle line anchors lineanchors = figure_id anchorlinenos = bool(figure_id) # Render the source code try: lexer = get_lexer_by_name(self.get_language_name(), tabsize=self.tab_size) except ClassNotFound: # Handle unknown language name lexer = get_lexer_by_name(self.default_language_name, tabsize=self.tab_size) style = get_style_by_name(self.pygments_css_style_name) formatter = HtmlFormatter(style=style, linenos='table' if self.display_line_numbers else False, hl_lines=self.get_highlight_lines(), linenostart=self.get_start_line_number(), noclasses=True, lineanchors=lineanchors, anchorlinenos=anchorlinenos) source_code = highlight(self.get_cleaned_content(), lexer, formatter) # Wrap table in div for horizontal scrolling source_code = self.wrapping_div_html_template.format(class_name=self.wrapping_div_class_name, source_code=source_code) # Get extra filename and source link src_filename = self.get_filename() src_link_url = self.get_source_link_url() # Render the HTML block if src_filename or src_link_url: # Source code with caption caption = self.source_caption_html_template.format(escape_html(src_filename) if src_filename else src_link_url) # And source link if src_link_url: extra_args = ' rel="nofollow"' if force_rel_nofollow else '' caption = self.source_link_html_template.format(src_link=src_link_url, extra_args=extra_args, caption=caption) # Return the final HTML return self.code_html_template.format(figure_id=figure_id, source_code=source_code, caption=caption) elif figure_id: # Source code only with anchor return self.code_only_html_template.format(figure_id=figure_id, source_code=source_code) else: # Source code only return source_code