Esempio n. 1
0
 def test_mit_rendering(self):
     msg = "**test**"
     converted = bugdown.convert(msg, "mit.edu/zephyr_mirror")
     self.assertEqual(converted, "<p>**test**</p>")
     msg = "* test"
     converted = bugdown.convert(msg, "mit.edu/zephyr_mirror")
     self.assertEqual(converted, "<p>* test</p>")
     msg = "https://lists.debian.org/debian-ctte/2014/02/msg00173.html"
     converted = bugdown.convert(msg, "mit.edu/zephyr_mirror")
     self.assertEqual(
         converted,
         '<p><a href="https://lists.debian.org/debian-ctte/2014/02/msg00173.html" target="_blank" title="https://lists.debian.org/debian-ctte/2014/02/msg00173.html">https://lists.debian.org/debian-ctte/2014/02/msg00173.html</a></p>',
     )
Esempio n. 2
0
def do_render_markdown(message: Message,
                       content: str,
                       realm: Realm,
                       message_user_ids: Set[int],
                       sent_by_bot: bool,
                       translate_emoticons: bool,
                       realm_alert_words_automaton: Optional[ahocorasick.Automaton]=None,
                       mention_data: Optional[bugdown.MentionData]=None,
                       email_gateway: Optional[bool]=False) -> str:
    """Return HTML for given markdown. Bugdown may add properties to the
    message object such as `mentions_user_ids`, `mentions_user_group_ids`, and
    `mentions_wildcard`.  These are only on this Django object and are not
    saved in the database.
    """

    message.mentions_wildcard = False
    message.mentions_user_ids = set()
    message.mentions_user_group_ids = set()
    message.alert_words = set()
    message.links_for_preview = set()
    message.user_ids_with_alert_words = set()

    # DO MAIN WORK HERE -- call bugdown to convert
    rendered_content = bugdown.convert(
        content,
        realm_alert_words_automaton=realm_alert_words_automaton,
        message=message,
        message_realm=realm,
        sent_by_bot=sent_by_bot,
        translate_emoticons=translate_emoticons,
        mention_data=mention_data,
        email_gateway=email_gateway
    )
    return rendered_content
Esempio n. 3
0
def do_render_markdown(message: Message,
                       content: str,
                       realm: Realm,
                       message_user_ids: Set[int],
                       sent_by_bot: bool,
                       translate_emoticons: bool,
                       realm_alert_words_automaton: Optional[ahocorasick.Automaton]=None,
                       mention_data: Optional[bugdown.MentionData]=None,
                       email_gateway: Optional[bool]=False) -> str:
    """Return HTML for given markdown. Bugdown may add properties to the
    message object such as `mentions_user_ids`, `mentions_user_group_ids`, and
    `mentions_wildcard`.  These are only on this Django object and are not
    saved in the database.
    """

    message.mentions_wildcard = False
    message.mentions_user_ids = set()
    message.mentions_user_group_ids = set()
    message.alert_words = set()
    message.links_for_preview = set()
    message.user_ids_with_alert_words = set()

    # DO MAIN WORK HERE -- call bugdown to convert
    rendered_content = bugdown.convert(
        content,
        realm_alert_words_automaton=realm_alert_words_automaton,
        message=message,
        message_realm=realm,
        sent_by_bot=sent_by_bot,
        translate_emoticons=translate_emoticons,
        mention_data=mention_data,
        email_gateway=email_gateway
    )
    return rendered_content
Esempio n. 4
0
    def render_markdown(self, content, domain=None):
        """Return HTML for given markdown. Bugdown may add properties to the
        message object such as `mentions_user_ids` and `mentions_wildcard`.
        These are only on this Django object and are not saved in the
        database.
        """
        global bugdown
        if bugdown is None:
            from zerver.lib import bugdown

        self.mentions_wildcard = False
        self.is_me_message = False
        self.mentions_user_ids = set()
        self.user_ids_with_alert_words = set()

        if not domain:
            domain = self.sender.realm.domain
        if self.sending_client.name == "zephyr_mirror" and domain == "mit.edu":
            # Use slightly customized Markdown processor for content
            # delivered via zephyr_mirror
            domain = "mit.edu/zephyr_mirror"
        rendered_content = bugdown.convert(content, domain, self)

        # For /me syntax, JS can detect the is_me_message flag
        # and do special rendering.
        if content.startswith('/me ') and '\n' not in content:
            if rendered_content.startswith('<p>') and rendered_content.endswith('</p>'):
                self.is_me_message = True

        return rendered_content
Esempio n. 5
0
def render_markdown(message,
                    content,
                    realm=None,
                    realm_alert_words=None,
                    message_users=None):
    # type: (Message, Text, Optional[Realm], Optional[RealmAlertWords], Set[UserProfile]) -> Text
    """Return HTML for given markdown. Bugdown may add properties to the
    message object such as `mentions_user_ids` and `mentions_wildcard`.
    These are only on this Django object and are not saved in the
    database.
    """

    if message_users is None:
        message_user_ids = set()  # type: Set[int]
    else:
        message_user_ids = {u.id for u in message_users}

    if message is not None:
        message.mentions_wildcard = False
        message.is_me_message = False
        message.mentions_user_ids = set()
        message.alert_words = set()
        message.links_for_preview = set()

        if realm is None:
            realm = message.get_realm()

    possible_words = set()  # type: Set[Text]
    if realm_alert_words is not None:
        for user_id, words in realm_alert_words.items():
            if user_id in message_user_ids:
                possible_words.update(set(words))

    if message is None:
        # If we don't have a message, then we are in the compose preview
        # codepath, so we know we are dealing with a human.
        sent_by_bot = False
    else:
        sent_by_bot = get_user_profile_by_id(message.sender_id).is_bot

    # DO MAIN WORK HERE -- call bugdown to convert
    rendered_content = bugdown.convert(content,
                                       message=message,
                                       message_realm=realm,
                                       possible_words=possible_words,
                                       sent_by_bot=sent_by_bot)

    if message is not None:
        message.user_ids_with_alert_words = set()

        if realm_alert_words is not None:
            for user_id, words in realm_alert_words.items():
                if user_id in message_user_ids:
                    if set(words).intersection(message.alert_words):
                        message.user_ids_with_alert_words.add(user_id)

        message.is_me_message = Message.is_status_message(
            content, rendered_content)

    return rendered_content
Esempio n. 6
0
def api_endpoint_docs(request):
    # type: (HttpRequest) -> HttpResponse
    context = {}  # type: Dict[str, Any]
    add_api_uri_context(context, request)

    raw_calls = open('templates/zerver/api_content.json', 'r').read()
    calls = ujson.loads(raw_calls)
    langs = set()
    for call in calls:
        call["endpoint"] = "%s/v1/%s" % (context["external_api_uri_subdomain"],
                                         call["endpoint"])
        call["example_request"]["curl"] = call["example_request"]["curl"].replace("https://api.zulip.com",
                                                                                  context["external_api_uri_subdomain"])
        response = call['example_response']
        if '\n' not in response:
            # For 1-line responses, pretty-print them
            extended_response = response.replace(", ", ",\n ")
        else:
            extended_response = response
        call['rendered_response'] = bugdown.convert("~~~ .py\n" + extended_response + "\n~~~\n")
        for example_type in ('request', 'response'):
            for lang in call.get('example_' + example_type, []):
                langs.add(lang)
    return render(
        request,
        'zerver/api_endpoints.html',
        context={'content': calls, 'langs': langs},
    )
Esempio n. 7
0
    def test_realm_emoji(self):
        def emoji_img(name, url):
            return '<img alt="%s" class="emoji" src="%s" title="%s">' % (name, url, name)

        zulip_realm = get_realm('zulip.com')
        url = "https://zulip.com/test_realm_emoji.png"
        do_add_realm_emoji(zulip_realm, "test", url)

        # Needs to mock an actual message because that's how bugdown obtains the realm
        msg = Message(sender=get_user_profile_by_email("*****@*****.**"))
        converted = bugdown.convert(":test:", "zulip.com", msg)
        self.assertEqual(converted, '<p>%s</p>' %(emoji_img(':test:', url)))

        do_remove_realm_emoji(zulip_realm, 'test')
        converted = bugdown.convert(":test:", "zulip.com", msg)
        self.assertEqual(converted, '<p>:test:</p>')
Esempio n. 8
0
    def render_markdown(self, content, domain=None):
        """Return HTML for given markdown. Bugdown may add properties to the
        message object such as `mentions_user_ids` and `mentions_wildcard`.
        These are only on this Django object and are not saved in the
        database.
        """
        global bugdown
        if bugdown is None:
            from zerver.lib import bugdown

        self.mentions_wildcard = False
        self.is_me_message = False
        self.mentions_user_ids = set()
        self.user_ids_with_alert_words = set()

        if not domain:
            domain = self.sender.realm.domain
        if self.sending_client.name == "zephyr_mirror" and domain == "mit.edu":
            # Use slightly customized Markdown processor for content
            # delivered via zephyr_mirror
            domain = "mit.edu/zephyr_mirror"
        rendered_content = bugdown.convert(content, domain, self)

        # For /me syntax, JS can detect the is_me_message flag
        # and do special rendering.
        if content.startswith('/me ') and '\n' not in content:
            if rendered_content.startswith(
                    '<p>') and rendered_content.endswith('</p>'):
                self.is_me_message = True

        return rendered_content
Esempio n. 9
0
def render_markdown(message: Message,
                    content: Text,
                    realm: Optional[Realm] = None,
                    realm_alert_words: Optional[RealmAlertWords] = None,
                    user_ids: Optional[Set[int]] = None,
                    mention_data: Optional[bugdown.MentionData] = None,
                    email_gateway: Optional[bool] = False) -> Text:
    """Return HTML for given markdown. Bugdown may add properties to the
    message object such as `mentions_user_ids`, `mentions_user_group_ids`, and
    `mentions_wildcard`.  These are only on this Django object and are not
    saved in the database.
    """

    if user_ids is None:
        message_user_ids = set()  # type: Set[int]
    else:
        message_user_ids = user_ids

    if message is not None:
        message.mentions_wildcard = False
        message.mentions_user_ids = set()
        message.mentions_user_group_ids = set()
        message.alert_words = set()
        message.links_for_preview = set()

        if realm is None:
            realm = message.get_realm()

    possible_words = set()  # type: Set[Text]
    if realm_alert_words is not None:
        for user_id, words in realm_alert_words.items():
            if user_id in message_user_ids:
                possible_words.update(set(words))

    if message is None:
        # If we don't have a message, then we are in the compose preview
        # codepath, so we know we are dealing with a human.
        sent_by_bot = False
    else:
        sent_by_bot = get_user_profile_by_id(message.sender_id).is_bot

    # DO MAIN WORK HERE -- call bugdown to convert
    rendered_content = bugdown.convert(content,
                                       message=message,
                                       message_realm=realm,
                                       possible_words=possible_words,
                                       sent_by_bot=sent_by_bot,
                                       mention_data=mention_data,
                                       email_gateway=email_gateway)

    if message is not None:
        message.user_ids_with_alert_words = set()

        if realm_alert_words is not None:
            for user_id, words in realm_alert_words.items():
                if user_id in message_user_ids:
                    if set(words).intersection(message.alert_words):
                        message.user_ids_with_alert_words.add(user_id)

    return rendered_content
Esempio n. 10
0
def api_endpoint_docs(request):
    # type: (HttpRequest) -> HttpResponse
    context = {}  # type: Dict[str, Any]
    add_api_uri_context(context, request)

    raw_calls = open('templates/zerver/api_content.json', 'r').read()
    calls = ujson.loads(raw_calls)
    langs = set()
    for call in calls:
        call["endpoint"] = "%s/v1/%s" % (context["external_api_uri_subdomain"],
                                         call["endpoint"])
        call["example_request"]["curl"] = call["example_request"]["curl"].replace("https://api.zulip.com",
                                                                                  context["external_api_uri_subdomain"])
        response = call['example_response']
        if '\n' not in response:
            # For 1-line responses, pretty-print them
            extended_response = response.replace(", ", ",\n ")
        else:
            extended_response = response
        call['rendered_response'] = bugdown.convert("~~~ .py\n" + extended_response + "\n~~~\n")
        for example_type in ('request', 'response'):
            for lang in call.get('example_' + example_type, []):
                langs.add(lang)
    return render(
        request,
        'zerver/api_endpoints.html',
        context={'content': calls, 'langs': langs},
    )
