Пример #1
0
def test_add_system_member(slave_channel):
    chat = GroupChat(channel=slave_channel, name="__name__", alias="__alias__", uid="__id__")
    member = chat.add_system_member(name="__member_name__", uid="__member_id__")
    assert isinstance(member, SystemChatMember)
    assert member.name == "__member_name__"
    assert member.uid == "__member_id__"
    assert member.chat is chat
    assert member in chat.members
Пример #2
0
    def build_efb_chat_as_member(chat: GroupChat,
                                 member: EFBGroupMember) -> ChatMember:
        """
        Build EFB ChatMember object from GroupChat and EFBGroupMember.
        It'll try to get member from GroupChat, if one is not found then a new member is added.

        :param chat: Original GroupChat
        :param member: EFBGroupMember object, see CustomTypes.py
        :return: Newly built ChatMember
        """
        with contextlib.suppress(KeyError):
            return chat.get_member(str(member.get('uid', '')))
        efb_chat: ChatMember = chat.add_member(**member)
        return efb_chat
Пример #3
0
    def __init__(self, channel: 'WeChatChannel'):
        self.channel: 'WeChatChannel' = channel
        self.logger: logging.Logger = logging.getLogger(__name__)

        # noinspection PyProtectedMember
        self._ = self.channel._

        self.MISSING_GROUP: GroupChat = GroupChat(
            channel=self.channel,
            uid=ChatID("__error_group__"),
            name=self._("Group Missing")
        )

        self.MISSING_CHAT: PrivateChat = PrivateChat(
            channel=self.channel,
            uid=ChatID("__error_chat__"),
            name=self._("Chat Missing")
        )

        self.efb_chat_objs: Dict[str, Chat] = {}
        # Cached Chat objects. Key: tuple(chat PUID, group PUID or None)

        # Load system chats
        self.system_chats: List[Chat] = []
        for i in channel.flag('system_chats_to_include'):
            self.system_chats.append(
                self.wxpy_chat_to_efb_chat(
                    wxpy.Chat(
                        wxpy.utils.wrap_user_name(i),
                        self.bot
                    )
                )
            )
Пример #4
0
    def __init__(self, instance_id=None):
        super().__init__(instance_id)
        self.alice = PrivateChat(channel=self, name="Alice", uid="alice")
        self.bob = PrivateChat(channel=self,
                               name="Bob",
                               alias="Little bobby",
                               uid="bob")

        self.wonderland = GroupChat(channel=self,
                                    name="Wonderland",
                                    uid="wonderland001")
        self.wonderland.add_member(name="bob", alias="Bob James", uid="bob")
        self.carol = self.wonderland.add_member(name="Carol", uid="carol")
        self.dave = self.wonderland.add_member(
            name="デブ", uid="dave")  # Nah, that's a joke

        self.chats: List[Chat] = [self.alice, self.bob, self.wonderland]
Пример #5
0
 def make_efb_chat_obj(self, diag) -> Chat:
     if isinstance(diag.entity, TgUser):
         return PrivateChat(channel=self,
                            name=diag.name,
                            uid=str(diag.entity.id),
                            other_is_self=diag.entity.is_self)
     if isinstance(diag.entity, TgChat) or isinstance(
             diag.entity, TgChannel):
         return GroupChat(channel=self,
                          name=diag.name,
                          uid=str(diag.entity.id))
Пример #6
0
    def __init__(self, channel: 'QQMessengerChannel'):
        self.channel: 'QQMessengerChannel' = channel
        self.logger: logging.Logger = logging.getLogger(__name__)

        self.MISSING_GROUP: GroupChat = GroupChat(
            channel=self.channel,
            uid=ChatID("__error_group__"),
            name="Group Missing")

        self.MISSING_CHAT: PrivateChat = PrivateChat(
            channel=self.channel,
            uid=ChatID("__error_chat__"),
            name="Chat Missing")
Пример #7
0
    def build_efb_chat_as_group(
            group: EFBGroupChat,
            members: Optional[List[EFBGroupMember]] = None) -> GroupChat:
        """
        Build EFB GroupChat object from EFBGroupChat Dict

        :return: GroupChat from group_id
        :param group: EFBGroupChat object, see CustomTypes.py
        :param members: Optional, the member list for the specific group, None by default
                        Each object in members (if not None) must follow the syntax of GroupChat.add_members
        """
        efb_chat: GroupChat = GroupChat(channel=ChatMgr.slave_channel, **group)
        if members:
            for member in members:
                efb_chat.add_member(**member)
        return efb_chat
