def qq_music_wrapper(self, data, chat: Chat = None):
     efb_msg = Message()
     if data['type'] == '163':  # Netease Cloud Music
         efb_msg.type = MsgType.Text
         efb_msg.text = 'https://music.163.com/#/song?id=' + data['id']
     else:
         efb_msg.type = MsgType.Text
         efb_msg.text = data['text']
     return [efb_msg]  # todo Port for other music platform
Example #2
0
    def exit_callback(self):
        # Don't send prompt if there's nowhere to send.
        if not getattr(coordinator, 'master', None):
            raise Exception(
                self._("Web WeChat logged your account out before master channel is ready."))
        self.logger.debug('Calling exit callback...')
        if self._stop_polling_event.is_set():
            return
        msg = Message(
            chat=self.user_auth_chat,
            author=self.user_auth_chat.other,
            deliver_to=coordinator.master,
            text=self._(
                "WeChat server has logged you out. Please log in again when you are ready."),
            uid=f"__reauth__.{uuid4()}",
            type=MsgType.Text,
        )
        on_log_out = self.flag("on_log_out")
        on_log_out = on_log_out if on_log_out in (
            "command", "idle", "reauth") else "command"
        if on_log_out == "command":
            msg.type = MsgType.Text
            msg.commands = MessageCommands(
                [MessageCommand(name=self._("Log in again"), callable_name="reauth", kwargs={"command": True})])
        elif on_log_out == "reauth":
            if self.flag("qr_reload") == "console_qr_code":
                msg.text += "\n" + self._("Please check your log to continue.")
            self.reauth()

        coordinator.send_message(msg)
 def wechat_location_msg(self, msg: wxpy.Message) -> Message:
     efb_msg = Message()
     efb_msg.text = msg.text.split('\n')[0][:-1]
     efb_msg.attributes = LocationAttribute(latitude=float(msg.location['x']),
                                            longitude=float(msg.location['y']))
     efb_msg.type = MsgType.Location
     return efb_msg
 def wechat_shared_image_msg(self, msg: wxpy.Message, source: str, text: str = "", mode: str = "image") -> Message:
     efb_msg = Message()
     efb_msg.type = MsgType.Image
     efb_msg.text = self._("Via {source}").format(source=source)
     if text:
         efb_msg.text = "%s\n%s" % (text, efb_msg.text)
     efb_msg.path, efb_msg.mime, efb_msg.file = self.save_file(msg, app_message=mode)
     return efb_msg
 def qq_text_simple_wrapper(self, text: str, ats: dict):  # This cute function only accepts string!
     efb_msg = Message()
     efb_msg.type = MsgType.Text
     efb_msg.text = text
     if ats:  # This is used to replace specific text with @blahblah
         # And Milkice really requires a brain check
         efb_msg.substitutions = Substitutions(ats)
     return efb_msg
 def wechat_voice_msg(self, msg: wxpy.Message) -> Message:
     efb_msg = Message(type=MsgType.Voice)
     try:
         efb_msg.path, efb_msg.mime, efb_msg.file = self.save_file(msg)
         efb_msg.text = ""
     except EOFError:
         efb_msg.type = MsgType.Text
         efb_msg.text += self._("[Failed to download the voice message, please check your phone.]")
     return efb_msg
    def wechat_sticker_msg(self, msg: wxpy.Message) -> Message:
        efb_msg = Message(type=MsgType.Sticker)
        try:
            if msg.raw['MsgType'] == 47 and not msg.raw['Content']:
                raise EOFError
            if msg.file_size == 0:
                raise EOFError
            efb_msg.path, efb_msg.mime, efb_msg.file = self.save_file(msg)
            efb_msg.filename = msg.file_name
            # ^ Also throws EOFError
            if 'gif' in efb_msg.mime and Image.open(efb_msg.path).is_animated:
                efb_msg.type = MsgType.Animation
            efb_msg.text = ""
        except EOFError:
            efb_msg.text += self._("[Failed to download the sticker, please check your phone.]")
            efb_msg.type = MsgType.Unsupported

        return efb_msg
 def qq_record_wrapper(self, data, chat: Chat = None):  # Experimental!
     efb_msg = Message()
     try:
         transformed_file = self.inst.coolq_api_query("get_record", file=data['file'], out_format='mp3')
         efb_msg.type = MsgType.Audio
         efb_msg.file = download_voice(transformed_file['file'],
                                       self.inst.client_config['api_root'].rstrip("/"),
                                       self.inst.client_config['access_token'])
         mime = magic.from_file(efb_msg.file.name, mime=True)
         if isinstance(mime, bytes):
             mime = mime.decode()
         efb_msg.path = efb_msg.file.name
         efb_msg.mime = mime
     except Exception:
         efb_msg.type = MsgType.Unsupported
         efb_msg.text = self._('[Voice Message] Please check it on your QQ')
         logging.getLogger(__name__).exception("Failed to download voice")
     return [efb_msg]
 def qq_file_after_wrapper(self, data):
     efb_msg = Message()
     efb_msg.file = data['file']
     efb_msg.type = MsgType.File
     mime = magic.from_file(efb_msg.file.name, mime=True)
     if isinstance(mime, bytes):
         mime = mime.decode()
     efb_msg.path = efb_msg.file.name
     efb_msg.mime = mime
     efb_msg.filename = quote(data['filename'])
     return efb_msg
 def wechat_video_msg(self, msg: wxpy.Message) -> Message:
     efb_msg = Message(type=MsgType.Video)
     try:
         if msg.file_size == 0:
             raise EOFError
         efb_msg.path, efb_msg.mime, efb_msg.file = self.save_file(msg)
         efb_msg.filename = msg.file_name
         efb_msg.text = ""
     except EOFError:
         efb_msg.type = MsgType.Text
         efb_msg.text += self._("[Failed to download the video message, please check your phone.]")
     return efb_msg
Example #11
0
    def master_qr_code(self, uuid, status, qrcode=None):
        status = int(status)
        if self.qr_uuid == (uuid, status):
            return
        self.qr_uuid = (uuid, status)

        msg = Message(
            uid=f"ews_auth_{uuid}_{status}_{uuid4()}",
            type=MsgType.Text,
            chat=self.user_auth_chat,
            author=self.user_auth_chat.other,
            deliver_to=coordinator.master,
        )

        if status == 201:
            msg.type = MsgType.Text
            msg.text = self._('Confirm on your phone.')
            self.master_qr_picture_id = None
        elif status == 200:
            msg.type = MsgType.Text
            msg.text = self._("Successfully logged in.")
            self.master_qr_picture_id = None
        elif uuid != self.qr_uuid:
            msg.type = MsgType.Image
            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 = Path(file.name)
            msg.file = file
            msg.mime = 'image/png'
            if self.master_qr_picture_id is not None:
                msg.edit = True
                msg.edit_media = True
                msg.uid = self.master_qr_picture_id
            else:
                self.master_qr_picture_id = msg.uid
        if status in (200, 201) or uuid != self.qr_uuid:
            coordinator.send_message(msg)
 def wechat_file_msg(self, msg: wxpy.Message) -> Message:
     efb_msg = Message(type=MsgType.File)
     try:
         file_name = msg.file_name
         efb_msg.text = file_name or ""
         app_name = msg.app_name
         if app_name:
             efb_msg.text = self._("{file_name} sent via {app_name}").format(file_name=file_name, app_name=app_name)
         efb_msg.filename = file_name or ""
         efb_msg.path, efb_msg.mime, efb_msg.file = self.save_file(msg)
     except EOFError:
         efb_msg.type = MsgType.Text
         efb_msg.text += self._("[Failed to download the file, please check your phone.]")
     return efb_msg
    def qq_image_wrapper(self, data, chat: Chat = None):
        efb_msg = Message()
        if 'url' not in data:
            efb_msg.type = MsgType.Text
            efb_msg.text = self._('[Image Source missing]')
            return [efb_msg]

        efb_msg.file = cq_get_image(data['url'])
        if efb_msg.file is None:
            efb_msg.type = MsgType.Text
            efb_msg.text = self._('[Download image failed, please check on your QQ client]')
            return [efb_msg]

        efb_msg.type = MsgType.Image
        mime = magic.from_file(efb_msg.file.name, mime=True)
        if isinstance(mime, bytes):
            mime = mime.decode()
        efb_msg.filename = data['file'] if 'file' in data else efb_msg.file.name
        efb_msg.filename += '.' + str(mime).split('/')[1]
        efb_msg.path = efb_msg.file.name
        efb_msg.mime = mime
        if "gif" in mime:
            efb_msg.type = MsgType.Animation
        return [efb_msg]
    def wechat_picture_msg(self, msg: wxpy.Message) -> Message:
        efb_msg = Message(type=MsgType.Image)
        try:
            if msg.raw['MsgType'] == 47 and not msg.raw['Content']:
                raise EOFError
            if msg.file_size == 0:
                raise EOFError
            efb_msg.path, efb_msg.mime, efb_msg.file = self.save_file(msg)
            efb_msg.filename = msg.file_name
            # ^ Also throws EOFError
            efb_msg.text = ""
        except EOFError:
            efb_msg.text += self._("[Failed to download the picture, please check your phone.]")
            efb_msg.type = MsgType.Unsupported

        return efb_msg
