예제 #1
0
    def build_message_dict(
            message: Optional[Message], message_id: int,
            last_edit_time: Optional[datetime.datetime],
            edit_history: Optional[str], content: str, subject: str,
            pub_date: datetime.datetime, rendered_content: Optional[str],
            rendered_content_version: Optional[int], sender_id: int,
            sender_realm_id: int, sending_client_name: str, recipient_id: int,
            recipient_type: int, recipient_type_id: int,
            reactions: List[Dict[str, Any]],
            submessages: List[Dict[str, Any]]) -> Dict[str, Any]:

        obj = dict(id=message_id,
                   sender_id=sender_id,
                   content=content,
                   recipient_type_id=recipient_type_id,
                   recipient_type=recipient_type,
                   recipient_id=recipient_id,
                   subject=subject,
                   timestamp=datetime_to_timestamp(pub_date),
                   client=sending_client_name)

        obj['sender_realm_id'] = sender_realm_id

        obj['raw_display_recipient'] = get_display_recipient_by_id(
            recipient_id, recipient_type, recipient_type_id)

        obj['subject_links'] = bugdown.topic_links(sender_realm_id, subject)

        if last_edit_time is not None:
            obj['last_edit_timestamp'] = datetime_to_timestamp(last_edit_time)
            assert edit_history is not None
            obj['edit_history'] = ujson.loads(edit_history)

        if Message.need_to_render_content(rendered_content,
                                          rendered_content_version,
                                          bugdown.version):
            if message is None:
                # We really shouldn't be rendering objects in this method, but there is
                # a scenario where we upgrade the version of bugdown and fail to run
                # management commands to re-render historical messages, and then we
                # need to have side effects.  This method is optimized to not need full
                # blown ORM objects, but the bugdown renderer is unfortunately highly
                # coupled to Message, and we also need to persist the new rendered content.
                # If we don't have a message object passed in, we get one here.  The cost
                # of going to the DB here should be overshadowed by the cost of rendering
                # and updating the row.
                # TODO: see #1379 to eliminate bugdown dependencies
                message = Message.objects.select_related().get(id=message_id)

            assert message is not None  # Hint for mypy.
            # It's unfortunate that we need to have side effects on the message
            # in some cases.
            rendered_content = save_message_rendered_content(message, content)

        if rendered_content is not None:
            obj['rendered_content'] = rendered_content
        else:
            obj['rendered_content'] = (
                '<p>[Zulip note: Sorry, we could not ' +
                'understand the formatting of your message]</p>')

        if rendered_content is not None:
            obj['is_me_message'] = Message.is_status_message(
                content, rendered_content)
        else:
            obj['is_me_message'] = False

        obj['reactions'] = [
            ReactionDict.build_dict_from_raw_db_row(reaction)
            for reaction in reactions
        ]
        obj['submessages'] = submessages
        return obj
예제 #2
0
    def build_message_dict(
            message: Optional[Message], message_id: int,
            last_edit_time: Optional[datetime.datetime],
            edit_history: Optional[str], content: str, topic_name: str,
            date_sent: datetime.datetime, rendered_content: Optional[str],
            rendered_content_version: Optional[int], sender_id: int,
            sender_realm_id: int, sending_client_name: str, recipient_id: int,
            recipient_type: int, recipient_type_id: int,
            reactions: List[Dict[str, Any]],
            submessages: List[Dict[str, Any]]) -> Dict[str, Any]:

        obj = dict(id=message_id,
                   sender_id=sender_id,
                   content=content,
                   recipient_type_id=recipient_type_id,
                   recipient_type=recipient_type,
                   recipient_id=recipient_id,
                   timestamp=datetime_to_timestamp(date_sent),
                   client=sending_client_name)

        obj[TOPIC_NAME] = topic_name
        obj['sender_realm_id'] = sender_realm_id

        # Render topic_links with the stream's realm instead of the
        # user's realm; this is important for messages sent by
        # cross-realm bots like NOTIFICATION_BOT.
        #
        # TODO: We could potentially avoid this database query in
        # common cases by optionally passing through the
        # stream_realm_id through the code path from do_send_messages
        # (where we've already fetched the data).  It would involve
        # somewhat messy plumbing, but would probably be worth it.
        rendering_realm_id = sender_realm_id
        if message and recipient_type == Recipient.STREAM:
            rendering_realm_id = Stream.objects.get(
                id=recipient_type_id).realm_id

        obj[TOPIC_LINKS] = bugdown.topic_links(rendering_realm_id, topic_name)

        if last_edit_time is not None:
            obj['last_edit_timestamp'] = datetime_to_timestamp(last_edit_time)
            assert edit_history is not None
            obj['edit_history'] = ujson.loads(edit_history)

        if Message.need_to_render_content(rendered_content,
                                          rendered_content_version,
                                          bugdown.version):
            if message is None:
                # We really shouldn't be rendering objects in this method, but there is
                # a scenario where we upgrade the version of bugdown and fail to run
                # management commands to re-render historical messages, and then we
                # need to have side effects.  This method is optimized to not need full
                # blown ORM objects, but the bugdown renderer is unfortunately highly
                # coupled to Message, and we also need to persist the new rendered content.
                # If we don't have a message object passed in, we get one here.  The cost
                # of going to the DB here should be overshadowed by the cost of rendering
                # and updating the row.
                # TODO: see #1379 to eliminate bugdown dependencies
                message = Message.objects.select_related().get(id=message_id)

            assert message is not None  # Hint for mypy.
            # It's unfortunate that we need to have side effects on the message
            # in some cases.
            rendered_content = save_message_rendered_content(message, content)

        if rendered_content is not None:
            obj['rendered_content'] = rendered_content
        else:
            obj['rendered_content'] = (
                '<p>[Zulip note: Sorry, we could not ' +
                'understand the formatting of your message]</p>')

        if rendered_content is not None:
            obj['is_me_message'] = Message.is_status_message(
                content, rendered_content)
        else:
            obj['is_me_message'] = False

        obj['reactions'] = [
            ReactionDict.build_dict_from_raw_db_row(reaction)
            for reaction in reactions
        ]
        obj['submessages'] = submessages
        return obj
