Пример #1
0
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
Пример #2
0
 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
          )
Пример #3
0
    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)
Пример #4
0
 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)
Пример #5
0
    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 ""
Пример #6
0
    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)
Пример #7
0
 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))
Пример #8
0
    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)
Пример #9
0
    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
Пример #10
0
 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)
Пример #11
0
    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
Пример #12
0
    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)
Пример #13
0
 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))
Пример #14
0
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>')
Пример #15
0
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)]
Пример #17
0
    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
Пример #18
0
    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
Пример #19
0
 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)
Пример #20
0
 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 ""
Пример #21
0
    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
Пример #22
0
    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}')
Пример #23
0
 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)
Пример #24
0
 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
Пример #25
0
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)
Пример #26
0
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))
Пример #27
0
 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)
Пример #28
0
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))
Пример #29
0
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)
Пример #30
0
 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)
Пример #31
0
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)
Пример #32
0
    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)
Пример #33
0
 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
Пример #34
0
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
Пример #35
0
 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)
Пример #36
0
    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)
Пример #37
0
    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()
        )
Пример #38
0
    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)
Пример #39
0
    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())
Пример #40
0
    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
Пример #41
0
    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)
Пример #42
0
 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)),
     )
Пример #43
0
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
Пример #44
0
 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),
     )
Пример #45
0
 def add_text(self, text, escape = True):
     if escape:
         text = escape_html(str(text))
     self.text.append(self.indent_text(text))
Пример #46
0
	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")
Пример #47
0
	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('&mdash;')
				elif ch == '.':
					buf.append('.')
				elif ch == '~':
					buf.append('&nbsp;')
			elif m.group(4):
				ch = m.group(4)
				if ch == "dq":
					buf.append('&quot;')
				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
Пример #48
0
 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
Пример #49
0
    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