Пример #1
0
 async def _send_comic(self, room_id: RoomID, comic: SatWInfo) -> None:
     info = await self._get_media_info(comic.image_url)
     body_html = escape(comic.body).replace("\n", "<br>")
     format = self.config["format"]
     if format == "inline":
         await self.client.send_text(room_id,
                                     text=f"{info.url}\n"
                                          f"# {comic.title}\n"
                                          f"{comic.body}",
                                     html=(f"<img src='{info.mxc_uri}' title='{comic.slug}'/>"
                                           f"<h1>{escape(comic.title)}</h1>"
                                           f"<p>{body_html}</p>"))
     elif format in ("separate", "filename"):
         filename = info.filename if format == "separate" else comic.title
         await self.client.send_image(room_id, url=info.mxc_uri, file_name=filename,
                                      info=ImageInfo(
                                          mimetype=info.mime_type,
                                          size=info.size,
                                          width=info.width,
                                          height=info.height,
                                      ))
         if format == "separate":
             await self.client.send_text(room_id, text=f"# {comic.title}\n{comic.body}",
                                         html=f"<h1>{escape(comic.title)}</h1>"
                                              f"<p>{body_html}</p>")
     else:
         self.log.error(f"Unknown format \"{self.config['format']}\" specified in config.")
Пример #2
0
 async def _send_xkcd(self, room_id: RoomID, xkcd: XKCDInfo) -> None:
     info = await self._get_media_info(xkcd.img)
     if self.config["inline"]:
         content = TextMessageEventContent(
             msgtype=MessageType.TEXT, format=Format.HTML,
             external_url=f"https://xkcd.com/{xkcd.num}",
             body=f"{xkcd.num}: **{xkcd.title}**\n"
                  f"{xkcd.img}\n{xkcd.alt}",
             formatted_body=f"{xkcd.num}: <strong>{xkcd.safe_title}</strong><br/>"
                            f"<img src='{info.mxc_uri}' title='{xkcd.alt}'/>")
         content["license"] = "CC-BY-NC-2.5"
         content["license_url"] = "https://xkcd.com/license.html"
         await self.client.send_message(room_id, content)
     else:
         await self.client.send_text(room_id, text=f"{xkcd.num}: **{xkcd.title}**",
                                     html=f"{xkcd.num}: <strong>{xkcd.safe_title}</strong>")
         content = MediaMessageEventContent(url=info.mxc_uri, body=info.file_name,
                                            msgtype=MessageType.IMAGE,
                                            external_url=f"https://xkcd.com/{xkcd.num}",
                                            info=ImageInfo(
                                                mimetype=info.mime_type,
                                                size=info.size,
                                                width=info.width,
                                                height=info.height,
                                            ),)
         content["license"] = "CC-BY-NC-2.5"
         content["license_url"] = "https://xkcd.com/license.html"
         await self.client.send_message(room_id, content)
         await self.client.send_text(room_id, text=xkcd.alt)
Пример #3
0
 async def _send_commit(self, room_id: RoomID, commit: CommitInfo) -> None:
     info = await self._get_media_info(commit.image_id)
     if self.config["format"] == "inline":
         await self.client.send_text(
             room_id,
             text=f"# {commit.title}\n{info.url}",
             html=(f"<h1>{escape(commit.title)}</h1><br/>"
                   f"<img src='{info.mxc_uri}'"
                   f"     title='{info.file_name}'/>"))
     elif self.config["format"] in ("separate", "filename"):
         if self.config["format"] == "separate":
             filename = info.file_name
             await self.client.send_text(
                 room_id,
                 text=f"# {commit.title}",
                 html=f"<h1>{escape(commit.title)}</h1>")
         else:
             filename = info.title
         await self.client.send_image(room_id,
                                      url=info.mxc_uri,
                                      file_name=filename,
                                      info=ImageInfo(
                                          mimetype=info.mime_type,
                                          size=info.size,
                                          width=info.width,
                                          height=info.height,
                                      ))
     else:
         self.log.error(
             f"Unknown format \"{self.config['format']}\" specified in config."
         )