Esempio n. 11
0
    def test_realm_emoji(self):
        def emoji_img(name, url):
            return '<img alt="%s" class="emoji" src="%s" title="%s">' % (
                name, url, name)

        zulip_realm = get_realm('zulip.com')
        url = "https://zulip.com/test_realm_emoji.png"
        do_add_realm_emoji(zulip_realm, "test", url)

        # Needs to mock an actual message because that's how bugdown obtains the realm
        msg = Message(sender=get_user_profile_by_email("*****@*****.**"))
        converted = bugdown.convert(":test:", "zulip.com", msg)
        self.assertEqual(converted, '<p>%s</p>' % (emoji_img(':test:', url)))

        do_remove_realm_emoji(zulip_realm, 'test')
        converted = bugdown.convert(":test:", "zulip.com", msg)
        self.assertEqual(converted, '<p>:test:</p>')
Esempio n. 12
0
    def test_realm_patterns(self):
        RealmFilter(realm=get_realm('zulip.com'), pattern=r"#(?P<id>[0-9]{2,8})",
                    url_format_string=r"https://trac.zulip.net/ticket/%(id)s").save()
        msg = Message(sender=get_user_profile_by_email("*****@*****.**"))

        content = "We should fix #224 and #115, but not issue#124 or #1124z or [trac #15](https://trac.zulip.net/ticket/16) today."
        converted = bugdown.convert(content, realm_domain='zulip.com', message=msg)

        self.assertEqual(converted, '<p>We should fix <a href="https://trac.zulip.net/ticket/224" target="_blank" title="https://trac.zulip.net/ticket/224">#224</a> and <a href="https://trac.zulip.net/ticket/115" target="_blank" title="https://trac.zulip.net/ticket/115">#115</a>, but not issue#124 or #1124z or <a href="https://trac.zulip.net/ticket/16" target="_blank" title="https://trac.zulip.net/ticket/16">trac #15</a> today.</p>')
Esempio n. 13
0
def render_markdown(message: Message,
                    content: str,
                    realm: Optional[Realm]=None,
                    realm_alert_words: Optional[RealmAlertWords]=None,
                    user_ids: Optional[Set[int]]=None,
                    mention_data: Optional[bugdown.MentionData]=None,
                    email_gateway: Optional[bool]=False) -> str:
    """Return HTML for given markdown. Bugdown may add properties to the
    message object such as `mentions_user_ids`, `mentions_user_group_ids`, and
    `mentions_wildcard`.  These are only on this Django object and are not
    saved in the database.
    """

    if user_ids is None:
        message_user_ids = set()  # type: Set[int]
    else:
        message_user_ids = user_ids

    message.mentions_wildcard = False
    message.mentions_user_ids = set()
    message.mentions_user_group_ids = set()
    message.alert_words = set()
    message.links_for_preview = set()

    if realm is None:
        realm = message.get_realm()

    possible_words = set()  # type: Set[str]
    if realm_alert_words is not None:
        for user_id, words in realm_alert_words.items():
            if user_id in message_user_ids:
                possible_words.update(set(words))

    sent_by_bot = get_user_profile_by_id(message.sender_id).is_bot

    # DO MAIN WORK HERE -- call bugdown to convert
    rendered_content = bugdown.convert(
        content,
        message=message,
        message_realm=realm,
        possible_words=possible_words,
        sent_by_bot=sent_by_bot,
        mention_data=mention_data,
        email_gateway=email_gateway
    )

    if message is not None:
        message.user_ids_with_alert_words = set()

        if realm_alert_words is not None:
            for user_id, words in realm_alert_words.items():
                if user_id in message_user_ids:
                    if set(words).intersection(message.alert_words):
                        message.user_ids_with_alert_words.add(user_id)

    return rendered_content
Esempio n. 14
0
def render_markdown(message,
                    content,
                    realm_id=None,
                    realm_alert_words=None,
                    message_users=None):
    # type: (Message, Text, Optional[int], Optional[RealmAlertWords], Set[UserProfile]) -> Text
    """Return HTML for given markdown. Bugdown may add properties to the
    message object such as `mentions_user_ids` and `mentions_wildcard`.
    These are only on this Django object and are not saved in the
    database.
    """

    if message_users is None:
        message_user_ids = set()  # type: Set[int]
    else:
        message_user_ids = {u.id for u in message_users}

    if message is not None:
        message.mentions_wildcard = False
        message.is_me_message = False
        message.mentions_user_ids = set()
        message.alert_words = set()
        message.links_for_preview = set()

        if realm_id is None:
            realm_id = message.sender.realm_id
        if message.sending_client.name == "zephyr_mirror" and message.sender.realm.is_zephyr_mirror_realm:
            # Use slightly customized Markdown processor for content
            # delivered via zephyr_mirror
            realm_id = bugdown.ZEPHYR_MIRROR_BUGDOWN_KEY

    possible_words = set()  # type: Set[Text]
    if realm_alert_words is not None:
        for user_id, words in realm_alert_words.items():
            if user_id in message_user_ids:
                possible_words.update(set(words))

    # DO MAIN WORK HERE -- call bugdown to convert
    rendered_content = bugdown.convert(content,
                                       realm_filters_key=realm_id,
                                       message=message,
                                       possible_words=possible_words)

    if message is not None:
        message.user_ids_with_alert_words = set()

        if realm_alert_words is not None:
            for user_id, words in realm_alert_words.items():
                if user_id in message_user_ids:
                    if set(words).intersection(message.alert_words):
                        message.user_ids_with_alert_words.add(user_id)

        message.is_me_message = Message.is_status_message(
            content, rendered_content)

    return rendered_content
Esempio n. 15
0
def render_markdown(message, content, realm=None, realm_alert_words=None, user_ids=None, mention_data=None):
    # type: (Message, Text, Optional[Realm], Optional[RealmAlertWords], Optional[Set[int]], Optional[bugdown.MentionData]) -> Text
    """Return HTML for given markdown. Bugdown may add properties to the
    message object such as `mentions_user_ids`, `mentions_user_group_ids`, and
    `mentions_wildcard`.  These are only on this Django object and are not
    saved in the database.
    """

    if user_ids is None:
        message_user_ids = set()  # type: Set[int]
    else:
        message_user_ids = user_ids

    if message is not None:
        message.mentions_wildcard = False
        message.mentions_user_ids = set()
        message.mentions_user_group_ids = set()
        message.alert_words = set()
        message.links_for_preview = set()

        if realm is None:
            realm = message.get_realm()

    possible_words = set()  # type: Set[Text]
    if realm_alert_words is not None:
        for user_id, words in realm_alert_words.items():
            if user_id in message_user_ids:
                possible_words.update(set(words))

    if message is None:
        # If we don't have a message, then we are in the compose preview
        # codepath, so we know we are dealing with a human.
        sent_by_bot = False
    else:
        sent_by_bot = get_user_profile_by_id(message.sender_id).is_bot

    # DO MAIN WORK HERE -- call bugdown to convert
    rendered_content = bugdown.convert(
        content,
        message=message,
        message_realm=realm,
        possible_words=possible_words,
        sent_by_bot=sent_by_bot,
        mention_data=mention_data,
    )

    if message is not None:
        message.user_ids_with_alert_words = set()

        if realm_alert_words is not None:
            for user_id, words in realm_alert_words.items():
                if user_id in message_user_ids:
                    if set(words).intersection(message.alert_words):
                        message.user_ids_with_alert_words.add(user_id)

    return rendered_content
Esempio n. 16
0
 def test_mit_rendering(self):
     msg = "**test**"
     converted = bugdown.convert(msg, "mit.edu/zephyr_mirror")
     self.assertEqual(
         converted,
         "<p>**test**</p>",
     )
     msg = "* test"
     converted = bugdown.convert(msg, "mit.edu/zephyr_mirror")
     self.assertEqual(
         converted,
         "<p>* test</p>",
     )
     msg = "https://lists.debian.org/debian-ctte/2014/02/msg00173.html"
     converted = bugdown.convert(msg, "mit.edu/zephyr_mirror")
     self.assertEqual(
         converted,
         '<p><a href="https://lists.debian.org/debian-ctte/2014/02/msg00173.html" target="_blank" title="https://lists.debian.org/debian-ctte/2014/02/msg00173.html">https://lists.debian.org/debian-ctte/2014/02/msg00173.html</a></p>',
     )
Esempio n. 17
0
 def test_mit_rendering(self):
     """Test the markdown configs for the MIT Zephyr mirroring system;
     verifies almost all inline patterns are disabled, but
     inline_interesting_links is still enabled"""
     msg = "**test**"
     converted = bugdown.convert(msg, "zephyr_mirror")
     self.assertEqual(
         converted,
         "<p>**test**</p>",
         )
     msg = "* test"
     converted = bugdown.convert(msg, "zephyr_mirror")
     self.assertEqual(
         converted,
         "<p>* test</p>",
         )
     msg = "https://lists.debian.org/debian-ctte/2014/02/msg00173.html"
     converted = bugdown.convert(msg, "zephyr_mirror")
     self.assertEqual(
         converted,
         '<p><a href="https://lists.debian.org/debian-ctte/2014/02/msg00173.html" target="_blank" title="https://lists.debian.org/debian-ctte/2014/02/msg00173.html">https://lists.debian.org/debian-ctte/2014/02/msg00173.html</a></p>',
         )
Esempio n. 18
0
def render_markdown(message, content, realm_id=None, realm_alert_words=None, message_users=None):
    # type: (Message, Text, Optional[int], Optional[RealmAlertWords], Set[UserProfile]) -> Text
    """Return HTML for given markdown. Bugdown may add properties to the
    message object such as `mentions_user_ids` and `mentions_wildcard`.
    These are only on this Django object and are not saved in the
    database.
    """

    if message_users is None:
        message_user_ids = set() # type: Set[int]
    else:
        message_user_ids = {u.id for u in message_users}

    if message is not None:
        message.mentions_wildcard = False
        message.is_me_message = False
        message.mentions_user_ids = set()
        message.alert_words = set()
        message.links_for_preview = set()

        if realm_id is None:
            realm_id = message.sender.realm_id
        if message.sending_client.name == "zephyr_mirror" and message.sender.realm.is_zephyr_mirror_realm:
            # Use slightly customized Markdown processor for content
            # delivered via zephyr_mirror
            realm_id = bugdown.ZEPHYR_MIRROR_BUGDOWN_KEY

    possible_words = set() # type: Set[Text]
    if realm_alert_words is not None:
        for user_id, words in realm_alert_words.items():
            if user_id in message_user_ids:
                possible_words.update(set(words))

    # DO MAIN WORK HERE -- call bugdown to convert
    rendered_content = bugdown.convert(content, realm_filters_key=realm_id, message=message,
                                       possible_words=possible_words)

    if message is not None:
        message.user_ids_with_alert_words = set()

        if realm_alert_words is not None:
            for user_id, words in realm_alert_words.items():
                if user_id in message_user_ids:
                    if set(words).intersection(message.alert_words):
                        message.user_ids_with_alert_words.add(user_id)

        message.is_me_message = Message.is_status_message(content, rendered_content)

    return rendered_content
Esempio n. 19
0
    def test_realm_patterns(self):
        RealmFilter(
            realm=get_realm('zulip.com'),
            pattern=r"#(?P<id>[0-9]{2,8})",
            url_format_string=r"https://trac.zulip.net/ticket/%(id)s").save()
        msg = Message(sender=get_user_profile_by_email("*****@*****.**"))

        content = "We should fix #224 and #115, but not issue#124 or #1124z or [trac #15](https://trac.zulip.net/ticket/16) today."
        converted = bugdown.convert(content,
                                    realm_domain='zulip.com',
                                    message=msg)

        self.assertEqual(
            converted,
            '<p>We should fix <a href="https://trac.zulip.net/ticket/224" target="_blank" title="https://trac.zulip.net/ticket/224">#224</a> and <a href="https://trac.zulip.net/ticket/115" target="_blank" title="https://trac.zulip.net/ticket/115">#115</a>, but not issue#124 or #1124z or <a href="https://trac.zulip.net/ticket/16" target="_blank" title="https://trac.zulip.net/ticket/16">trac #15</a> today.</p>'
        )
