Exemplo n.º 1
0
    def make_summary_text(self, notifs_by_room, room_state_ids, notif_events,
                          user_id, reason):
        if len(notifs_by_room) == 1:
            # Only one room has new stuff
            room_id = notifs_by_room.keys()[0]

            # If the room has some kind of name, use it, but we don't
            # want the generated-from-names one here otherwise we'll
            # end up with, "new message from Bob in the Bob room"
            room_name = yield calculate_room_name(self.store,
                                                  room_state_ids[room_id],
                                                  user_id,
                                                  fallback_to_members=False)

            my_member_event_id = room_state_ids[room_id][("m.room.member",
                                                          user_id)]
            my_member_event = yield self.store.get_event(my_member_event_id)
            if my_member_event.content["membership"] == "invite":
                inviter_member_event_id = room_state_ids[room_id][(
                    "m.room.member", my_member_event.sender)]
                inviter_member_event = yield self.store.get_event(
                    inviter_member_event_id)
                inviter_name = name_from_member_event(inviter_member_event)

                if room_name is None:
                    defer.returnValue(INVITE_FROM_PERSON % {
                        "person": inviter_name,
                        "app": self.app_name
                    })
                else:
                    defer.returnValue(
                        INVITE_FROM_PERSON_TO_ROOM % {
                            "person": inviter_name,
                            "room": room_name,
                            "app": self.app_name,
                        })

            sender_name = None
            if len(notifs_by_room[room_id]) == 1:
                # There is just the one notification, so give some detail
                event = notif_events[notifs_by_room[room_id][0]["event_id"]]
                if ("m.room.member", event.sender) in room_state_ids[room_id]:
                    state_event_id = room_state_ids[room_id][("m.room.member",
                                                              event.sender)]
                    state_event = yield self.store.get_event(state_event_id)
                    sender_name = name_from_member_event(state_event)

                if sender_name is not None and room_name is not None:
                    defer.returnValue(
                        MESSAGE_FROM_PERSON_IN_ROOM % {
                            "person": sender_name,
                            "room": room_name,
                            "app": self.app_name,
                        })
                elif sender_name is not None:
                    defer.returnValue(MESSAGE_FROM_PERSON % {
                        "person": sender_name,
                        "app": self.app_name,
                    })
            else:
                # There's more than one notification for this room, so just
                # say there are several
                if room_name is not None:
                    defer.returnValue(MESSAGES_IN_ROOM % {
                        "room": room_name,
                        "app": self.app_name,
                    })
                else:
                    # If the room doesn't have a name, say who the messages
                    # are from explicitly to avoid, "messages in the Bob room"
                    sender_ids = list(
                        set([
                            notif_events[n['event_id']].sender
                            for n in notifs_by_room[room_id]
                        ]))

                    member_events = yield self.store.get_events([
                        room_state_ids[room_id][("m.room.member", s)]
                        for s in sender_ids
                    ])

                    defer.returnValue(
                        MESSAGES_FROM_PERSON % {
                            "person":
                            descriptor_from_member_events(
                                member_events.values()),
                            "app":
                            self.app_name,
                        })
        else:
            # Stuff's happened in multiple different rooms

            # ...but we still refer to the 'reason' room which triggered the mail
            if reason['room_name'] is not None:
                defer.returnValue(MESSAGES_IN_ROOM_AND_OTHERS % {
                    "room": reason['room_name'],
                    "app": self.app_name,
                })
            else:
                # If the reason room doesn't have a name, say who the messages
                # are from explicitly to avoid, "messages in the Bob room"
                sender_ids = list(
                    set([
                        notif_events[n['event_id']].sender
                        for n in notifs_by_room[reason['room_id']]
                    ]))

                member_events = yield self.store.get_events([
                    room_state_ids[room_id][("m.room.member", s)]
                    for s in sender_ids
                ])

                defer.returnValue(
                    MESSAGES_FROM_PERSON_AND_OTHERS % {
                        "person":
                        descriptor_from_member_events(member_events.values()),
                        "app":
                        self.app_name,
                    })