Example #15
0
 def reply_message(self, message: Message, text: str):
     reply = Message()
     reply.text = text
     # reply.chat = coordinator.slaves[message.chat.channel_id].get_chat(message.chat.chat_uid)
     reply.chat = coordinator.slaves[message.chat.module_id].get_chat(
         message.chat.uid)
     reply.author = message.chat.make_system_member(
         uid=self.middleware_id, name=self.middleware_name, middleware=self)
     reply.type = MsgType.Text
     # reply.deliver_to = coordinator.master
     reply.deliver_to = coordinator.slaves[message.chat.module_id]
     # reply.target = message
     reply.uid = str(uuid.uuid4())
     r2 = reply
     coordinator.send_message(reply)
     r2.deliver_to = coordinator.master
     coordinator.send_message(r2)
Example #16
0
    def reply_message_img(self, message: Message, im3: Image.Image):
        reply = Message()
        # reply.text = text
        # reply.chat = coordinator.slaves[message.chat.channel_id].get_chat(message.chat.chat_uid)
        reply.chat = coordinator.slaves[message.chat.module_id].get_chat(
            message.chat.uid)
        reply.author = message.chat.make_system_member(
            uid=self.middleware_id, name=self.middleware_name, middleware=self)
        reply.type = MsgType.Image
        reply.mime = 'image/png'
        f = tempfile.NamedTemporaryFile(suffix='.png')
        img_data = io.BytesIO()
        im3.save(img_data, format='png')
        f.write(img_data.getvalue())
        f.file.seek(0)
        reply.file = f
        reply.path = f.name
        reply.filename = os.path.basename(reply.file.name)

        # reply.deliver_to = coordinator.master
        reply.deliver_to = coordinator.slaves[message.chat.module_id]
        # reply.target = message
        reply.uid = str(uuid.uuid4())
        r2 = reply
        coordinator.send_message(reply)

        r2.type = MsgType.Image
        r2.mime = 'image/png'
        f = tempfile.NamedTemporaryFile(suffix='.png')
        img_data = io.BytesIO()
        im3.save(img_data, format='png')
        f.write(img_data.getvalue())
        f.file.seek(0)
        r2.file = f
        r2.path = f.name
        r2.filename = os.path.basename(r2.file.name)
        r2.deliver_to = coordinator.master
        coordinator.send_message(r2)