Пример #8
0
 def build_efb_chat_as_group(self,
                             context,
                             update_member=False):  # Should be cached
     is_discuss = False if context['message_type'] == 'group' else True
     chat_uid = context['discuss_id'] if is_discuss else context['group_id']
     efb_chat = GroupChat(channel=self.channel, uid=str(chat_uid))
     if not is_discuss:
         efb_chat.uid = 'group' + '_' + str(chat_uid)
         i = self.channel.QQClient.get_group_info(chat_uid)
         if i is not None:
             efb_chat.name = str(
                 i['group_name']) if 'group_name' not in context else str(
                     context['group_name'])
         else:
             efb_chat.name = str(chat_uid)
         efb_chat.vendor_specific = {'is_discuss': False}
         if update_member:
             members = self.channel.QQClient.get_group_member_list(
                 chat_uid, False)
             if members:
                 for member in members:
                     efb_chat.add_member(name=str(member['card']),
                                         alias=str(member['nickname']),
                                         uid=str(member['user_id']))
     else:
         efb_chat.uid = 'discuss' + '_' + str(chat_uid)
         efb_chat.name = 'Discuss Group' + '_' + str(chat_uid)
         # todo Find a way to distinguish from different discuss group
         efb_chat.vendor_specific = {'is_discuss': True}
     return efb_chat
Пример #9
0
    def wxpy_chat_to_efb_chat(self, chat: wxpy.Chat) -> Chat:
        # self.logger.debug("Converting WXPY chat %r, %sin recursive mode", chat, '' if recursive else 'not ')
        # self.logger.debug("WXPY chat with ID: %s, name: %s, alias: %s;", chat.puid, chat.nick_name, chat.alias)
        if chat is None:
            return self.MISSING_USER

        cache_key = chat.puid

        chat_name, chat_alias = self.get_name_alias(chat)

        cached_obj: Optional[Chat] = None
        if cache_key in self.efb_chat_objs:
            cached_obj = self.efb_chat_objs[cache_key]
            if chat_name == cached_obj.name and chat_alias == cached_obj.alias:
                return cached_obj

        # if chat name or alias changes, update cache
        efb_chat: Chat
        chat_id = ChatID(chat.puid or f"__invalid_{uuid4()}__")
        if cached_obj:
            efb_chat = cached_obj
            efb_chat.uid = chat_id
            efb_chat.name = chat_name
            efb_chat.alias = chat_alias
            efb_chat.vendor_specific = {'is_mp': isinstance(chat, wxpy.MP)}

            if isinstance(chat, wxpy.Group):
                # Update members if necessary
                remote_puids = {i.puid for i in chat.members}
                local_ids = {i.uid for i in efb_chat.members if not isinstance(i, SelfChatMember)}
                # Add missing members
                missing_puids = remote_puids - local_ids
                for member in chat.members:
                    if member.puid in missing_puids:
                        member_name, member_alias = self.get_name_alias(member)
                        efb_chat.add_member(name=member_name, alias=member_alias, uid=member.puid,
                                            vendor_specific={'is_mp': False})
        elif chat == chat.bot.self:
            efb_chat = PrivateChat(channel=self.channel, uid=chat_id, name=chat_name,
                                   alias=chat_alias, vendor_specific={'is_mp': True}, other_is_self=True)
        elif isinstance(chat, wxpy.Group):
            efb_chat = GroupChat(channel=self.channel, uid=chat_id, name=chat_name,
                                 alias=chat_alias, vendor_specific={'is_mp': False})
            for i in chat.members:
                if i.user_name == self.bot.self.user_name:
                    continue
                member_name, member_alias = self.get_name_alias(i)
                efb_chat.add_member(name=member_name, alias=member_alias, uid=i.puid, vendor_specific={'is_mp': False})
        elif isinstance(chat, wxpy.MP):
            efb_chat = PrivateChat(channel=self.channel, uid=chat_id, name=chat_name,
                                   alias=chat_alias, vendor_specific={'is_mp': True})
        elif isinstance(chat, wxpy.User):
            efb_chat = PrivateChat(channel=self.channel, uid=chat_id, name=chat_name,
                                   alias=chat_alias, vendor_specific={'is_mp': False})
        else:
            efb_chat = SystemChat(channel=self.channel, uid=chat_id, name=chat_name,
                                  alias=chat_alias, vendor_specific={'is_mp': False})

        efb_chat.vendor_specific.update(self.generate_vendor_specific(chat))
        if efb_chat.vendor_specific.get('is_muted', False):
            efb_chat.notification = ChatNotificationState.MENTIONS

        self.efb_chat_objs[cache_key] = efb_chat

        return efb_chat
    def build_chat_by_thread_obj(self, thread: Thread) -> Chat:
        vendor_specific = {
            "chat_type": thread.type.name.capitalize(),
            "profile_picture_url": thread.photo,
        }
        chat: Chat
        if thread.uid == self.client.uid:
            chat = PrivateChat(channel=self.channel,
                               uid=thread.uid,
                               other_is_self=True)
            chat.name = chat.self.name  # type: ignore
        elif isinstance(thread, User):
            chat = PrivateChat(channel=self.channel,
                               name=thread.name,
                               uid=ChatID(thread.uid),
                               alias=thread.own_nickname or thread.nickname,
                               vendor_specific=vendor_specific)
        elif isinstance(thread, Page):
            desc = self._("{subtitle}\n{category} in {city}\n"
                          "Likes: {likes}\n{url}").format(
                              subtitle=thread.sub_title,
                              category=thread.category,
                              city=thread.city,
                              likes=thread.likes,
                              url=thread.url)
            chat = PrivateChat(channel=self.channel,
                               name=thread.name,
                               uid=ChatID(thread.uid),
                               description=desc,
                               vendor_specific=vendor_specific)
        elif isinstance(thread, Group):
            name = thread.name or ""

            group = GroupChat(channel=self.channel,
                              name=name,
                              uid=ChatID(thread.uid),
                              vendor_specific=vendor_specific)
            participant_ids = thread.participants - {self.client.uid}
            try:
                participants: Dict[ThreadID,
                                   User] = self.client.fetchThreadInfo(
                                       *participant_ids)
                for i in participant_ids:
                    member = participants[i]
                    alias = member.own_nickname or member.nickname or None
                    if thread.nicknames and i in thread.nicknames:
                        alias = thread.nicknames[str(i)] or None
                    group.add_member(name=member.name,
                                     alias=alias,
                                     uid=ChatID(i))
            except FBchatException:
                self.logger.exception(
                    "Error occurred while building chat members.")
                for i in participant_ids:
                    group.add_member(name=str(i), uid=ChatID(i))

            if thread.name is None:
                names = sorted(i.name for i in group.members)
                # TRANSLATORS: separation symbol between member names when group name is not provided.
                name = self._(", ").join(names[:3])
                if len(names) > 3:
                    extras = len(names) - 3
                    name += self.ngettext(", and {number} more",
                                          ", and {number} more",
                                          extras).format(number=extras)
                group.name = name

            chat = group
        else:
            chat = SystemChat(channel=self.channel,
                              name=thread.name,
                              uid=ChatID(thread.uid),
                              vendor_specific=vendor_specific)
        if chat.self:
            chat.self.uid = self.client.uid
        return chat
