예제 #1
0
def test_verify_message_command():
    msg = EFBMsg()
    msg.deliver_to = coordinator.master

    msg.author = patch_chat_0
    msg.chat = patch_chat_1
    msg.text = "Message"
    msg.verify()

    msg.type = MsgType.Text
    msg.attributes = None
    msg.commands = EFBMsgCommands([
        EFBMsgCommand(name="Command 1", callable_name="command_1")
    ])

    msg.commands.commands[0].verify = mock.Mock()

    msg.verify()

    msg.commands.commands[0].verify.assert_called_once()
예제 #2
0
def test_pickle_media_message(media_type):
    with NamedTemporaryFile() as f:
        msg = EFBMsg()
        msg.deliver_to = coordinator.master
        msg.author = chat
        msg.chat = chat
        msg.type = media_type
        msg.file = f
        msg.filename = "test.bin"
        msg.path = f.name
        msg.mime = "application/octet-stream"
        msg.uid = "message_id"
        msg.verify()
        msg_dup = pickle.loads(pickle.dumps(msg))
        for attr in ("deliver_to", "author", "chat", "type", "chat", "filename", "path", "mime", "text", "uid"):
            assert getattr(msg, attr) == getattr(msg_dup, attr)
예제 #3
0
def test_verify_status_message():
    msg = EFBMsg()
    msg.deliver_to = coordinator.master

    msg.author = patch_chat_0
    msg.chat = patch_chat_1
    msg.text = "Message"
    msg.verify()

    msg.type = MsgType.Status
    msg.attributes = EFBMsgStatusAttribute(status_type=EFBMsgStatusAttribute.Types.TYPING)
    msg.attributes.verify = mock.Mock()
    msg.verify()

    msg.attributes.verify.assert_called_once()
예제 #4
0
def test_verify_location_message():
    msg = EFBMsg()
    msg.deliver_to = coordinator.master

    msg.author = patch_chat_0
    msg.chat = patch_chat_1
    msg.text = "Message"
    msg.verify()

    msg.type = MsgType.Location
    msg.attributes = EFBMsgLocationAttribute(latitude=0.0, longitude=0.0)
    msg.attributes.verify = mock.Mock()
    msg.verify()

    msg.attributes.verify.assert_called_once()
예제 #5
0
def test_verify_link_message():
    msg = EFBMsg()
    msg.deliver_to = coordinator.master

    msg.author = patch_chat_0
    msg.chat = patch_chat_1
    msg.text = "Message"
    msg.verify()

    msg.type = MsgType.Link
    msg.attributes = EFBMsgLinkAttribute(title='Title', url='URL')
    msg.attributes.verify = mock.Mock()
    msg.verify()

    msg.attributes.verify.assert_called_once()
