This commit is contained in:
夜坂雅 2023-02-13 17:23:29 +08:00
parent 1734650394
commit d848f3f1bc
4 changed files with 70 additions and 68 deletions

View file

@ -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,
)

View file

@ -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(

View file

@ -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

View file

@ -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)