<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># coding=utf-8
import logging
import re

log = logging.getLogger(__name__)


def is_email(element):
    """
    &gt;&gt;&gt; is_email('username@example.com')
    True
    &gt;&gt;&gt; is_email('example.com')
    False
    &gt;&gt;&gt; is_email('firstname.lastname@domain.co.uk')
    True
    """
    email_regex = r"^[A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*$"
    return re.match(email_regex, str(element))


def html_email(email, title=None):
    """
    &gt;&gt;&gt; html_email('username@example.com')
    '&lt;a href="mailto:username@example.com"&gt;username@example.com&lt;/a&gt;'
    """

    if not title:
        title = email

    return '&lt;a href="mailto:{email}"&gt;{title}&lt;/a&gt;'.format(email=email, title=title)


def html_list(data):
    """
    &gt;&gt;&gt; html_list(['example.com', 'admin1@example.com', 'admin2@example.com'])
    '&lt;ul&gt;
        &lt;li&gt;example.com&lt;/li&gt;
        &lt;li&gt;&lt;a href="mailto:admin1@example.com"&gt;admin1@example.com&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="mailto:admin2@example.com"&gt;admin2@example.com&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;'
    """
    html = "&lt;ul&gt;"

    for item in data:

        if isinstance(item, dict):
            if item.get("email"):
                item = html_email(item.get("email"), item.get("name", None))
            elif item.get("name"):
                item = item.get("name")

        if is_email(item):
            item = html_email(item, item)

        html += "&lt;li&gt;{}&lt;/li&gt;".format(item)

    return html + "&lt;/ul&gt;"


def html_table_header_row(data):
    """
    &gt;&gt;&gt; html_table_header_row(['administrators', 'key', 'leader', 'project'])
    '\\n\\t&lt;tr&gt;&lt;th&gt;Administrators&lt;/th&gt;&lt;th&gt;Key&lt;/th&gt;&lt;th&gt;Leader&lt;/th&gt;&lt;th&gt;Project&lt;/th&gt;&lt;/tr&gt;'
    &gt;&gt;&gt; html_table_header_row(['key', 'project', 'leader', 'administrators'])
    '\\n\\t&lt;tr&gt;&lt;th&gt;Key&lt;/th&gt;&lt;th&gt;Project&lt;/th&gt;&lt;th&gt;Leader&lt;/th&gt;&lt;th&gt;Administrators&lt;/th&gt;&lt;/tr&gt;'
    """
    html = "\n\t&lt;tr&gt;"

    for th in data:
        title = th.replace("_", " ").title()
        html += "&lt;th&gt;{}&lt;/th&gt;".format(title)

    return html + "&lt;/tr&gt;"


def html_row_with_ordered_headers(data, col_headers, row_header=None):
    """
    &gt;&gt;&gt; headers = ['administrators', 'key', 'leader', 'project']
    &gt;&gt;&gt; data = {'key': 'DEMO', 'project': 'Demonstration',
                'leader': 'leader@example.com',
                'administrators': ['admin1@example.com', 'admin2@example.com']}
    &gt;&gt;&gt; html_row_with_ordered_headers(data, headers)
    '\\n\\t&lt;tr&gt;&lt;td&gt;&lt;ul&gt;
                        &lt;li&gt;&lt;a href="mailto:admin1@example.com"&gt;admin1@example.com&lt;/a&gt;&lt;/li&gt;
                        &lt;li&gt;&lt;a href="mailto:admin2@example.com"&gt;admin2@example.com&lt;/a&gt;&lt;/li&gt;
                    &lt;/ul&gt;&lt;/td&gt;&lt;td&gt;DEMO&lt;/td&gt;&lt;td&gt;leader@example.com&lt;/td&gt;&lt;td&gt;Demonstration&lt;/td&gt;&lt;/tr&gt;'
    &gt;&gt;&gt; headers = ['key', 'project', 'leader', 'administrators']
    &gt;&gt;&gt; html_row_with_ordered_headers(data, headers)
    '\\n\\t&lt;tr&gt;&lt;td&gt;DEMO&lt;/td&gt;&lt;td&gt;Demonstration&lt;/td&gt;
                &lt;td&gt;leader@example.com&lt;/td&gt;&lt;td&gt;
                &lt;ul&gt;
                    &lt;li&gt;&lt;a href="mailto:admin1@example.com"&gt;admin1@example.com&lt;/a&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;a href="mailto:admin2@example.com"&gt;admin2@example.com&lt;/a&gt;&lt;/li&gt;
                &lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;'
    """
    html = "\n\t&lt;tr&gt;"

    if row_header:
        html += "&lt;th&gt;{}&lt;/th&gt;".format(row_header.replace("_", " ").title())
    for header in col_headers:
        element = data[header]

        if isinstance(element, list):
            element = html_list(element)

        if is_email(element):
            element = html_email(element)

        html += "&lt;td&gt;{}&lt;/td&gt;".format(element)

    return html + "&lt;/tr&gt;"