Esempio n. 20
0
def do_render_markdown(message: Message,
                       content: str,
                       realm: Realm,
                       realm_alert_words: RealmAlertWords,
                       message_user_ids: Set[int],
                       sent_by_bot: bool,
                       translate_emoticons: bool,
                       mention_data: Optional[bugdown.MentionData]=None,
                       email_gateway: Optional[bool]=False) -> str:
    """Return HTML for given markdown. Bugdown may add properties to the
    message object such as `mentions_user_ids`, `mentions_user_group_ids`, and
    `mentions_wildcard`.  These are only on this Django object and are not
    saved in the database.
    """

    message.mentions_wildcard = False
    message.mentions_user_ids = set()
    message.mentions_user_group_ids = set()
    message.alert_words = set()
    message.links_for_preview = set()

    possible_words = set()  # type: Set[str]
    for user_id, words in realm_alert_words.items():
        if user_id in message_user_ids:
            possible_words.update(set(words))

    # DO MAIN WORK HERE -- call bugdown to convert
    rendered_content = bugdown.convert(
        content,
        message=message,
        message_realm=realm,
        possible_words=possible_words,
        sent_by_bot=sent_by_bot,
        translate_emoticons=translate_emoticons,
        mention_data=mention_data,
        email_gateway=email_gateway
    )

    message.user_ids_with_alert_words = set()

    for user_id, words in realm_alert_words.items():
        if user_id in message_user_ids:
            if set(words).intersection(message.alert_words):
                message.user_ids_with_alert_words.add(user_id)

    return rendered_content
Esempio n. 21
0
def do_render_markdown(message: Message,
                       content: str,
                       realm: Realm,
                       realm_alert_words: RealmAlertWords,
                       message_user_ids: Set[int],
                       sent_by_bot: bool,
                       translate_emoticons: bool,
                       mention_data: Optional[bugdown.MentionData]=None,
                       email_gateway: Optional[bool]=False) -> str:
    """Return HTML for given markdown. Bugdown may add properties to the
    message object such as `mentions_user_ids`, `mentions_user_group_ids`, and
    `mentions_wildcard`.  These are only on this Django object and are not
    saved in the database.
    """

    message.mentions_wildcard = False
    message.mentions_user_ids = set()
    message.mentions_user_group_ids = set()
    message.alert_words = set()
    message.links_for_preview = set()

    possible_words = set()  # type: Set[str]
    for user_id, words in realm_alert_words.items():
        if user_id in message_user_ids:
            possible_words.update(set(words))

    # DO MAIN WORK HERE -- call bugdown to convert
    rendered_content = bugdown.convert(
        content,
        message=message,
        message_realm=realm,
        possible_words=possible_words,
        sent_by_bot=sent_by_bot,
        translate_emoticons=translate_emoticons,
        mention_data=mention_data,
        email_gateway=email_gateway
    )

    message.user_ids_with_alert_words = set()

    for user_id, words in realm_alert_words.items():
        if user_id in message_user_ids:
            if set(words).intersection(message.alert_words):
                message.user_ids_with_alert_words.add(user_id)

    return rendered_content
Esempio n. 22
0
def render_markdown(message, content, realm=None, realm_alert_words=None, message_users=None):
    # type: (Message, Text, Optional[Realm], Optional[RealmAlertWords], Set[UserProfile]) -> Text
    """Return HTML for given markdown. Bugdown may add properties to the
    message object such as `mentions_user_ids` and `mentions_wildcard`.
    These are only on this Django object and are not saved in the
    database.
    """

    if message_users is None:
        message_user_ids = set() # type: Set[int]
    else:
        message_user_ids = {u.id for u in message_users}

    if message is not None:
        message.mentions_wildcard = False
        message.is_me_message = False
        message.mentions_user_ids = set()
        message.alert_words = set()
        message.links_for_preview = set()

        if realm is None:
            realm = message.get_realm()

    possible_words = set() # type: Set[Text]
    if realm_alert_words is not None:
        for user_id, words in realm_alert_words.items():
            if user_id in message_user_ids:
                possible_words.update(set(words))

    # DO MAIN WORK HERE -- call bugdown to convert
    rendered_content = bugdown.convert(content, message=message, message_realm=realm,
                                       possible_words=possible_words)

    if message is not None:
        message.user_ids_with_alert_words = set()

        if realm_alert_words is not None:
            for user_id, words in realm_alert_words.items():
                if user_id in message_user_ids:
                    if set(words).intersection(message.alert_words):
                        message.user_ids_with_alert_words.add(user_id)

        message.is_me_message = Message.is_status_message(content, rendered_content)

    return rendered_content
Esempio n. 23
0
    def test_realm_patterns(self):
        realm = get_realm('zulip.com')
        url_format_string = r"https://trac.zulip.net/ticket/%(id)s"
        realm_filter = RealmFilter(realm=realm,
                                   pattern=r"#(?P<id>[0-9]{2,8})",
                                   url_format_string=url_format_string)
        realm_filter.save()
        self.assertEqual(
            str(realm_filter),
            '<RealmFilter(zulip.com): #(?P<id>[0-9]{2,8})'
            ' https://trac.zulip.net/ticket/%(id)s>')


        msg = Message(sender=get_user_profile_by_email("*****@*****.**"),
                      subject="#444")

        content = "We should fix #224 and #115, but not issue#124 or #1124z or [trac #15](https://trac.zulip.net/ticket/16) today."
        converted = bugdown.convert(content, realm_domain='zulip.com', message=msg)
        converted_subject = bugdown.subject_links(realm.domain.lower(), msg.subject)

        self.assertEqual(converted, '<p>We should fix <a href="https://trac.zulip.net/ticket/224" target="_blank" title="https://trac.zulip.net/ticket/224">#224</a> and <a href="https://trac.zulip.net/ticket/115" target="_blank" title="https://trac.zulip.net/ticket/115">#115</a>, but not issue#124 or #1124z or <a href="https://trac.zulip.net/ticket/16" target="_blank" title="https://trac.zulip.net/ticket/16">trac #15</a> today.</p>')
        self.assertEqual(converted_subject,  [u'https://trac.zulip.net/ticket/444'])