예제 #6
0
    def send_message(self, msg: EFBMsg) -> EFBMsg:
        """Send a message to WeChat.
        Supports text, image, sticker, and file.

        Args:
            msg (channel.EFBMsg): Message Object to be sent.

        Returns:
            This method returns nothing.

        Raises:
            EFBMessageTypeNotSupported: Raised when message type is not supported by the channel.
        """
        chat: wxpy.Chat = self.chats.get_wxpy_chat_by_uid(msg.chat.chat_uid)
        r = None
        self.logger.info(
            "[%s] Sending message to WeChat:\n"
            "uid: %s\n"
            "UserName: %s\n"
            "NickName: %s\n"
            "Type: %s\n"
            "Text: %s", msg.uid, msg.chat.chat_uid, chat.user_name, chat.name,
            msg.type, msg.text)

        self.logger.debug('[%s] Is edited: %s', msg.uid, msg.edit)
        if msg.edit:
            if self.flag('delete_on_edit'):
                try:
                    ews_utils.message_to_dummy_message(msg.uid, self).recall()
                except wxpy.ResponseError as e:
                    self.logger.error(
                        "[%s] Trying to recall message but failed: %s",
                        msg.uid, e)
                    raise EFBMessageError(
                        self.
                        _('Failed to recall message, edited message was not sent.'
                          ))
            else:
                raise EFBOperationNotSupported()
        if msg.type in [MsgType.Text, MsgType.Link]:
            if isinstance(msg.target, EFBMsg):
                max_length = self.flag("max_quote_length")
                qt_txt = "%s" % msg.target.text
                if max_length > 0:
                    tgt_text = qt_txt[:max_length]
                    if len(qt_txt) >= max_length:
                        tgt_text += "…"
                    tgt_text = "「%s」" % tgt_text
                elif max_length < 0:
                    tgt_text = "「%s」" % qt_txt
                else:
                    tgt_text = ""
                if isinstance(chat,
                              wxpy.Group) and not msg.target.author.is_self:
                    tgt_alias = "@%s\u2005 " % msg.target.author.chat_alias
                else:
                    tgt_alias = ""
                msg.text = "%s%s\n\n%s" % (tgt_alias, tgt_text, msg.text)
            r: wxpy.SentMessage = self._bot_send_msg(chat, msg.text)
            self.logger.debug('[%s] Sent as a text message. %s', msg.uid,
                              msg.text)
        elif msg.type in (MsgType.Image, MsgType.Sticker):
            self.logger.info("[%s] Image/Sticker %s", msg.uid, msg.type)
            if msg.type != MsgType.Sticker:
                if os.fstat(msg.file.fileno()).st_size > self.MAX_FILE_SIZE:
                    raise EFBMessageError(
                        self._("Image size is too large. (IS01)"))
                self.logger.debug("[%s] Sending %s (image) to WeChat.",
                                  msg.uid, msg.path)
                r: wxpy.SentMessage = self._bot_send_image(
                    chat, msg.path, msg.file)
                msg.file.close()
            else:  # Convert Image format
                with NamedTemporaryFile(suffix=".gif") as f:
                    img = Image.open(msg.file)
                    try:
                        alpha = img.split()[3]
                        mask = Image.eval(alpha, lambda a: 255
                                          if a <= 128 else 0)
                    except IndexError:
                        mask = Image.eval(img.split()[0], lambda a: 0)
                    img = img.convert('RGB').convert('P',
                                                     palette=Image.ADAPTIVE,
                                                     colors=255)
                    img.paste(255, mask)
                    img.save(f, transparency=255)
                    msg.path = f.name
                    self.logger.debug('[%s] Image converted from %s to GIF',
                                      msg.uid, msg.mime)
                    msg.file.close()
                    f.seek(0)
                    if os.fstat(f.fileno()).st_size > self.MAX_FILE_SIZE:
                        raise EFBMessageError(
                            self._("Image size is too large. (IS02)"))
                    r: wxpy.SentMessage = self._bot_send_image(chat, f.name, f)
            if msg.text:
                self._bot_send_msg(chat, msg.text)
        elif msg.type in (MsgType.File, MsgType.Audio):
            self.logger.info(
                "[%s] Sending %s to WeChat\nFileName: %s\nPath: %s\nFilename: %s",
                msg.uid, msg.type, msg.text, msg.path, msg.filename)
            r = self._bot_send_file(chat, msg.filename, file=msg.file)
            if msg.text:
                self._bot_send_msg(chat, msg.text)
            msg.file.close()
        elif msg.type == MsgType.Video:
            self.logger.info(
                "[%s] Sending video to WeChat\nFileName: %s\nPath: %s",
                msg.uid, msg.text, msg.path)
            r = self._bot_send_video(chat, msg.path, file=msg.file)
            if msg.text:
                self._bot_send_msg(chat, msg.text)
            msg.file.close()
        else:
            raise EFBMessageTypeNotSupported()

        msg.uid = ews_utils.generate_message_uid(r)
        self.logger.debug('WeChat message is assigned with unique ID: %s',
                          msg.uid)
        return msg
예제 #7
0
    def master_qr_code(self, uuid, status, qrcode=None):
        status = int(status)
        msg = EFBMsg()
        msg.type = MsgType.Text
        msg.chat = EFBChat(self).system()
        msg.chat.chat_name = self._("EWS User Auth")
        msg.author = msg.chat
        msg.deliver_to = coordinator.master

        if status == 201:
            msg.type = MsgType.Text
            msg.text = self._('Confirm on your phone.')
        elif status == 200:
            msg.type = MsgType.Text
            msg.text = self._("Successfully logged in.")
        elif uuid != self.qr_uuid:
            msg.type = MsgType.Image
            # path = os.path.join("storage", self.channel_id)
            # if not os.path.exists(path):
            #     os.makedirs(path)
            # path = os.path.join(path, 'QR-%s.jpg' % int(time.time()))
            # self.logger.debug("master_qr_code file path: %s", path)
            file = NamedTemporaryFile(suffix=".png")
            qr_url = "https://login.weixin.qq.com/l/" + uuid
            QRCode(qr_url).png(file, scale=10)
            msg.text = self._("QR code expired, please scan the new one.")
            msg.path = file.name
            msg.file = file
            msg.mime = 'image/png'
        if status in (200, 201) or uuid != self.qr_uuid:
            coordinator.send_message(msg)
            self.qr_uuid = uuid