def html_table_from_dict(data, ordering):
    """
    &gt;&gt;&gt; ordering = ['administrators', 'key', 'leader', 'project']
    &gt;&gt;&gt; data = [ \
        {'key': 'DEMO', 'project': 'Demo project', 'leader': 'lead@example.com', \
            'administrators': ['admin@example.com', 'root@example.com']},]
    &gt;&gt;&gt; html_table_from_dict(data, ordering)
    '&lt;table&gt;
        &lt;tbody&gt;\\n
            &lt;tr&gt;
                &lt;th&gt;Administrators&lt;/th&gt;
                &lt;th&gt;Key&lt;/th&gt;
                &lt;th&gt;Leader&lt;/th&gt;
                &lt;th&gt;Project&lt;/th&gt;
            &lt;/tr&gt;\\n
        &lt;tr&gt;
            &lt;td&gt;
                &lt;ul&gt;
                    &lt;li&gt;&lt;a href="mailto:admin@example.com"&gt;admin@example.com&lt;/a&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;a href="mailto:root@example.com"&gt;root@example.com&lt;/a&gt;&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/td&gt;
            &lt;td&gt;DEMO&lt;/td&gt;
            &lt;td&gt;lead@example.com&lt;/td&gt;
            &lt;td&gt;Demo project&lt;/td&gt;
        &lt;/tr&gt;\\n
        &lt;/tbody&gt;
    &lt;/table&gt;'
    &gt;&gt;&gt; ordering = ['key', 'project', 'leader', 'administrators']
    &gt;&gt;&gt; html_table_from_dict(data, ordering)
    '&lt;table&gt;
        &lt;tbody&gt;\\n
            &lt;tr&gt;
                &lt;th&gt;Key&lt;/th&gt;
                &lt;th&gt;Project&lt;/th&gt;
                &lt;th&gt;Leader&lt;/th&gt;
                &lt;th&gt;Administrators&lt;/th&gt;
            &lt;/tr&gt;\\n
            &lt;tr&gt;
                &lt;td&gt;DEMO&lt;/td&gt;
                &lt;td&gt;Demo project&lt;/td&gt;
                &lt;td&gt;lead@example.com&lt;/td&gt;
                &lt;td&gt;
                    &lt;ul&gt;
                        &lt;li&gt;&lt;a href="mailto:admin@example.com"&gt;admin@example.com&lt;/a&gt;&lt;/li&gt;
                        &lt;li&gt;&lt;a href="mailto:root@example.com"&gt;root@example.com&lt;/a&gt;&lt;/li&gt;
                    &lt;/ul&gt;
                &lt;/td&gt;
            &lt;/tr&gt;\\n
        &lt;/tbody&gt;
    &lt;/table&gt;'
    """
    html = "&lt;table&gt;&lt;tbody&gt;"
    html += html_table_header_row(ordering)

    for row in data:
        html += html_row_with_ordered_headers(row, ordering)

    return html + "\n&lt;/tbody&gt;&lt;/table&gt;"


def html_table_from_nested_dict(data, ordering):
    """
    &gt;&gt;&gt; ordering = ['manager', 'admin', 'employee_count']
    &gt;&gt;&gt;     data = {
        'project_A': {'manager': 'John', 'admin': 'admin1@example.com', 'employee_count': '4'},
        'project_B': {'manager': 'Jane', 'admin': 'admin2@example.com', 'employee_count': '7'}
    }
    &gt;&gt;&gt; html_table_from_nested_dict(data, ordering)
    &lt;table&gt;
        &lt;tbody&gt;
            &lt;tr&gt;
                &lt;th&gt;&lt;/th&gt;
                &lt;th&gt;Manager&lt;/th&gt;
                &lt;th&gt;Admin&lt;/th&gt;
                &lt;th&gt;Employee Count&lt;/th&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;th&gt;Project A&lt;/th&gt;
                &lt;td&gt;John&lt;/td&gt;
                &lt;td&gt;&lt;a href="mailto:admin1@example.com"&gt;admin1@example.com&lt;/a&gt;&lt;/td&gt;
                &lt;td&gt;4&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;th&gt;Project B&lt;/th&gt;
                &lt;td&gt;Jane&lt;/td&gt;
                &lt;td&gt;&lt;a href="mailto:admin2@example.com"&gt;admin2@example.com&lt;/a&gt;&lt;/td&gt;
                &lt;td&gt;7&lt;/td&gt;
            &lt;/tr&gt;
        &lt;/tbody&gt;
    &lt;/table&gt;
    """

    html = "&lt;table&gt;&lt;tbody&gt;"
    # Add an empty first cell for the row header column
    header_row = [""]
    header_row.extend(ordering)
    html += html_table_header_row(header_row)

    for row_header, row in data.items():
        html += html_row_with_ordered_headers(row, ordering, row_header)

    return html + "\n&lt;/tbody&gt;&lt;/table&gt;"