Пример #11
0
class MockSlaveChannel(SlaveChannel):
    channel_name: str = "Mock Slave"
    channel_emoji: str = "➖"
    channel_id: ModuleID = ModuleID("tests.mocks.slave.MockSlaveChannel")
    supported_message_types: Set[MsgType] = {MsgType.Text, MsgType.Link}
    __version__: str = '0.0.1'

    logger = getLogger(channel_id)

    polling = threading.Event()

    __picture_dict = {
        "alice": "A.png",
        "bob": "B.png",
        "carol": "C.png",
        "dave": "D.png",
        "wonderland001": "W.png"
    }

    def __init__(self, instance_id=None):
        super().__init__(instance_id)
        self.alice = PrivateChat(channel=self, name="Alice", uid="alice")
        self.bob = PrivateChat(channel=self,
                               name="Bob",
                               alias="Little bobby",
                               uid="bob")

        self.wonderland = GroupChat(channel=self,
                                    name="Wonderland",
                                    uid="wonderland001")
        self.wonderland.add_member(name="bob", alias="Bob James", uid="bob")
        self.carol = self.wonderland.add_member(name="Carol", uid="carol")
        self.dave = self.wonderland.add_member(
            name="デブ", uid="dave")  # Nah, that's a joke

        self.chats: List[Chat] = [self.alice, self.bob, self.wonderland]

    def poll(self):
        self.polling.wait()

    def send_status(self, status: Status):
        self.logger.debug("Received status: %r", status)

    def send_message(self, msg: Message) -> Message:
        self.logger.debug("Received message: %r", msg)
        return msg

    def stop_polling(self):
        self.polling.set()

    def get_chat(self, chat_uid: str) -> Chat:
        for i in self.chats:
            if chat_uid == i.uid:
                return i
        raise EFBChatNotFound()

    def get_chats(self) -> List[Chat]:
        return self.chats.copy()

    def get_chat_picture(self, chat: Chat):
        if chat.uid in self.__picture_dict:
            return open('tests/mocks/' + self.__picture_dict[chat.uid], 'rb')

    def get_message_by_id(self, chat: Chat,
                          msg_id: MessageID) -> Optional['Message']:
        pass

    @extra(name="Echo",
           desc="Echo back the input.\n"
           "Usage:\n"
           "    {function_name} text")
    def echo(self, args):
        return args

    @extra(name="Extra function A",
           desc="Do something A.\nUsage: {function_name}")
    def function_a(self):
        return f"Value of function A from {self.channel_id}."

    @extra(name="Extra function B",
           desc="Do something B.\nUsage: {function_name}")
    def function_b(self):
        return f"Value of function B from {self.channel_name}."