Exemplo n.º 2
0
    async def make_summary_text(
        self, notifs_by_room, room_state_ids, notif_events, user_id, reason
    ):
        if len(notifs_by_room) == 1:
            # Only one room has new stuff
            room_id = list(notifs_by_room.keys())[0]

            # If the room has some kind of name, use it, but we don't
            # want the generated-from-names one here otherwise we'll
            # end up with, "new message from Bob in the Bob room"
            room_name = await calculate_room_name(
                self.store, room_state_ids[room_id], user_id, fallback_to_members=False
            )

            my_member_event_id = room_state_ids[room_id][("m.room.member", user_id)]
            my_member_event = await self.store.get_event(my_member_event_id)
            if my_member_event.content["membership"] == "invite":
                inviter_member_event_id = room_state_ids[room_id][
                    ("m.room.member", my_member_event.sender)
                ]
                inviter_member_event = await self.store.get_event(
                    inviter_member_event_id
                )
                inviter_name = name_from_member_event(inviter_member_event)

                if room_name is None:
                    return self.email_subjects.invite_from_person % {
                        "person": inviter_name,
                        "app": self.app_name,
                    }
                else:
                    return self.email_subjects.invite_from_person_to_room % {
                        "person": inviter_name,
                        "room": room_name,
                        "app": self.app_name,
                    }

            sender_name = None
            if len(notifs_by_room[room_id]) == 1:
                # There is just the one notification, so give some detail
                event = notif_events[notifs_by_room[room_id][0]["event_id"]]
                if ("m.room.member", event.sender) in room_state_ids[room_id]:
                    state_event_id = room_state_ids[room_id][
                        ("m.room.member", event.sender)
                    ]
                    state_event = await self.store.get_event(state_event_id)
                    sender_name = name_from_member_event(state_event)

                if sender_name is not None and room_name is not None:
                    return self.email_subjects.message_from_person_in_room % {
                        "person": sender_name,
                        "room": room_name,
                        "app": self.app_name,
                    }
                elif sender_name is not None:
                    return self.email_subjects.message_from_person % {
                        "person": sender_name,
                        "app": self.app_name,
                    }
            else:
                # There's more than one notification for this room, so just
                # say there are several
                if room_name is not None:
                    return self.email_subjects.messages_in_room % {
                        "room": room_name,
                        "app": self.app_name,
                    }
                else:
                    # If the room doesn't have a name, say who the messages
                    # are from explicitly to avoid, "messages in the Bob room"
                    sender_ids = list(
                        {
                            notif_events[n["event_id"]].sender
                            for n in notifs_by_room[room_id]
                        }
                    )

                    member_events = await self.store.get_events(
                        [
                            room_state_ids[room_id][("m.room.member", s)]
                            for s in sender_ids
                        ]
                    )

                    return self.email_subjects.messages_from_person % {
                        "person": descriptor_from_member_events(member_events.values()),
                        "app": self.app_name,
                    }
        else:
            # Stuff's happened in multiple different rooms

            # ...but we still refer to the 'reason' room which triggered the mail
            if reason["room_name"] is not None:
                return self.email_subjects.messages_in_room_and_others % {
                    "room": reason["room_name"],
                    "app": self.app_name,
                }
            else:
                # If the reason room doesn't have a name, say who the messages
                # are from explicitly to avoid, "messages in the Bob room"
                room_id = reason["room_id"]

                sender_ids = list(
                    {
                        notif_events[n["event_id"]].sender
                        for n in notifs_by_room[room_id]
                    }
                )

                member_events = await self.store.get_events(
                    [room_state_ids[room_id][("m.room.member", s)] for s in sender_ids]
                )

                return self.email_subjects.messages_from_person_and_others % {
                    "person": descriptor_from_member_events(member_events.values()),
                    "app": self.app_name,
                }
Exemplo n.º 3
0
    async def make_summary_text(
        self,
        notifs_by_room: Dict[str, List[Dict[str, Any]]],
        room_state_ids: Dict[str, StateMap[str]],
        notif_events: Dict[str, EventBase],
        user_id: str,
        reason: Dict[str, Any],
    ):
        if len(notifs_by_room) == 1:
            # Only one room has new stuff
            room_id = list(notifs_by_room.keys())[0]

            # If the room has some kind of name, use it, but we don't
            # want the generated-from-names one here otherwise we'll
            # end up with, "new message from Bob in the Bob room"
            room_name = await calculate_room_name(self.store,
                                                  room_state_ids[room_id],
                                                  user_id,
                                                  fallback_to_members=False)

            # See if one of the notifs is an invite event for the user
            invite_event = None
            for n in notifs_by_room[room_id]:
                ev = notif_events[n["event_id"]]
                if ev.type == EventTypes.Member and ev.state_key == user_id:
                    if ev.content.get("membership") == Membership.INVITE:
                        invite_event = ev
                        break

            if invite_event:
                inviter_member_event_id = room_state_ids[room_id].get(
                    ("m.room.member", invite_event.sender))
                inviter_name = invite_event.sender
                if inviter_member_event_id:
                    inviter_member_event = await self.store.get_event(
                        inviter_member_event_id, allow_none=True)
                    if inviter_member_event:
                        inviter_name = name_from_member_event(
                            inviter_member_event)

                if room_name is None:
                    return self.email_subjects.invite_from_person % {
                        "person": inviter_name,
                        "app": self.app_name,
                    }
                else:
                    return self.email_subjects.invite_from_person_to_room % {
                        "person": inviter_name,
                        "room": room_name,
                        "app": self.app_name,
                    }

            sender_name = None
            if len(notifs_by_room[room_id]) == 1:
                # There is just the one notification, so give some detail
                event = notif_events[notifs_by_room[room_id][0]["event_id"]]
                if ("m.room.member", event.sender) in room_state_ids[room_id]:
                    state_event_id = room_state_ids[room_id][("m.room.member",
                                                              event.sender)]
                    state_event = await self.store.get_event(state_event_id)
                    sender_name = name_from_member_event(state_event)

                if sender_name is not None and room_name is not None:
                    return self.email_subjects.message_from_person_in_room % {
                        "person": sender_name,
                        "room": room_name,
                        "app": self.app_name,
                    }
                elif sender_name is not None:
                    return self.email_subjects.message_from_person % {
                        "person": sender_name,
                        "app": self.app_name,
                    }
            else:
                # There's more than one notification for this room, so just
                # say there are several
                if room_name is not None:
                    return self.email_subjects.messages_in_room % {
                        "room": room_name,
                        "app": self.app_name,
                    }
                else:
                    # If the room doesn't have a name, say who the messages
                    # are from explicitly to avoid, "messages in the Bob room"
                    sender_ids = list({
                        notif_events[n["event_id"]].sender
                        for n in notifs_by_room[room_id]
                    })

                    member_events = await self.store.get_events([
                        room_state_ids[room_id][("m.room.member", s)]
                        for s in sender_ids
                    ])

                    return self.email_subjects.messages_from_person % {
                        "person":
                        descriptor_from_member_events(member_events.values()),
                        "app":
                        self.app_name,
                    }
        else:
            # Stuff's happened in multiple different rooms

            # ...but we still refer to the 'reason' room which triggered the mail
            if reason["room_name"] is not None:
                return self.email_subjects.messages_in_room_and_others % {
                    "room": reason["room_name"],
                    "app": self.app_name,
                }
            else:
                # If the reason room doesn't have a name, say who the messages
                # are from explicitly to avoid, "messages in the Bob room"
                room_id = reason["room_id"]

                sender_ids = list({
                    notif_events[n["event_id"]].sender
                    for n in notifs_by_room[room_id]
                })

                member_events = await self.store.get_events([
                    room_state_ids[room_id][("m.room.member", s)]
                    for s in sender_ids
                ])

                return self.email_subjects.messages_from_person_and_others % {
                    "person": descriptor_from_member_events(
                        member_events.values()),
                    "app": self.app_name,
                }
Exemplo n.º 4
0
    async def _make_summary_text_from_member_events(
        self,
        room_id: str,
        notifs: List[EmailPushAction],
        room_state_ids: StateMap[str],
        notif_events: Dict[str, EventBase],
    ) -> str:
        """
        Make a summary text for the email when only a single room has notifications.

        Args:
            room_id: The ID of the room.
            notifs: The push actions for this room.
            room_state_ids: The state map for the room.
            notif_events: A map of event ID -> notification event.

        Returns:
            The summary text.
        """
        # If the room doesn't have a name, say who the messages
        # are from explicitly to avoid, "messages in the Bob room"

        # Find the latest event ID for each sender, note that the notifications
        # are already in descending received_ts.
        sender_ids = {}
        for n in notifs:
            sender = notif_events[n.event_id].sender
            if sender not in sender_ids:
                sender_ids[sender] = n.event_id

        # Get the actual member events (in order to calculate a pretty name for
        # the room).
        member_event_ids = []
        member_events = {}
        for sender_id, event_id in sender_ids.items():
            type_state_key = ("m.room.member", sender_id)
            sender_state_event_id = room_state_ids.get(type_state_key)
            if sender_state_event_id:
                member_event_ids.append(sender_state_event_id)
            else:
                # Attempt to check the historical state for the room.
                historical_state = (
                    await self._state_storage_controller.get_state_for_event(
                        event_id, StateFilter.from_types((type_state_key, ))))
                sender_state_event = historical_state.get(type_state_key)
                if sender_state_event:
                    member_events[event_id] = sender_state_event
        member_events.update(await self.store.get_events(member_event_ids))

        if not member_events:
            # No member events were found! Maybe the room is empty?
            # Fallback to the room ID (note that if there was a room name this
            # would already have been used previously).
            return self.email_subjects.messages_in_room % {
                "room": room_id,
                "app": self.app_name,
            }

        # There was a single sender.
        if len(member_events) == 1:
            return self.email_subjects.messages_from_person % {
                "person": descriptor_from_member_events(
                    member_events.values()),
                "app": self.app_name,
            }

        # There was more than one sender, use the first one and a tweaked template.
        return self.email_subjects.messages_from_person_and_others % {
            "person":
            descriptor_from_member_events(list(member_events.values())[:1]),
            "app":
            self.app_name,
        }
