From d848f3f1bc994445c3b210aa632ca7833d29b185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E5=9D=82=E9=9B=85?= <23130178+ShadowRZ@users.noreply.github.com> Date: Mon, 13 Feb 2023 17:23:29 +0800 Subject: [PATCH] Update --- nyx_bot/chat_functions.py | 2 +- nyx_bot/multiquote.py | 3 +- nyx_bot/quote_image.py | 66 +++++++++++++++++++++++++++++++++++++- nyx_bot/utils.py | 67 ++------------------------------------- 4 files changed, 70 insertions(+), 68 deletions(-) diff --git a/nyx_bot/chat_functions.py b/nyx_bot/chat_functions.py index 30ae2d9..a5e14aa 100644 --- a/nyx_bot/chat_functions.py +++ b/nyx_bot/chat_functions.py @@ -28,13 +28,13 @@ from wand.image import Image from nyx_bot.errors import NyxBotRuntimeError, NyxBotValueError from nyx_bot.multiquote import make_multiquote_image +from nyx_bot.quote_image import make_single_quote_image from nyx_bot.storage import MatrixMessage from nyx_bot.utils import ( get_body, get_external_url, get_replaces, make_datetime, - make_single_quote_image, strip_beginning_quote, user_name, ) diff --git a/nyx_bot/multiquote.py b/nyx_bot/multiquote.py index fcf40e6..491cc56 100644 --- a/nyx_bot/multiquote.py +++ b/nyx_bot/multiquote.py @@ -2,7 +2,8 @@ from nio import AsyncClient, MatrixRoom, RoomMessageText from wand.drawing import Drawing from wand.image import Image -from nyx_bot.utils import get_replaces, make_single_quote_image, strip_beginning_quote +from nyx_bot.quote_image import make_single_quote_image +from nyx_bot.utils import get_replaces, strip_beginning_quote async def make_multiquote_image( diff --git a/nyx_bot/quote_image.py b/nyx_bot/quote_image.py index 82725c5..955af7e 100644 --- a/nyx_bot/quote_image.py +++ b/nyx_bot/quote_image.py @@ -3,15 +3,27 @@ import os.path from asyncio import create_subprocess_exec from asyncio.subprocess import PIPE from html import escape +from io import BytesIO from os import remove from tempfile import mkstemp from typing import Optional +from nio import AsyncClient, DownloadError, MatrixRoom, RoomMessageText from wand.drawing import Drawing from wand.image import Image from wand.version import MAGICK_VERSION_INFO import nyx_bot +from nyx_bot.errors import NyxBotRuntimeError +from nyx_bot.parsers import MatrixHTMLParser +from nyx_bot.storage import UserTag +from nyx_bot.utils import ( + get_body, + get_formatted_body, + get_reply_to, + strip_beginning_quote, + user_name, +) logger = logging.getLogger(__name__) @@ -23,7 +35,7 @@ BORDER_MARGIN = 8 MASK_FILE = os.path.join(nyx_bot.__path__[0], "mask.png") -async def make_quote_image( +async def _make_quote_image( sender: Optional[str], text: str, avatar: Optional[Image], @@ -121,3 +133,55 @@ async def render_text(text: str) -> str: if stderr: print(f"[stderr]\n{stderr}") return path + + +async def make_single_quote_image( + client: AsyncClient, + room: MatrixRoom, + target_event: RoomMessageText, + replace_map: dict, + show_user: bool = True, +) -> Image: + sender = target_event.sender + body = "" + formatted = True + formatted_body = await get_formatted_body( + client, room, target_event.event_id, replace_map + ) + if not formatted_body: + formatted = False + if formatted: + parser = MatrixHTMLParser() + parser.feed(formatted_body) + body = parser.into_pango_markup() + else: + body = await get_body(client, room.room_id, target_event.event_id, replace_map) + if get_reply_to(target_event): + body = strip_beginning_quote(body) + if len(body) > 1000: + body_stripped = body[:1000] + body = f"{body_stripped}..." + sender_name = user_name(room, sender) + sender_avatar = room.avatar_url(sender) + image = None + if show_user: + if sender_avatar: + avatar_resp = await client.download(mxc=sender_avatar) + if isinstance(avatar_resp, DownloadError): + error = avatar_resp.message + raise NyxBotRuntimeError(f"Failed to download {sender_avatar}: {error}") + data = avatar_resp.body + bytesio = BytesIO(data) + image = Image(file=bytesio) + else: + image = Image(width=64, height=64, background="#FFFF00") + else: + sender_name = None + user_tag = UserTag.get_or_none( + (UserTag.room_id == room.room_id) & (UserTag.sender == sender) + ) + tag_name = None + if user_tag: + tag_name = f"#{user_tag.tag}" + quote_image = await _make_quote_image(sender_name, body, image, formatted, tag_name) + return quote_image diff --git a/nyx_bot/utils.py b/nyx_bot/utils.py index 5fbed8d..130ddcc 100644 --- a/nyx_bot/utils.py +++ b/nyx_bot/utils.py @@ -1,26 +1,15 @@ import math from datetime import datetime from html.parser import HTMLParser -from io import BytesIO, StringIO +from io import StringIO from random import Random from typing import Dict, Optional, Tuple from urllib.parse import unquote, urlparse from zlib import crc32 -from nio import ( - AsyncClient, - DownloadError, - Event, - MatrixRoom, - RoomGetEventError, - RoomMessageText, -) -from wand.image import Image +from nio import AsyncClient, Event, MatrixRoom, RoomGetEventError, RoomMessageText from nyx_bot.errors import NyxBotRuntimeError -from nyx_bot.parsers import MatrixHTMLParser -from nyx_bot.quote_image import make_quote_image -from nyx_bot.storage import UserTag def user_name(room: MatrixRoom, user_id: str) -> Optional[str]: @@ -151,58 +140,6 @@ def parse_matrixdotto_link(link: str): return "event", room, event_id -async def make_single_quote_image( - client: AsyncClient, - room: MatrixRoom, - target_event: RoomMessageText, - replace_map: dict, - show_user: bool = True, -) -> Image: - sender = target_event.sender - body = "" - formatted = True - formatted_body = await get_formatted_body( - client, room, target_event.event_id, replace_map - ) - if not formatted_body: - formatted = False - if formatted: - parser = MatrixHTMLParser() - parser.feed(formatted_body) - body = parser.into_pango_markup() - else: - body = await get_body(client, room.room_id, target_event.event_id, replace_map) - if get_reply_to(target_event): - body = strip_beginning_quote(body) - if len(body) > 1000: - body_stripped = body[:1000] - body = f"{body_stripped}..." - sender_name = user_name(room, sender) - sender_avatar = room.avatar_url(sender) - image = None - if show_user: - if sender_avatar: - avatar_resp = await client.download(mxc=sender_avatar) - if isinstance(avatar_resp, DownloadError): - error = avatar_resp.message - raise NyxBotRuntimeError(f"Failed to download {sender_avatar}: {error}") - data = avatar_resp.body - bytesio = BytesIO(data) - image = Image(file=bytesio) - else: - image = Image(width=64, height=64, background="#FFFF00") - else: - sender_name = None - user_tag = UserTag.get_or_none( - (UserTag.room_id == room.room_id) & (UserTag.sender == sender) - ) - tag_name = None - if user_tag: - tag_name = f"#{user_tag.tag}" - quote_image = await make_quote_image(sender_name, body, image, formatted, tag_name) - return quote_image - - def make_divergence(room: MatrixRoom): seed = crc32(room.room_id.encode()) divergence = Random(seed)