Esempio n. 24
0
def zulip_default_context(request):
    # type: (HttpRequest) -> Dict[str, Any]
    """Context available to all Zulip Jinja2 templates that have a request
    passed in.  Designed to provide the long list of variables at the
    bottom of this function in a wide range of situations: logged-in
    or logged-out, subdomains or not, etc.

    The main variable in the below is whether we know the realm, which
    is the case if there is only one realm, or we're on a
    REALMS_HAVE_SUBDOMAINS subdomain, or the user is logged in.
    """
    realm = get_realm_from_request(request)

    if realm is not None:
        realm_uri = realm.uri
        realm_name = realm.name
        realm_icon = get_realm_icon_url(realm)
        realm_description_raw = realm.description or "The coolest place in the universe."
        realm_description = convert(realm_description_raw, message_realm=realm)
    else:
        realm_uri = settings.SERVER_URI
        realm_name = None
        realm_icon = None
        realm_description = None

    register_link_disabled = settings.REGISTER_LINK_DISABLED
    login_link_disabled = settings.LOGIN_LINK_DISABLED
    about_link_disabled = settings.ABOUT_LINK_DISABLED
    find_team_link_disabled = settings.FIND_TEAM_LINK_DISABLED
    if settings.SUBDOMAINS_HOMEPAGE and get_subdomain(request) == "":
        register_link_disabled = True
        login_link_disabled = True
        about_link_disabled = True
        find_team_link_disabled = False

    apps_page_url = 'https://zulipchat.com/apps/'
    if settings.ZILENCER_ENABLED:
        apps_page_url = '/apps/'

    return {
        'realms_have_subdomains': settings.REALMS_HAVE_SUBDOMAINS,
        'custom_logo_url': settings.CUSTOM_LOGO_URL,
        'register_link_disabled': register_link_disabled,
        'login_link_disabled': login_link_disabled,
        'about_link_disabled': about_link_disabled,
        'terms_of_service': settings.TERMS_OF_SERVICE,
        'privacy_policy': settings.PRIVACY_POLICY,
        'login_url': settings.HOME_NOT_LOGGED_IN,
        'only_sso': settings.ONLY_SSO,
        'external_api_path': settings.EXTERNAL_API_PATH,
        'external_api_uri': settings.EXTERNAL_API_URI,
        'external_host': settings.EXTERNAL_HOST,
        'external_uri_scheme': settings.EXTERNAL_URI_SCHEME,
        'realm_uri': realm_uri,
        'realm_name': realm_name,
        'realm_icon': realm_icon,
        'realm_description': realm_description,
        'server_uri': settings.SERVER_URI,
        'api_site_required': settings.EXTERNAL_API_PATH != "api.zulip.com",
        'email_gateway_example': settings.EMAIL_GATEWAY_EXAMPLE,
        'apps_page_url': apps_page_url,
        'open_realm_creation': settings.OPEN_REALM_CREATION,
        'password_auth_enabled': password_auth_enabled(realm),
        'dev_auth_enabled': dev_auth_enabled(realm),
        'google_auth_enabled': google_auth_enabled(realm),
        'github_auth_enabled': github_auth_enabled(realm),
        'any_oauth_backend_enabled': any_oauth_backend_enabled(realm),
        'no_auth_enabled': not auth_enabled_helper(list(AUTH_BACKEND_NAME_MAP.keys()), realm),
        'development_environment': settings.DEVELOPMENT,
        'support_email': FromAddress.SUPPORT,
        'find_team_link_disabled': find_team_link_disabled,
        'password_min_length': settings.PASSWORD_MIN_LENGTH,
        'password_min_quality': settings.PASSWORD_MIN_ZXCVBN_QUALITY,
        'zulip_version': ZULIP_VERSION,
    }
Esempio n. 25
0
def zulip_default_context(request):
    # type: (HttpRequest) -> Dict[str, Any]
    """Context available to all Zulip Jinja2 templates that have a request
    passed in.  Designed to provide the long list of variables at the
    bottom of this function in a wide range of situations: logged-in
    or logged-out, subdomains or not, etc.

    The main variable in the below is whether we know what realm the
    user is trying to interact with.
    """
    realm = get_realm_from_request(request)

    if realm is None:
        realm_uri = settings.ROOT_DOMAIN_URI
        realm_name = None
        realm_icon = None
        realm_description = None
        realm_invite_required = False
    else:
        realm_uri = realm.uri
        realm_name = realm.name
        realm_icon = get_realm_icon_url(realm)
        realm_description_raw = realm.description or "The coolest place in the universe."
        realm_description = convert(realm_description_raw, message_realm=realm)
        realm_invite_required = realm.invite_required

    register_link_disabled = settings.REGISTER_LINK_DISABLED
    login_link_disabled = settings.LOGIN_LINK_DISABLED
    about_link_disabled = settings.ABOUT_LINK_DISABLED
    find_team_link_disabled = settings.FIND_TEAM_LINK_DISABLED

    if settings.ROOT_DOMAIN_LANDING_PAGE and get_subdomain(request) == "":
        register_link_disabled = True
        login_link_disabled = True
        about_link_disabled = True
        find_team_link_disabled = False

    apps_page_url = 'https://zulipchat.com/apps/'
    if settings.ZILENCER_ENABLED:
        apps_page_url = '/apps/'

    user_is_authenticated = False
    if hasattr(request, 'user') and hasattr(request.user, 'is_authenticated'):
        user_is_authenticated = request.user.is_authenticated.value

    if settings.DEVELOPMENT:
        secrets_path = "zproject/dev-secrets.conf"
        settings_path = "zproject/dev_settings.py"
        settings_comments_path = "zproject/prod_settings_template.py"
    else:
        secrets_path = "/etc/zulip/zulip-secrets.conf"
        settings_path = "/etc/zulip/settings.py"
        settings_comments_path = "/etc/zulip/settings.py"

    if hasattr(request, "client") and request.client.name == "ZulipElectron":
        platform = "ZulipElectron"  # nocoverage
    else:
        platform = "ZulipWeb"

    return {
        'root_domain_landing_page':
        settings.ROOT_DOMAIN_LANDING_PAGE,
        'custom_logo_url':
        settings.CUSTOM_LOGO_URL,
        'register_link_disabled':
        register_link_disabled,
        'login_link_disabled':
        login_link_disabled,
        'about_link_disabled':
        about_link_disabled,
        'terms_of_service':
        settings.TERMS_OF_SERVICE,
        'privacy_policy':
        settings.PRIVACY_POLICY,
        'login_url':
        settings.HOME_NOT_LOGGED_IN,
        'only_sso':
        settings.ONLY_SSO,
        'external_api_path':
        settings.EXTERNAL_API_PATH,
        'external_api_uri':
        settings.EXTERNAL_API_URI,
        'external_host':
        settings.EXTERNAL_HOST,
        'external_uri_scheme':
        settings.EXTERNAL_URI_SCHEME,
        'realm_invite_required':
        realm_invite_required,
        'realm_uri':
        realm_uri,
        'realm_name':
        realm_name,
        'realm_icon':
        realm_icon,
        'realm_description':
        realm_description,
        'root_domain_uri':
        settings.ROOT_DOMAIN_URI,
        'api_site_required':
        settings.EXTERNAL_API_PATH != "api.zulip.com",
        'email_gateway_example':
        settings.EMAIL_GATEWAY_EXAMPLE,
        'apps_page_url':
        apps_page_url,
        'open_realm_creation':
        settings.OPEN_REALM_CREATION,
        'password_auth_enabled':
        password_auth_enabled(realm),
        'dev_auth_enabled':
        dev_auth_enabled(realm),
        'google_auth_enabled':
        google_auth_enabled(realm),
        'github_auth_enabled':
        github_auth_enabled(realm),
        'email_auth_enabled':
        email_auth_enabled(realm),
        'require_email_format_usernames':
        require_email_format_usernames(realm),
        'any_oauth_backend_enabled':
        any_oauth_backend_enabled(realm),
        'no_auth_enabled':
        not auth_enabled_helper(list(AUTH_BACKEND_NAME_MAP.keys()), realm),
        'development_environment':
        settings.DEVELOPMENT,
        'support_email':
        FromAddress.SUPPORT,
        'find_team_link_disabled':
        find_team_link_disabled,
        'password_min_length':
        settings.PASSWORD_MIN_LENGTH,
        'password_min_guesses':
        settings.PASSWORD_MIN_GUESSES,
        'zulip_version':
        ZULIP_VERSION,
        'user_is_authenticated':
        user_is_authenticated,
        'settings_path':
        settings_path,
        'secrets_path':
        secrets_path,
        'settings_comments_path':
        settings_comments_path,
        'platform':
        platform,
    }
Esempio n. 26
0
def zulip_default_context(request: HttpRequest) -> Dict[str, Any]:
    """Context available to all Zulip Jinja2 templates that have a request
    passed in.  Designed to provide the long list of variables at the
    bottom of this function in a wide range of situations: logged-in
    or logged-out, subdomains or not, etc.

    The main variable in the below is whether we know what realm the
    user is trying to interact with.
    """
    realm = get_realm_from_request(request)

    if realm is None:
        realm_uri = settings.ROOT_DOMAIN_URI
        realm_name = None
        realm_icon = None
        realm_description = None
        realm_invite_required = False
    else:
        realm_uri = realm.uri
        realm_name = realm.name
        realm_icon = get_realm_icon_url(realm)
        realm_description_raw = realm.description or "The coolest place in the universe."
        realm_description = convert(realm_description_raw, message_realm=realm)
        realm_invite_required = realm.invite_required

    register_link_disabled = settings.REGISTER_LINK_DISABLED
    login_link_disabled = settings.LOGIN_LINK_DISABLED
    find_team_link_disabled = settings.FIND_TEAM_LINK_DISABLED
    allow_search_engine_indexing = False

    if (settings.ROOT_DOMAIN_LANDING_PAGE
            and get_subdomain(request) == Realm.SUBDOMAIN_FOR_ROOT_DOMAIN):
        register_link_disabled = True
        login_link_disabled = True
        find_team_link_disabled = False
        allow_search_engine_indexing = True

    apps_page_url = 'https://zulipchat.com/apps/'
    if settings.ZILENCER_ENABLED:
        apps_page_url = '/apps/'

    user_is_authenticated = False
    if hasattr(request, 'user') and hasattr(request.user, 'is_authenticated'):
        user_is_authenticated = request.user.is_authenticated.value

    if settings.DEVELOPMENT:
        secrets_path = "zproject/dev-secrets.conf"
        settings_path = "zproject/dev_settings.py"
        settings_comments_path = "zproject/prod_settings_template.py"
    else:
        secrets_path = "/etc/zulip/zulip-secrets.conf"
        settings_path = "/etc/zulip/settings.py"
        settings_comments_path = "/etc/zulip/settings.py"

    if hasattr(request, "client") and request.client.name == "ZulipElectron":
        platform = "ZulipElectron"  # nocoverage
    else:
        platform = "ZulipWeb"

    return {
        'root_domain_landing_page': settings.ROOT_DOMAIN_LANDING_PAGE,
        'custom_logo_url': settings.CUSTOM_LOGO_URL,
        'register_link_disabled': register_link_disabled,
        'login_link_disabled': login_link_disabled,
        'terms_of_service': settings.TERMS_OF_SERVICE,
        'privacy_policy': settings.PRIVACY_POLICY,
        'login_url': settings.HOME_NOT_LOGGED_IN,
        'only_sso': settings.ONLY_SSO,
        'custom_profile_fields_enabled': settings.DEVELOPMENT,
        'external_host': settings.EXTERNAL_HOST,
        'external_uri_scheme': settings.EXTERNAL_URI_SCHEME,
        'realm_invite_required': realm_invite_required,
        'realm_uri': realm_uri,
        'realm_name': realm_name,
        'realm_icon': realm_icon,
        'realm_description': realm_description,
        'root_domain_uri': settings.ROOT_DOMAIN_URI,
        'apps_page_url': apps_page_url,
        'open_realm_creation': settings.OPEN_REALM_CREATION,
        'password_auth_enabled': password_auth_enabled(realm),
        'dev_auth_enabled': dev_auth_enabled(realm),
        'google_auth_enabled': google_auth_enabled(realm),
        'github_auth_enabled': github_auth_enabled(realm),
        'email_auth_enabled': email_auth_enabled(realm),
        'require_email_format_usernames': require_email_format_usernames(realm),
        'any_oauth_backend_enabled': any_oauth_backend_enabled(realm),
        'no_auth_enabled': not auth_enabled_helper(list(AUTH_BACKEND_NAME_MAP.keys()), realm),
        'development_environment': settings.DEVELOPMENT,
        'support_email': FromAddress.SUPPORT,
        'find_team_link_disabled': find_team_link_disabled,
        'password_min_length': settings.PASSWORD_MIN_LENGTH,
        'password_min_guesses': settings.PASSWORD_MIN_GUESSES,
        'jitsi_server_url': settings.JITSI_SERVER_URL,
        'two_factor_authentication_enabled': settings.TWO_FACTOR_AUTHENTICATION_ENABLED,
        'zulip_version': ZULIP_VERSION,
        'user_is_authenticated': user_is_authenticated,
        'settings_path': settings_path,
        'secrets_path': secrets_path,
        'settings_comments_path': settings_comments_path,
        'platform': platform,
        'allow_search_engine_indexing': allow_search_engine_indexing,
    }