Example #17
0
    def process_message(self, message: Message) -> Optional[Message]:
        """
        Process a message with middleware

        Args:
            message (:obj:`.Message`): Message object to process

        Returns:
            Optional[:obj:`.Message`]: Processed message or None if discarded.
        """
        if not self.sent_by_master(message):
            return message

        msg_text = message.text
        if msg_text.startswith('\\np '):
            message.text = msg_text[3:]
            return message

        # re_url = r'https?:\/\/\S+'
        # taken from django https://github.com/django/django/blob/master/django/core/validators.py#L68
        valid_url = re.compile(
            r'(https?://)?'  # scheme is validated separately
            r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}(?<!-)\.?)|'  # domain...
            r'localhost|'  # localhost...
            r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|'  # ...or ipv4
            r'\[?[A-F0-9]*:[A-F0-9:]+\]?)'  # ...or ipv6
            r'(?::\d+)?'  # optional port
            r'(?:[/?]\S+|[/?])?',
            re.IGNORECASE)
        url = valid_url.search(msg_text)
        if not url:
            return message

        url = url.group(0)
        try:
            lp = LinkPreview(url)
            title = lp.title
            desc = lp.desc
        except Exception as e:
            self.logger.error("Failed to get link preview: {}".format(e))
            return message

        text = msg_text
        if title or desc:
            text = '\n'.join([
                msg_text,
                'preview'.center(23, '='),
                title.center(23),
                '-' * 27,
                str(desc),
            ])

        if lp.type.startswith('image') and lp.image:
            suffix = os.path.splitext(lp.image_url)[1]
            message.file = NamedTemporaryFile(suffix=suffix)
            message.filename = os.path.basename(message.file.name)
            message.file.write(lp.image)
            message.file.file.seek(0)
            message.type = MsgType.Image
            message.mime = lp.type
            message.path = message.file.name

        message.text = text
        return message
Example #18
0
    def handle_tg_img_preview(self, message: Message):
        if not message or not message.file or not message.filename:
            return
        if message.author.uid == self.middleware_id:  # trysh-middleware
            # self.lg('self')
            return
        if message.type != MsgType.Image:
            return

        try:
            message.file.seek(0)
            fbs = message.file.read()
            message.file.seek(0)
            im: Image.Image = Image.open(io.BytesIO(fbs))

            max_size = max(im.size)
            min_size = min(im.size)
            img_ratio = max_size / min_size
            if img_ratio < 10.0:
                return

            im2 = im.copy()
            for _ in range(100):
                max_size = max(im.size)
                min_size = min(im.size)
                img_ratio = max_size / min_size
                if img_ratio >= 10.0:
                    if im.width == min_size:
                        im = im.resize((im.width * 2, im.height),
                                       box=(0, 0, 1, 1))
                    else:
                        im = im.resize((im.width, im.height * 2),
                                       box=(0, 0, 1, 1))
                    continue
                else:
                    break

            im.paste(im2, (0, 0, im2.width, im2.height))

            im3 = im.convert('RGB')  # im.copy()  #
            reply = Message()
            # reply.text = text
            # reply.chat = coordinator.slaves[message.chat.channel_id].get_chat(message.chat.chat_uid)
            reply.chat = coordinator.slaves[message.chat.module_id].get_chat(
                message.chat.uid)
            reply.author = message.chat.make_system_member(
                uid=self.middleware_id,
                name=self.middleware_name,
                middleware=self)

            reply.type = MsgType.Image
            reply.mime = 'image/png'
            f = tempfile.NamedTemporaryFile(suffix='.png')
            img_data = io.BytesIO()
            im3.save(img_data, format='png')
            f.write(img_data.getvalue())
            f.file.seek(0)
            reply.file = f
            reply.path = f.name
            reply.filename = os.path.basename(reply.file.name)

            # reply.deliver_to = coordinator.master
            reply.deliver_to = coordinator.master
            # reply.target = message
            reply.uid = str(uuid.uuid4())
            coordinator.send_message(reply)

        except BaseException as e:
            self.lg(f'handle_tg_img_preview e:{e}')
        pass
 def wechat_unsupported_msg(self, msg: wxpy.Message) -> Message:
     efb_msg = Message()
     efb_msg.type = MsgType.Unsupported
     efb_msg.text += self._("[Unsupported message, please check your phone.]")
     return efb_msg