embeds: make mediaproxy functions return list of embeds

- embeds: make mediaproxy functions check their types
This commit is contained in:
Luna 2020-01-24 21:13:34 -03:00
parent 6c802ad3fa
commit d8a24ad052
3 changed files with 24 additions and 25 deletions

View File

@ -49,7 +49,7 @@ from litecord.common.messages import (
msg_add_attachment, msg_add_attachment,
msg_guild_text_mentions, 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.messages import process_url_embed, is_media_url
from litecord.embed.schemas import EmbedURL from litecord.embed.schemas import EmbedURL
from litecord.utils import pg_set_json 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 # we still fetch the URL to check its validity, mimetypes, etc
# but in the end, we will store it under the webhook_avatars table, # but in the end, we will store it under the webhook_avatars table,
# not IconManager. # not IconManager.
resp, raw = await fetch_raw_img(avatar_url) resp, raw = await fetch_mediaproxy_img(avatar_url)
# raw_b64 = base64.b64encode(raw).decode() # raw_b64 = base64.b64encode(raw).decode()
mime = resp.headers["content-type"] mime = resp.headers["content-type"]

View File

@ -21,11 +21,12 @@ import re
import asyncio import asyncio
import urllib.parse import urllib.parse
from pathlib import Path from pathlib import Path
from typing import List
from quart import current_app as app from quart import current_app as app
from logbook import Logger 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 from litecord.embed.schemas import EmbedURL
log = Logger(__name__) log = Logger(__name__)
@ -34,7 +35,7 @@ log = Logger(__name__)
MEDIA_EXTENSIONS = ("png", "jpg", "jpeg", "gif", "webm") 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.""" """Insert media metadata as an embed."""
img_proxy_url = proxify(url) img_proxy_url = proxify(url)
meta = await fetch_metadata(url) meta = await fetch_metadata(url)
@ -105,12 +106,6 @@ def is_media_url(url) -> bool:
return extension in MEDIA_EXTENSIONS 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): async def process_url_embed(payload: dict, *, delay=0):
"""Process URLs in a message and generate embeds based on that.""" """Process URLs in a message and generate embeds based on that."""
await asyncio.sleep(delay) await asyncio.sleep(delay)
@ -143,17 +138,17 @@ async def process_url_embed(payload: dict, *, delay=0):
new_embeds = [] new_embeds = []
for url in urls: for url in urls:
url = EmbedURL(url) url: List[dict] = EmbedURL(url)
if is_media_url(url): if is_media_url(url):
embed = await insert_media_meta(url) embeds = [await fetch_mediaproxy_img_meta(url)]
else: else:
embed = await insert_mp_embed(url) embeds = await fetch_mediaproxy_embed(url)
if not embed: if not embeds:
continue continue
new_embeds.append(embed) new_embeds.extend(embeds)
# update if we got embeds # update if we got embeds
if not new_embeds: if not new_embeds:

View File

@ -111,7 +111,7 @@ def proxify(url) -> str:
async def _md_client_req( async def _md_client_req(
scope: str, url, *, ret_resp=False scope: str, url, *, ret_resp=False
) -> Optional[Union[Tuple, Dict]]: ) -> Optional[Union[Tuple, Dict, List[Dict]]]:
"""Makes a request to the mediaproxy. """Makes a request to the mediaproxy.
This has common code between all the main mediaproxy request functions This has common code between all the main mediaproxy request functions
@ -143,37 +143,41 @@ async def _md_client_req(
return await resp.json() return await resp.json()
body = await resp.text() body = await resp.read()
log.warning("failed to call {!r}, {} {!r}", request_url, resp.status, body) log.warning("failed to call {!r}, {} {!r}", request_url, resp.status, body)
return None return None
async def fetch_metadata(url) -> Optional[Dict]: async def fetch_metadata(url) -> Optional[Dict]:
"""Fetch metadata for a url (image width, mime, etc).""" """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). """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 Returns a tuple containing the response object and the raw bytes given by
the website. the website.
""" """
tup = await _md_client_req("img", url, ret_resp=True) tup = await _md_client_req("img", url, ret_resp=True)
assert tup is not None
if not tup: assert isinstance(tup, tuple)
return None
return tup 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 """Fetch an embed for a given webpage (an automatically generated embed
by the mediaproxy, look over the project on how it generates embeds). by the mediaproxy, look over the project on how it generates embeds).
Returns a discord embed object. 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]: async def fill_embed(embed: Optional[Embed]) -> Optional[Embed]: