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 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]
예제 #3
0
 def edit_file_like_message(self,
                            message: Message,
                            file_path: Path,
                            mime: str,
                            reactions: bool = False,
                            commands: bool = False,
                            substitution: bool = False) -> Message:
     message.text = f"Content of edited {message.type.name} media with ID {message.uid}"
     message.edit = True
     message.edit_media = True
     message.file = file_path.open('rb')
     message.filename = file_path.name
     message.path = file_path
     message.mime = mime
     message = self.attach_message_properties(message, reactions, commands,
                                              substitution)
     self.messages_sent[message.uid] = message
     coordinator.send_message(message)
     return message
예제 #4
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)
예제 #5
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)
    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]
예제 #7
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
예제 #8
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