예제 #3
0
파일: message.py 프로젝트: brainwane/zulip
    def build_message_dict(
            message: Optional[Message],
            message_id: int,
            last_edit_time: Optional[datetime.datetime],
            edit_history: Optional[str],
            content: str,
            topic_name: str,
            pub_date: datetime.datetime,
            rendered_content: Optional[str],
            rendered_content_version: Optional[int],
            sender_id: int,
            sender_realm_id: int,
            sending_client_name: str,
            recipient_id: int,
            recipient_type: int,
            recipient_type_id: int,
            reactions: List[Dict[str, Any]],
            submessages: List[Dict[str, Any]]
    ) -> Dict[str, Any]:

        obj = dict(
            id                = message_id,
            sender_id         = sender_id,
            content           = content,
            recipient_type_id = recipient_type_id,
            recipient_type    = recipient_type,
            recipient_id      = recipient_id,
            timestamp         = datetime_to_timestamp(pub_date),
            client            = sending_client_name)

        obj[TOPIC_NAME] = topic_name
        obj['sender_realm_id'] = sender_realm_id

        obj['raw_display_recipient'] = get_display_recipient_by_id(
            recipient_id,
            recipient_type,
            recipient_type_id
        )

        obj[TOPIC_LINKS] = bugdown.topic_links(sender_realm_id, topic_name)

        if last_edit_time is not None:
            obj['last_edit_timestamp'] = datetime_to_timestamp(last_edit_time)
            assert edit_history is not None
            obj['edit_history'] = ujson.loads(edit_history)

        if Message.need_to_render_content(rendered_content, rendered_content_version, bugdown.version):
            if message is None:
                # We really shouldn't be rendering objects in this method, but there is
                # a scenario where we upgrade the version of bugdown and fail to run
                # management commands to re-render historical messages, and then we
                # need to have side effects.  This method is optimized to not need full
                # blown ORM objects, but the bugdown renderer is unfortunately highly
                # coupled to Message, and we also need to persist the new rendered content.
                # If we don't have a message object passed in, we get one here.  The cost
                # of going to the DB here should be overshadowed by the cost of rendering
                # and updating the row.
                # TODO: see #1379 to eliminate bugdown dependencies
                message = Message.objects.select_related().get(id=message_id)

            assert message is not None  # Hint for mypy.
            # It's unfortunate that we need to have side effects on the message
            # in some cases.
            rendered_content = save_message_rendered_content(message, content)

        if rendered_content is not None:
            obj['rendered_content'] = rendered_content
        else:
            obj['rendered_content'] = ('<p>[Zulip note: Sorry, we could not ' +
                                       'understand the formatting of your message]</p>')

        if rendered_content is not None:
            obj['is_me_message'] = Message.is_status_message(content, rendered_content)
        else:
            obj['is_me_message'] = False

        obj['reactions'] = [ReactionDict.build_dict_from_raw_db_row(reaction)
                            for reaction in reactions]
        obj['submessages'] = submessages
        return obj