def block_code_macro_confluence(code, lang=None):
    """
    Wrap into code block macro
    :param code:
    :param lang:
    :return:
    """
    if not lang:
        lang = ""
    return (
        """\
                &lt;ac:structured-macro ac:name="code" ac:schema-version="1"&gt;
                    &lt;ac:parameter ac:name="language"&gt;{lang}&lt;/ac:parameter&gt;
                    &lt;ac:plain-text-body&gt;&lt;![CDATA[{code}]]&gt;&lt;/ac:plain-text-body&gt;
                &lt;/ac:structured-macro&gt;
            """
    ).format(lang=lang, code=code)


def html_code__macro_confluence(text):
    """
    Wrap into html macro
    :param text:
    :return:
    """
    return (
        """\
                &lt;ac:structured-macro ac:name="html" ac:schema-version="1"&gt;
                    &lt;ac:plain-text-body&gt;&lt;![CDATA[{text}]]&gt;&lt;/ac:plain-text-body&gt;
                &lt;/ac:structured-macro&gt;
            """
    ).format(text=text)


def noformat_code_macro_confluence(text, nopanel=None):
    """
    Wrap into code block macro
    :param text:
    :param nopanel: (bool) True or False Removes the panel around the content.
    :return:
    """
    if not nopanel:
        nopanel = False
    return (
        """\
                &lt;ac:structured-macro ac:name="noformat" ac:schema-version="1"&gt;
                    &lt;ac:parameter ac:name="nopanel"&gt;{nopanel}&lt;/ac:parameter&gt;
                    &lt;ac:plain-text-body&gt;&lt;![CDATA[{text}]]&gt;&lt;/ac:plain-text-body&gt;
                &lt;/ac:structured-macro&gt;
            """
    ).format(nopanel=nopanel, text=text)


def symbol_normalizer(text):
    if not text:
        return ""
    result = text
    result = result.replace("&amp;Auml;", "Г„")
    result = result.replace("&amp;auml;", "Г¤")
    result = result.replace("&amp;Euml;", "Г‹")
    result = result.replace("&amp;euml;", "Г«")
    result = result.replace("&amp;Iuml;", "ГЏ")
    result = result.replace("&amp;iuml;", "ГЇ")
    result = result.replace("&amp;Ouml;", "Г–")
    result = result.replace("&amp;ouml;", "Г¶")
    result = result.replace("&amp;Uuml;", "Гњ")
    result = result.replace("&amp;uuml;", "Гј")
    result = result.replace("&amp;Aacute;", "ГЃ")
    result = result.replace("&amp;aacute;", "ГЎ")
    result = result.replace("&amp;Eacute;", "Г‰")
    result = result.replace("&amp;eacute;", "Г©")
    result = result.replace("&amp;Iacute;", "ГЌ")
    result = result.replace("&amp;iacute;", "Г­")
    result = result.replace("&amp;Oacute;", "Г“")
    result = result.replace("&amp;oacute;", "Гі")
    result = result.replace("&amp;Uacute;", "Гљ")
    result = result.replace("&amp;uacute;", "Гє")
    result = result.replace("&amp;Agrave;", "ГЂ")
    result = result.replace("&amp;agrave;", "Г&nbsp;")
    result = result.replace("&amp;Egrave;", "Г€")
    result = result.replace("&amp;egrave;", "ГЁ")
    result = result.replace("&amp;Igrave;", "ГЊ")
    result = result.replace("&amp;igrave;", "Г¬")
    result = result.replace("&amp;Ograve;", "Г’")
    result = result.replace("&amp;ograve;", "ГІ")
    result = result.replace("&amp;Ugrave;", "Г™")
    result = result.replace("&amp;ugrave;", "Г№")
    result = result.replace("&amp;Acirc;", "Г‚")
    result = result.replace("&amp;acirc;", "Гў")
    result = result.replace("&amp;Ecirc;", "ГЉ")
    result = result.replace("&amp;ecirc;", "ГЄ")
    result = result.replace("&amp;Icirc;", "ГЋ")
    result = result.replace("&amp;icirc;", "Г®")
    result = result.replace("&amp;Ocirc;", "Г”")
    result = result.replace("&amp;ocirc;", "Гґ")
    result = result.replace("&amp;Ucirc;", "Г›")
    result = result.replace("&amp;ucirc;", "Г»")
    result = result.replace("&amp;Aring;", "Г…")
    result = result.replace("&amp;aring;", "ГҐ")
    result = result.replace("&amp;deg;", "В°")
    return result


def parse_cookie_file(cookie_file):
    """
    Parse a cookies.txt file (Netscape HTTP Cookie File)
    return a dictionary of key value pairs
    compatible with requests.
    :param cookie_file: a cookie file
    :return dict of cookies pair
    """
    cookies = {}
    with open(cookie_file, "r") as fp:
        for line in fp:
            if not re.match(r"^(#|$)", line):
                line_fields = line.strip().split("\t")
                try:
                    cookies[line_fields[5]] = line_fields[6]
                except IndexError as e:
                    log.error(e)
    return cookies
</pre></body></html>