diff --git a/litecord/blueprints/webhooks.py b/litecord/blueprints/webhooks.py index 7cfd69f..9f5cd30 100644 --- a/litecord/blueprints/webhooks.py +++ b/litecord/blueprints/webhooks.py @@ -49,7 +49,7 @@ from litecord.common.messages import ( msg_add_attachment, msg_guild_text_mentions, ) -from litecord.embed.sanitizer import fill_embed, fetch_raw_img +from litecord.embed.sanitizer import fill_embed, fetch_mediaproxy_img from litecord.embed.messages import process_url_embed, is_media_url from litecord.embed.schemas import EmbedURL from litecord.utils import pg_set_json @@ -423,7 +423,7 @@ async def _create_avatar(webhook_id: int, avatar_url: EmbedURL) -> str: # we still fetch the URL to check its validity, mimetypes, etc # but in the end, we will store it under the webhook_avatars table, # not IconManager. - resp, raw = await fetch_raw_img(avatar_url) + resp, raw = await fetch_mediaproxy_img(avatar_url) # raw_b64 = base64.b64encode(raw).decode() mime = resp.headers["content-type"] diff --git a/litecord/embed/messages.py b/litecord/embed/messages.py index bc240ea..7f60dc8 100644 --- a/litecord/embed/messages.py +++ b/litecord/embed/messages.py @@ -21,11 +21,12 @@ import re import asyncio import urllib.parse from pathlib import Path +from typing import List from quart import current_app as app from logbook import Logger -from litecord.embed.sanitizer import proxify, fetch_metadata, fetch_embed +from litecord.embed.sanitizer import proxify, fetch_metadata, fetch_mediaproxy_embed from litecord.embed.schemas import EmbedURL log = Logger(__name__) @@ -34,7 +35,7 @@ log = Logger(__name__) MEDIA_EXTENSIONS = ("png", "jpg", "jpeg", "gif", "webm") -async def insert_media_meta(url): +async def fetch_mediaproxy_img_meta(url) -> dict: """Insert media metadata as an embed.""" img_proxy_url = proxify(url) meta = await fetch_metadata(url) @@ -105,12 +106,6 @@ def is_media_url(url) -> bool: return extension in MEDIA_EXTENSIONS -async def insert_mp_embed(parsed): - """Insert mediaproxy embed.""" - embed = await fetch_embed(parsed) - return embed - - async def process_url_embed(payload: dict, *, delay=0): """Process URLs in a message and generate embeds based on that.""" await asyncio.sleep(delay) @@ -143,17 +138,17 @@ async def process_url_embed(payload: dict, *, delay=0): new_embeds = [] for url in urls: - url = EmbedURL(url) + url: List[dict] = EmbedURL(url) if is_media_url(url): - embed = await insert_media_meta(url) + embeds = [await fetch_mediaproxy_img_meta(url)] else: - embed = await insert_mp_embed(url) + embeds = await fetch_mediaproxy_embed(url) - if not embed: + if not embeds: continue - new_embeds.append(embed) + new_embeds.extend(embeds) # update if we got embeds if not new_embeds: diff --git a/litecord/embed/sanitizer.py b/litecord/embed/sanitizer.py index 14e8977..992522b 100644 --- a/litecord/embed/sanitizer.py +++ b/litecord/embed/sanitizer.py @@ -111,7 +111,7 @@ def proxify(url) -> str: async def _md_client_req( scope: str, url, *, ret_resp=False -) -> Optional[Union[Tuple, Dict]]: +) -> Optional[Union[Tuple, Dict, List[Dict]]]: """Makes a request to the mediaproxy. This has common code between all the main mediaproxy request functions @@ -143,37 +143,41 @@ async def _md_client_req( return await resp.json() - body = await resp.text() + body = await resp.read() log.warning("failed to call {!r}, {} {!r}", request_url, resp.status, body) return None async def fetch_metadata(url) -> Optional[Dict]: """Fetch metadata for a url (image width, mime, etc).""" - return await _md_client_req("meta", url) + body = await _md_client_req("meta", url) + assert body is not None + assert isinstance(body, dict) + return body -async def fetch_raw_img(url) -> Optional[tuple]: +async def fetch_mediaproxy_img(url) -> Optional[tuple]: """Fetch raw data for a url (the bytes given off, used to proxy images). Returns a tuple containing the response object and the raw bytes given by the website. """ tup = await _md_client_req("img", url, ret_resp=True) - - if not tup: - return None - + assert tup is not None + assert isinstance(tup, tuple) return tup -async def fetch_embed(url) -> Dict[str, Any]: +async def fetch_mediaproxy_embed(url) -> List[Dict[str, Any]]: """Fetch an embed for a given webpage (an automatically generated embed by the mediaproxy, look over the project on how it generates embeds). Returns a discord embed object. """ - return await _md_client_req("embed", url) + resp = await _md_client_req("embed", url) + assert resp is not None + assert isinstance(resp, list) + return resp async def fill_embed(embed: Optional[Embed]) -> Optional[Embed]: