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.")
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)
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." )
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
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'))
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
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)
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)
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)
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)
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
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
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))
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
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)
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
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'] ))
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)
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)
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)))
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)
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))
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
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
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,
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