Exemplo n.º 5
0
    def make_summary_text(self, notifs_by_room, state_by_room,
                          notif_events, user_id, reason):
        if len(notifs_by_room) == 1:
            # Only one room has new stuff
            room_id = notifs_by_room.keys()[0]

            # If the room has some kind of name, use it, but we don't
            # want the generated-from-names one here otherwise we'll
            # end up with, "new message from Bob in the Bob room"
            room_name = yield calculate_room_name(
                self.store, state_by_room[room_id], user_id, fallback_to_members=False
            )

            my_member_event = state_by_room[room_id][("m.room.member", user_id)]
            if my_member_event.content["membership"] == "invite":
                inviter_member_event = state_by_room[room_id][
                    ("m.room.member", my_member_event.sender)
                ]
                inviter_name = name_from_member_event(inviter_member_event)

                if room_name is None:
                    defer.returnValue(INVITE_FROM_PERSON % {
                        "person": inviter_name,
                        "app": self.app_name
                    })
                else:
                    defer.returnValue(INVITE_FROM_PERSON_TO_ROOM % {
                        "person": inviter_name,
                        "room": room_name,
                        "app": self.app_name,
                    })

            sender_name = None
            if len(notifs_by_room[room_id]) == 1:
                # There is just the one notification, so give some detail
                event = notif_events[notifs_by_room[room_id][0]["event_id"]]
                if ("m.room.member", event.sender) in state_by_room[room_id]:
                    state_event = state_by_room[room_id][("m.room.member", event.sender)]
                    sender_name = name_from_member_event(state_event)

                if sender_name is not None and room_name is not None:
                    defer.returnValue(MESSAGE_FROM_PERSON_IN_ROOM % {
                        "person": sender_name,
                        "room": room_name,
                        "app": self.app_name,
                    })
                elif sender_name is not None:
                    defer.returnValue(MESSAGE_FROM_PERSON % {
                        "person": sender_name,
                        "app": self.app_name,
                    })
            else:
                # There's more than one notification for this room, so just
                # say there are several
                if room_name is not None:
                    defer.returnValue(MESSAGES_IN_ROOM % {
                        "room": room_name,
                        "app": self.app_name,
                    })
                else:
                    # If the room doesn't have a name, say who the messages
                    # are from explicitly to avoid, "messages in the Bob room"
                    sender_ids = list(set([
                        notif_events[n['event_id']].sender
                        for n in notifs_by_room[room_id]
                    ]))

                    defer.returnValue(MESSAGES_FROM_PERSON % {
                        "person": descriptor_from_member_events([
                            state_by_room[room_id][("m.room.member", s)]
                            for s in sender_ids
                        ]),
                        "app": self.app_name,
                    })
        else:
            # Stuff's happened in multiple different rooms

            # ...but we still refer to the 'reason' room which triggered the mail
            if reason['room_name'] is not None:
                defer.returnValue(MESSAGES_IN_ROOM_AND_OTHERS % {
                    "room": reason['room_name'],
                    "app": self.app_name,
                })
            else:
                # If the reason room doesn't have a name, say who the messages
                # are from explicitly to avoid, "messages in the Bob room"
                sender_ids = list(set([
                    notif_events[n['event_id']].sender
                    for n in notifs_by_room[reason['room_id']]
                ]))

                defer.returnValue(MESSAGES_FROM_PERSON_AND_OTHERS % {
                    "person": descriptor_from_member_events([
                        state_by_room[reason['room_id']][("m.room.member", s)]
                        for s in sender_ids
                    ]),
                    "app": self.app_name,
                })