Пример #4
0
 async def handle_telegram_photo(self, source: 'AbstractUser', intent: IntentAPI, evt: Message,
                                 relates_to: Dict = None) -> Optional[EventID]:
     loc, largest_size = self._get_largest_photo_size(evt.media.photo)
     file = await util.transfer_file_to_matrix(source.client, intent, loc)
     if not file:
         return None
     if self.get_config("inline_images") and (evt.message
                                              or evt.fwd_from or evt.reply_to_msg_id):
         content = await formatter.telegram_to_matrix(
             evt, source, self.main_intent,
             prefix_html=f"<img src='{file.mxc}' alt='Inline Telegram photo'/><br/>",
             prefix_text="Inline image: ")
         content.external_url = self._get_external_url(evt)
         await intent.set_typing(self.mxid, is_typing=False)
         return await intent.send_message(self.mxid, content, timestamp=evt.date)
     info = ImageInfo(
         height=largest_size.h, width=largest_size.w, orientation=0, mimetype=file.mime_type,
         size=(len(largest_size.bytes) if (isinstance(largest_size, PhotoCachedSize))
               else largest_size.size))
     name = f"image{sane_mimetypes.guess_extension(file.mime_type)}"
     await intent.set_typing(self.mxid, is_typing=False)
     content = MediaMessageEventContent(url=file.mxc, msgtype=MessageType.IMAGE, info=info,
                                        body=name, relates_to=relates_to,
                                        external_url=self._get_external_url(evt))
     result = await intent.send_message(self.mxid, content, timestamp=evt.date)
     if evt.message:
         caption_content = await formatter.telegram_to_matrix(evt, source, self.main_intent,
                                                              no_reply_fallback=True)
         caption_content.external_url = content.external_url
         result = await intent.send_message(self.mxid, caption_content, timestamp=evt.date)
     return result
Пример #5
0
    async def handler(self, evt: MessageEvent, search_term: str) -> None:
        await evt.mark_read()

        appid = self.config["appid"]
        url_params = urllib.parse.urlencode({"i": search_term, "appid": appid})
        gif_link = "https://api.wolframalpha.com/v1/simple?{}".format(
            url_params)
        resp = await self.http.get(gif_link)
        if resp.status == 501:
            await evt.reply("WolframAlpha doesn't understand your query")
            return None
        if resp.status != 200:
            self.log.warning(
                f"Unexpected status fetching image {gif_link}: {resp.status}")
            return None
        gif = await resp.read()

        filename = f"{search_term}.png" if len(
            search_term) > 0 else "wolfram.gif"
        uri = await self.client.upload_media(gif,
                                             mime_type='image/gif',
                                             filename=filename)

        await self.client.send_image(evt.room_id,
                                     url=uri,
                                     file_name=filename,
                                     info=ImageInfo(mimetype='image/png'))
Пример #6
0
 async def _handle_facebook_attachment(self, intent: IntentAPI, attachment: AttachmentClass
                                       ) -> Optional[EventID]:
     if isinstance(attachment, AudioAttachment):
         mxc, mime, size = await self._reupload_fb_photo(attachment.url, intent,
                                                         attachment.filename)
         event_id = await intent.send_file(self.mxid, mxc, file_type=MessageType.AUDIO,
                                           info=AudioInfo(size=size, mimetype=mime,
                                                          duration=attachment.duration),
                                           file_name=attachment.filename, )
     # elif isinstance(attachment, VideoAttachment):
     # TODO
     elif isinstance(attachment, FileAttachment):
         mxc, mime, size = await self._reupload_fb_photo(attachment.url, intent, attachment.name)
         event_id = await intent.send_file(self.mxid, mxc,
                                           info=FileInfo(size=size, mimetype=mime),
                                           file_name=attachment.name)
     elif isinstance(attachment, ImageAttachment):
         mxc, mime, size = await self._reupload_fb_photo(attachment.large_preview_url, intent)
         event_id = await intent.send_image(self.mxid, mxc,
                                            file_name=f"image.{attachment.original_extension}",
                                            info=ImageInfo(size=size, mimetype=mime,
                                                           width=attachment.large_preview_width,
                                                           height=attachment.large_preview_height))
     elif isinstance(attachment, LocationAttachment):
         content = await self._convert_facebook_location(intent, attachment)
         event_id = await intent.send_message(self.mxid, content)
     else:
         self.log.warn(f"Unsupported attachment type: {attachment}")
         return None
     self._last_bridged_mxid = event_id
     return event_id
Пример #7
0
 def _make_media_content(
         attachment: Attachment) -> MediaMessageEventContent:
     if attachment.content_type.startswith("image/"):
         msgtype = MessageType.IMAGE
         info = ImageInfo(mimetype=attachment.content_type,
                          width=attachment.width,
                          height=attachment.height)
     elif attachment.content_type.startswith("video/"):
         msgtype = MessageType.VIDEO
         info = VideoInfo(mimetype=attachment.content_type,
                          width=attachment.width,
                          height=attachment.height)
     elif attachment.voice_note or attachment.content_type.startswith(
             "audio/"):
         msgtype = MessageType.AUDIO
         info = AudioInfo(mimetype=attachment.content_type)
     else:
         msgtype = MessageType.FILE
         info = FileInfo(mimetype=attachment.content_type)
     if not attachment.custom_filename:
         ext = mimetypes.guess_extension(attachment.content_type) or ""
         attachment.custom_filename = attachment.id + ext
     return MediaMessageEventContent(msgtype=msgtype,
                                     info=info,
                                     body=attachment.custom_filename)
Пример #8
0
    async def tex(self, evt: MessageEvent, formula: str) -> None:
        fig = plot.figure(figsize=(0.01, 0.01))
        text = fig.text(0, 0, rf"${formula}$",
                        fontsize=self.config["font_size"],
                        usetex=self.config["use_tex"])
        info = ImageInfo(thumbnail_info=ThumbnailInfo())

        output = BytesIO()
        if self.config["mode"] == "svg":
            fig.savefig(output, format="svg", bbox_inches="tight")
            data = output.getvalue()

            file_name = "tex.svg"
            info.mimetype = "image/svg+xml"
            info.size = len(data)

            bb = text.get_window_extent(fig.canvas.get_renderer())
            info.width, info.height = int(bb.width), int(bb.height)

            uri = await self.client.upload_media(data, info.mimetype, file_name)
        else:
            fig.savefig(output, dpi=300, format="png", bbox_inches="tight")
            data = output.getvalue()

            file_name = "tex.png"
            info.mimetype = "image/png"
            info.size = len(data)

            output.seek(0)
            img = Image.open(output)
            info.width, info.height = img.size

            uri = await self.client.upload_media(data, info.mimetype, file_name)

        output.seek(0)
        output.truncate(0)
        fig.savefig(output, dpi=self.config["thumbnail_dpi"], format="png", bbox_inches="tight")

        data = output.getvalue()
        info.thumbnail_url = await self.client.upload_media(data, "image/png", "tex.thumb.png")
        info.thumbnail_info.size = len(data)
        plot.close(fig)

        output.seek(0)
        img = Image.open(output)
        info.thumbnail_info.width, info.thumbnail_info.height = img.size
        img.close()
        output.close()

        await self.client.send_image(evt.room_id, uri, info=info, file_name=file_name)
Пример #9
0
 async def _reupload_instagram_animated(
         self, source: 'u.User', media: AnimatedMediaItem,
         intent: IntentAPI) -> Optional[ReuploadedMediaInfo]:
     url = media.images.fixed_height.webp
     info = ImageInfo(height=int(media.images.fixed_height.height),
                      width=int(media.images.fixed_height.width))
     return await self._reupload_instagram_file(source, url,
                                                MessageType.IMAGE, info,
                                                intent)
Пример #10
0
 async def _handle_facebook_sticker(self, intent: IntentAPI, sticker: FBSticker) -> EventID:
     # TODO handle animated stickers?
     mxc, mime, size = await self._reupload_fb_photo(sticker.url, intent)
     return await intent.send_sticker(room_id=self.mxid, url=mxc,
                                      info=ImageInfo(width=sticker.width,
                                                     height=sticker.height,
                                                     mimetype=mime,
                                                     size=size),
                                      text=sticker.label)
Пример #11
0
 async def _handle_twitter_attachment(
         self, source: 'u.User', sender: 'p.Puppet',
         message: MessageData) -> Optional[MediaMessageEventContent]:
     content = None
     intent = sender.intent_for(self)
     media = message.attachment.media
     if media:
         reuploaded_info = await self._reupload_twitter_media(
             source, media.media_url_https, intent)
         thumbnail_info = None
         if media.video_info:
             thumbnail_info = reuploaded_info
             best_variant = None
             for variant in media.video_info.variants:
                 if ((not best_variant or (variant.bitrate or 0) >
                      (best_variant.bitrate or 0)
                      or self._is_better_mime(best_variant, variant))):
                     best_variant = variant
             reuploaded_info = await self._reupload_twitter_media(
                 source, best_variant.url, intent)
         content = MediaMessageEventContent(
             body=reuploaded_info.file_name,
             url=reuploaded_info.mxc,
             file=reuploaded_info.decryption_info,
             external_url=media.media_url_https)
         if message.attachment.video:
             content.msgtype = MessageType.VIDEO
             content.info = VideoInfo(
                 mimetype=reuploaded_info.mime_type,
                 size=reuploaded_info.size,
                 width=media.original_info.width,
                 height=media.original_info.height,
                 duration=media.video_info.duration_millis // 1000)
         elif message.attachment.photo or message.attachment.animated_gif:
             content.msgtype = MessageType.IMAGE
             content.info = ImageInfo(mimetype=reuploaded_info.mime_type,
                                      size=reuploaded_info.size,
                                      width=media.original_info.width,
                                      height=media.original_info.height)
         if thumbnail_info:
             content.info.thumbnail_url = thumbnail_info.mxc
             content.info.thumbnail_file = thumbnail_info.decryption_info
             content.info.thumbnail_info = ThumbnailInfo(
                 mimetype=thumbnail_info.mime_type,
                 size=thumbnail_info.size,
                 width=media.original_info.width,
                 height=media.original_info.height)
         # Remove the attachment link from message.text
         start, end = media.indices
         message.text = message.text[:start] + message.text[end:]
     elif message.attachment.tweet:
         # TODO special handling for tweets?
         pass
     return content
Пример #12
0
    def _parse_telegram_document_meta(
            evt: Message, file: DBTelegramFile, attrs: DocAttrs,
            thumb_size: TypePhotoSize) -> Tuple[ImageInfo, str]:
        document = evt.media.document
        name = evt.message or attrs.name
        if attrs.is_sticker:
            alt = attrs.sticker_alt
            if len(alt) > 0:
                try:
                    name = f"{alt} ({unicodedata.name(alt[0]).lower()})"
                except ValueError:
                    name = alt

        generic_types = ("text/plain", "application/octet-stream")
        if file.mime_type in generic_types and document.mime_type not in generic_types:
            mime_type = document.mime_type or file.mime_type
        elif file.mime_type == 'application/ogg':
            mime_type = 'audio/ogg'
        else:
            mime_type = file.mime_type or document.mime_type
        info = ImageInfo(size=file.size, mimetype=mime_type)

        if attrs.mime_type and not file.was_converted:
            file.mime_type = attrs.mime_type or file.mime_type
        if file.width and file.height:
            info.width, info.height = file.width, file.height
        elif attrs.width and attrs.height:
            info.width, info.height = attrs.width, attrs.height

        if file.thumbnail:
            info.thumbnail_url = file.thumbnail.mxc
            info.thumbnail_info = ThumbnailInfo(
                mimetype=file.thumbnail.mime_type,
                height=file.thumbnail.height or thumb_size.h,
                width=file.thumbnail.width or thumb_size.w,
                size=file.thumbnail.size)
        else:
            info.thumbnail_url = file.mxc
            info.thumbnail_info = ImageInfo.deserialize(info.serialize())

        return info, name
Пример #13
0
async def make_qr(intent: IntentAPI, data: Union[str, bytes], body: str = None
                  ) -> MediaMessageEventContent:
    # TODO always encrypt QR codes?
    buffer = io.BytesIO()
    image = qrcode.make(data)
    size = image.pixel_size
    image.save(buffer, "PNG")
    qr = buffer.getvalue()
    mxc = await intent.upload_media(qr, "image/png", "qr.png", len(qr))
    return MediaMessageEventContent(body=body or data, url=mxc, msgtype=MessageType.IMAGE,
                                    info=ImageInfo(mimetype="image/png", size=len(qr),
                                                   width=size, height=size))
Пример #14
0
 async def handle_telegram_photo(self, source: 'AbstractUser', intent: IntentAPI, evt: Message,
                                 relates_to: RelatesTo = None) -> Optional[EventID]:
     media: MessageMediaPhoto = evt.media
     if media.photo is None and media.ttl_seconds:
         return await self._send_message(intent, TextMessageEventContent(
             msgtype=MessageType.NOTICE, body="Photo has expired"))
     loc, largest_size = self._get_largest_photo_size(media.photo)
     if loc is None:
         content = TextMessageEventContent(msgtype=MessageType.TEXT,
                                           body="Failed to bridge image",
                                           external_url=self._get_external_url(evt))
         return await self._send_message(intent, content, timestamp=evt.date)
     file = await util.transfer_file_to_matrix(source.client, intent, loc,
                                               encrypt=self.encrypted)
     if not file:
         return None
     if self.get_config("inline_images") and (evt.message or evt.fwd_from or evt.reply_to):
         content = await formatter.telegram_to_matrix(
             evt, source, self.main_intent,
             prefix_html=f"<img src='{file.mxc}' alt='Inline Telegram photo'/><br/>",
             prefix_text="Inline image: ")
         content.external_url = self._get_external_url(evt)
         await intent.set_typing(self.mxid, is_typing=False)
         return await self._send_message(intent, content, timestamp=evt.date)
     info = ImageInfo(
         height=largest_size.h, width=largest_size.w, orientation=0, mimetype=file.mime_type,
         size=(len(largest_size.bytes) if (isinstance(largest_size, PhotoCachedSize))
               else largest_size.size))
     ext = sane_mimetypes.guess_extension(file.mime_type)
     name = f"disappearing_image{ext}" if media.ttl_seconds else f"image{ext}"
     await intent.set_typing(self.mxid, is_typing=False)
     content = MediaMessageEventContent(msgtype=MessageType.IMAGE, info=info,
                                        body=name, relates_to=relates_to,
                                        external_url=self._get_external_url(evt))
     if file.decryption_info:
         content.file = file.decryption_info
     else:
         content.url = file.mxc
     result = await self._send_message(intent, content, timestamp=evt.date)
     if media.ttl_seconds:
         self.loop.create_task(self._expire_telegram_photo(intent, result,
                                                           media.ttl_seconds))
     if evt.message:
         caption_content = await formatter.telegram_to_matrix(evt, source, self.main_intent,
                                                              no_reply_fallback=True)
         caption_content.external_url = content.external_url
         result = await self._send_message(intent, caption_content, timestamp=evt.date)
     return result
Пример #15
0
 async def callback(uri: str) -> None:
     buffer = io.BytesIO()
     image = qrcode.make(uri)
     size = image.pixel_size
     image.save(buffer, "PNG")
     qr = buffer.getvalue()
     mxc = await evt.az.intent.upload_media(qr, "image/png", "link-qr.png",
                                            len(qr))
     content = MediaMessageEventContent(body=uri,
                                        url=mxc,
                                        msgtype=MessageType.IMAGE,
                                        info=ImageInfo(mimetype="image/png",
                                                       size=len(qr),
                                                       width=size,
                                                       height=size))
     await evt.az.intent.send_message(evt.room_id, content)
Пример #16
0
    async def process_hangouts_attachments(
            self, event: ChatMessageEvent,
            intent: IntentAPI) -> Optional[EventID]:
        attachments_pb = event._event.chat_message.message_content.attachment

        if len(event.attachments) > 1:
            self.log.warning("Can't handle more that one attachment")
            return None

        attachment = event.attachments[0]
        attachment_pb = attachments_pb[0]

        embed_item = attachment_pb.embed_item

        # Get the filename from the headers
        async with self.az.http_session.request("GET", attachment) as resp:
            value, params = cgi.parse_header(
                resp.headers["Content-Disposition"])
            mime = resp.headers["Content-Type"]
            filename = params.get('filename', attachment.split("/")[-1])

        # TODO: This also catches movies, but I can't work out how they present
        #       differently to images
        if embed_item.type[0] == hangouts.ITEM_TYPE_PLUS_PHOTO:
            data = await self._get_remote_bytes(attachment)
            upload_mime = mime
            decryption_info = None
            if self.encrypted and encrypt_attachment:
                data, decryption_info_dict = encrypt_attachment(data)
                decryption_info = EncryptedFile.deserialize(
                    decryption_info_dict)
                upload_mime = "application/octet-stream"
            mxc_url = await intent.upload_media(data,
                                                mime_type=upload_mime,
                                                filename=filename)
            if decryption_info:
                decryption_info.url = mxc_url
            content = MediaMessageEventContent(url=mxc_url,
                                               file=decryption_info,
                                               body=filename,
                                               info=ImageInfo(size=len(data),
                                                              mimetype=mime),
                                               msgtype=MessageType.IMAGE)
            return await self._send_message(intent,
                                            content,
                                            timestamp=event.timestamp)
        return None
Пример #17
0
    async def send_gif(self, room_id: RoomID, gif_link: str, query: str, info: dict) -> None:
        resp = await self.http.get(gif_link)
        if resp.status != 200:
            self.log.warning(f"Unexpected status fetching image {url}: {resp.status}")
            return None
        
        data = await resp.read()
        mime = info['mime'] 
        filename = f"{query}.gif" if len(query) > 0 else "giphy.gif"
        uri = await self.client.upload_media(data, mime_type=mime, filename=filename)

        await self.client.send_image(room_id, url=uri, file_name=filename,
                info=ImageInfo(
                        mimetype=info['mime'],
                        width=info['width'],
                        height=info['height']
                    ))
Пример #18
0
 async def upload_qr() -> None:
     nonlocal qr_event_id
     buffer = io.BytesIO()
     image = qrcode.make(qr_login.url)
     size = image.pixel_size
     image.save(buffer, "PNG")
     qr = buffer.getvalue()
     mxc = await evt.az.intent.upload_media(qr, "image/png", "login-qr.png", len(qr))
     content = MediaMessageEventContent(body=qr_login.url, url=mxc, msgtype=MessageType.IMAGE,
                                        info=ImageInfo(mimetype="image/png", size=len(qr),
                                                       width=size, height=size))
     if qr_event_id:
         content.set_edit(qr_event_id)
         await evt.az.intent.send_message(evt.room_id, content)
     else:
         content.set_reply(evt.event_id)
         qr_event_id = await evt.az.intent.send_message(evt.room_id, content)
Пример #19
0
 async def _reupload(self,
                     url: URL,
                     title: Optional[str] = None,
                     dimensions: Optional[Tuple[int, int]] = None,
                     external_url: Optional[str] = None,
                     thumbnail_url: Optional[URL] = None,
                     thumbnail_dimensions: Optional[Tuple[int, int]] = None,
                     headers: Optional[Dict[str, str]] = None) -> Image:
     info = ImageInfo()
     if "user_agent" in self.config:
         headers["User-Agent"] = self.config["user_agent"]
     async with self.bot.http.get(url, headers=headers) as resp:
         data = await resp.read()
         info.size = len(data)
         info.mimetype = resp.headers["Content-Type"]
         if not info.mimetype:
             info.mimetype = magic.from_buffer(data, mime=True)
         if not title:
             title = self._get_filename(url, resp, info.mimetype)
     if dimensions:
         info.width, info.height = dimensions
     elif Pillow:
         img = Pillow.open(BytesIO(data))
         info.width, info.height = img.size
     mxc = await self.bot.client.upload_media(data, info.mimetype)
     if thumbnail_url:
         thumbnail = await self._reupload(thumbnail_url,
                                          title=title,
                                          headers=headers,
                                          dimensions=thumbnail_dimensions)
         info.thumbnail_url = thumbnail.url
         info.thumbnail_info = thumbnail.info
     return Image(url=mxc,
                  info=info,
                  title=title,
                  external_url=external_url)
Пример #20
0
 async def _handle_facebook_sticker(self, intent: IntentAPI,
                                    sticker: FBSticker,
                                    reply_to: str) -> EventID:
     # TODO handle animated stickers?
     mxc, mime, size, decryption_info = await self._reupload_fb_file(
         sticker.url, intent, encrypt=self.encrypted)
     return await self._send_message(
         intent,
         event_type=EventType.STICKER,
         content=MediaMessageEventContent(
             url=mxc,
             file=decryption_info,
             msgtype=MessageType.STICKER,
             body=sticker.label,
             info=ImageInfo(width=sticker.width,
                            size=size,
                            height=sticker.height,
                            mimetype=mime),
             relates_to=self._get_facebook_reply(reply_to)))
Пример #21
0
 async def _reupload_instagram_media(self, source: 'u.User', media: RegularMediaItem,
                                     intent: IntentAPI) -> Optional[ReuploadedMediaInfo]:
     if media.media_type == MediaType.IMAGE:
         image = media.best_image
         if not image:
             return None
         url = image.url
         msgtype = MessageType.IMAGE
         info = ImageInfo(height=image.height, width=image.width)
     elif media.media_type == MediaType.VIDEO:
         video = media.best_video
         if not video:
             return None
         url = video.url
         msgtype = MessageType.VIDEO
         info = VideoInfo(height=video.height, width=video.width)
     else:
         return None
     return await self._reupload_instagram_file(source, url, msgtype, info, intent)
Пример #22
0
 async def _reupload(self,
                     status: int) -> Optional[MediaMessageEventContent]:
     url = self.config["url"].format(status=status)
     self.log.info(f"Reuploading {url}")
     resp = await self.http.get(url)
     if resp.status != 200:
         resp.raise_for_status()
     data = await resp.read()
     img = Image.open(BytesIO(data))
     width, height = img.size
     mimetype = Image.MIME[img.format]
     filename = f"{status}{guess_extension(mimetype)}"
     mxc = await self.client.upload_media(data, mimetype, filename=filename)
     return MediaMessageEventContent(msgtype=MessageType.IMAGE,
                                     body=filename,
                                     url=mxc,
                                     info=ImageInfo(mimetype=mimetype,
                                                    size=len(data),
                                                    width=width,
                                                    height=height))
Пример #23
0
 async def _handle_twitter_attachment(
         self, source: 'u.User', sender: 'p.Puppet',
         message: MessageData) -> Optional[MediaMessageEventContent]:
     content = None
     intent = sender.intent_for(self)
     media = message.attachment.media
     if media:
         # TODO this doesn't actually work for gifs and videos
         #      The actual url is in media.video_info.variants[0].url
         #      Gifs are also videos
         reuploaded_info = await self._reupload_twitter_media(
             source, media, intent)
         content = MediaMessageEventContent(
             body=reuploaded_info.file_name,
             url=reuploaded_info.mxc,
             file=reuploaded_info.decryption_info,
             external_url=media.media_url_https)
         if message.attachment.video:
             content.msgtype = MessageType.VIDEO
             content.info = VideoInfo(
                 mimetype=reuploaded_info.mime_type,
                 size=reuploaded_info.size,
                 width=media.original_info.width,
                 height=media.original_info.height,
                 duration=media.video_info.duration_millis // 1000)
         elif message.attachment.photo or message.attachment.animated_gif:
             content.msgtype = MessageType.IMAGE
             content.info = ImageInfo(mimetype=reuploaded_info.mime_type,
                                      size=reuploaded_info.size,
                                      width=media.original_info.width,
                                      height=media.original_info.height)
         # Remove the attachment link from message.text
         start, end = media.indices
         message.text = message.text[:start] + message.text[end:]
     elif message.attachment.tweet:
         # TODO special handling for tweets?
         pass
     return content
Пример #24
0
 async def _handle_facebook_attachment(self, intent: IntentAPI,
                                       attachment: AttachmentClass,
                                       reply_to: str) -> Optional[EventID]:
     if isinstance(attachment, AudioAttachment):
         mxc, mime, size, decryption_info = await self._reupload_fb_file(
             attachment.url,
             intent,
             attachment.filename,
             encrypt=self.encrypted)
         event_id = await self._send_message(
             intent,
             MediaMessageEventContent(
                 url=mxc,
                 file=decryption_info,
                 msgtype=MessageType.AUDIO,
                 body=attachment.filename,
                 info=AudioInfo(size=size,
                                mimetype=mime,
                                duration=attachment.duration),
                 relates_to=self._get_facebook_reply(reply_to)))
     # elif isinstance(attachment, VideoAttachment):
     # TODO
     elif isinstance(attachment, FileAttachment):
         mxc, mime, size, decryption_info = await self._reupload_fb_file(
             attachment.url,
             intent,
             attachment.name,
             encrypt=self.encrypted)
         event_id = await self._send_message(
             intent,
             MediaMessageEventContent(
                 url=mxc,
                 file=decryption_info,
                 msgtype=MessageType.FILE,
                 body=attachment.name,
                 info=FileInfo(size=size, mimetype=mime),
                 relates_to=self._get_facebook_reply(reply_to)))
     elif isinstance(attachment, ImageAttachment):
         mxc, mime, size, decryption_info = await self._reupload_fb_file(
             attachment.large_preview_url or attachment.preview_url,
             intent,
             encrypt=self.encrypted)
         event_id = await self._send_message(
             intent,
             MediaMessageEventContent(
                 url=mxc,
                 file=decryption_info,
                 msgtype=MessageType.IMAGE,
                 body=f"image.{attachment.original_extension}",
                 info=ImageInfo(size=size,
                                mimetype=mime,
                                width=attachment.large_preview_width,
                                height=attachment.large_preview_height),
                 relates_to=self._get_facebook_reply(reply_to)))
     elif isinstance(attachment, LocationAttachment):
         content = await self._convert_facebook_location(intent, attachment)
         content.relates_to = self._get_facebook_reply(reply_to)
         event_id = await self._send_message(intent, content)
     elif isinstance(attachment, ShareAttachment):
         # These are handled in the text formatter
         return None
     else:
         self.log.warning(f"Unsupported attachment type: {attachment}")
         return None
     self._last_bridged_mxid = event_id
     return event_id
Пример #25
0
from mautrix.types import (MessageType, MediaMessageEventContent, ImageInfo,
                           ThumbnailInfo, ContentURI)

gif_versions: Dict[str, MediaMessageEventContent] = {
    "crap":
    MediaMessageEventContent(
        msgtype=MessageType.IMAGE,
        body="putkiteippi.gif",
        url=ContentURI("mxc://maunium.net/IkSoSYYrtaYJQeCaABSLqKiD"),
        info=ImageInfo(
            mimetype="image/gif",
            width=364,
            height=153,
            size=2079294,
            thumbnail_url=ContentURI(
                "mxc://maunium.net/iivOnCDjcGqGvnwnNWxSbAvb"),
            thumbnail_info=ThumbnailInfo(
                mimetype="image/png",
                width=364,
                height=153,
                size=51302,
            ),
        ),
    ),
    "low":
    MediaMessageEventContent(
        msgtype=MessageType.IMAGE,
        body="putkiteippi.gif",
        url=ContentURI("mxc://maunium.net/PXbFbVEmcGzkaMXwUOrzZcQM"),
        info=ImageInfo(
            mimetype="image/gif",
            width=640,
Пример #26
0
    async def _handle_facebook_attachment(
            self, intent: IntentAPI, attachment: AttachmentClass,
            reply_to: str, message_text: str) -> Optional[EventID]:
        if isinstance(attachment, AudioAttachment):
            mxc, mime, size = await self._reupload_fb_photo(
                attachment.url, intent, attachment.filename)
            event_id = await intent.send_file(
                self.mxid,
                mxc,
                file_type=MessageType.AUDIO,
                info=AudioInfo(size=size,
                               mimetype=mime,
                               duration=attachment.duration),
                file_name=attachment.filename,
                relates_to=self._get_facebook_reply(reply_to))
        # elif isinstance(attachment, VideoAttachment):
        # TODO
        elif isinstance(attachment, FileAttachment):
            mxc, mime, size = await self._reupload_fb_photo(
                attachment.url, intent, attachment.name)
            event_id = await intent.send_file(
                self.mxid,
                mxc,
                info=FileInfo(size=size, mimetype=mime),
                file_name=attachment.name,
                relates_to=self._get_facebook_reply(reply_to))
        elif isinstance(attachment, ImageAttachment):
            mxc, mime, size = await self._reupload_fb_photo(
                attachment.large_preview_url or attachment.preview_url, intent)
            info = ImageInfo(size=size,
                             mimetype=mime,
                             width=attachment.large_preview_width,
                             height=attachment.large_preview_height)
            event_id = await intent.send_image(
                self.mxid,
                mxc,
                info=info,
                file_name=f"image.{attachment.original_extension}",
                relates_to=self._get_facebook_reply(reply_to))
        elif isinstance(attachment, LocationAttachment):
            content = await self._convert_facebook_location(intent, attachment)
            content.relates_to = self._get_facebook_reply(reply_to)
            event_id = await intent.send_message(self.mxid, content)
        elif isinstance(attachment, ShareAttachment):
            # remove trailing slash for url searching
            url = attachment.original_url
            if url[-1] == "/":
                url = url[0:-1]

            title = attachment.title
            if title == "":
                title = url
            # Prevent sending urls that are already in the original message text
            if message_text is not None and url not in message_text:
                content = TextMessageEventContent(
                    msgtype=MessageType.TEXT,
                    body=f"{title}: {attachment.original_url}")
                content.format = Format.HTML
                content.formatted_body = f"<a href='{attachment.original_url}'>{title}</a>"
                event_id = await intent.send_message(self.mxid, content)
            elif message_text is None:
                content = TextMessageEventContent(
                    msgtype=MessageType.TEXT,
                    body=f"{title}: {attachment.original_url}")
                content.format = Format.HTML
                content.formatted_body = f"<a href='{attachment.original_url}'>{title}</a>"
                event_id = await intent.send_message(self.mxid, content)
            else:
                return None
        else:
            self.log.warning(f"Unsupported attachment type: {attachment}")
            return None
        self._last_bridged_mxid = event_id
        return event_id