Esempio n. 27
0
def bugdown_convert(text):
    return bugdown.convert(text, "zulip.com")
Esempio n. 28
0
 def test_bugdown_error_handling(self):
     # type: () -> None
     with self.simulated_markdown_failure():
         with self.assertRaises(bugdown.BugdownRenderingException):
             bugdown.convert('', 'zulip.com')
Esempio n. 29
0
def render_message_backend(request, user_profile, content=REQ):
    rendered_content = bugdown.convert(content, user_profile.realm.domain)
    return json_success({"rendered": rendered_content})
Esempio n. 30
0
def render_message_backend(request, user_profile, content=REQ()):
    # type: (HttpRequest, UserProfile, text_type) -> HttpResponse
    rendered_content = bugdown.convert(content, user_profile.realm.domain)
    return json_success({"rendered": rendered_content})
Esempio n. 31
0
def zulip_default_context(request):
    # type: (HttpRequest) -> Dict[str, Any]
    """Context available to all Zulip Jinja2 templates that have a request
    passed in.  Designed to provide the long list of variables at the
    bottom of this function in a wide range of situations: logged-in
    or logged-out, subdomains or not, etc.

    The main variable in the below is whether we know the realm, which
    is the case if there is only one realm, or we're on a
    REALMS_HAVE_SUBDOMAINS subdomain, or the user is logged in.
    """
    realm = get_realm_from_request(request)

    if realm is not None:
        realm_uri = realm.uri
        realm_name = realm.name
        realm_icon = get_realm_icon_url(realm)
        realm_description_raw = realm.description or "The coolest place in the universe."
        realm_description = convert(realm_description_raw, message_realm=realm)
    else:
        realm_uri = settings.SERVER_URI
        realm_name = None
        realm_icon = None
        realm_description = None

    register_link_disabled = settings.REGISTER_LINK_DISABLED
    login_link_disabled = settings.LOGIN_LINK_DISABLED
    about_link_disabled = settings.ABOUT_LINK_DISABLED
    find_team_link_disabled = settings.FIND_TEAM_LINK_DISABLED
    if settings.SUBDOMAINS_HOMEPAGE and get_subdomain(request) == "":
        register_link_disabled = True
        login_link_disabled = True
        about_link_disabled = True
        find_team_link_disabled = False

    return {
        'realms_have_subdomains':
        settings.REALMS_HAVE_SUBDOMAINS,
        'custom_logo_url':
        settings.CUSTOM_LOGO_URL,
        'register_link_disabled':
        register_link_disabled,
        'login_link_disabled':
        login_link_disabled,
        'about_link_disabled':
        about_link_disabled,
        'show_oss_announcement':
        settings.SHOW_OSS_ANNOUNCEMENT,
        'zulip_admin':
        settings.ZULIP_ADMINISTRATOR,
        'terms_of_service':
        settings.TERMS_OF_SERVICE,
        'privacy_policy':
        settings.PRIVACY_POLICY,
        'login_url':
        settings.HOME_NOT_LOGGED_IN,
        'only_sso':
        settings.ONLY_SSO,
        'external_api_path':
        settings.EXTERNAL_API_PATH,
        'external_api_uri':
        settings.EXTERNAL_API_URI,
        'external_host':
        settings.EXTERNAL_HOST,
        'external_uri_scheme':
        settings.EXTERNAL_URI_SCHEME,
        'realm_uri':
        realm_uri,
        'realm_name':
        realm_name,
        'realm_icon':
        realm_icon,
        'realm_description':
        realm_description,
        'server_uri':
        settings.SERVER_URI,
        'api_site_required':
        settings.EXTERNAL_API_PATH != "api.zulip.com",
        'email_gateway_example':
        settings.EMAIL_GATEWAY_EXAMPLE,
        'open_realm_creation':
        settings.OPEN_REALM_CREATION,
        'password_auth_enabled':
        password_auth_enabled(realm),
        'dev_auth_enabled':
        dev_auth_enabled(realm),
        'google_auth_enabled':
        google_auth_enabled(realm),
        'github_auth_enabled':
        github_auth_enabled(realm),
        'any_oauth_backend_enabled':
        any_oauth_backend_enabled(realm),
        'no_auth_enabled':
        not auth_enabled_helper(list(AUTH_BACKEND_NAME_MAP.keys()), realm),
        'development_environment':
        settings.DEVELOPMENT,
        'support_email':
        settings.ZULIP_ADMINISTRATOR,
        'find_team_link_disabled':
        find_team_link_disabled,
        'password_min_length':
        settings.PASSWORD_MIN_LENGTH,
        'password_min_quality':
        settings.PASSWORD_MIN_ZXCVBN_QUALITY,
        'zulip_version':
        ZULIP_VERSION,
    }
Esempio n. 32
0
def render_message_backend(request, user_profile, content=REQ()):
    rendered_content = bugdown.convert(content, user_profile.realm.domain)
    return json_success({"rendered": rendered_content})
Esempio n. 33
0
def render_message_backend(request, user_profile, content=REQ()):
    # type: (HttpRequest, UserProfile, text_type) -> HttpResponse
    rendered_content = bugdown.convert(content, user_profile.realm.domain)
    return json_success({"rendered": rendered_content})
Esempio n. 34
0
def bugdown_convert(text):
    return bugdown.convert(text, "zulip.com")