import base64
import traceback
from typing import List, Union
import aiohttp
import filetype as ft
import ujson as json
from PIL import Image as PImage
from aiofile import async_open
from config import Config
from core.builtins import Plain, Image, Voice, Embed, MessageChain
from core.logger import Logger
from core.utils.cache import random_cache_path
from core.utils.http import download_to_cache
web_render = Config('web_render')
web_render_local = Config('web_render_local')
async def image_split(i: Image) -> List[Image]:
i = PImage.open(await i.get())
iw, ih = i.size
if ih <= 1500:
return [Image(i)]
_h = 0
i_list = []
for x in range((ih // 1500) + 1):
if _h + 1500 > ih:
crop_h = ih
else:
crop_h = _h + 1500
i_list.append(Image(i.crop((0, _h, iw, crop_h))))
_h = crop_h
return i_list
save_source = True
async def msgchain2image(msgchain: Union[List, MessageChain], use_local=True):
if not web_render_local:
if not web_render:
Logger.warn('[Webrender] Webrender is not configured.')
return False
use_local = False
if isinstance(msgchain, List):
msgchain = MessageChain(msgchain)
lst = []
html_template = """
Document
${content}
"""
for m in msgchain.asSendable(embed=False):
if isinstance(m, Plain):
lst.append('' + m.text.replace('\n', '
') + '
')
if isinstance(m, Image):
async with async_open(await m.get(), 'rb') as fi:
data = await fi.read()
try:
ftt = ft.match(data)
lst.append(
f'')
except TypeError:
traceback.print_exc()
if isinstance(m, Voice):
lst.append('[Voice]
')
if isinstance(m, Embed):
lst.append('[Embed]
')
pic = False
d = {'content': html_template.replace('${content}', '\n'.join(lst)), 'element': '.botbox'}
html_ = json.dumps(d)
fname = random_cache_path() + '.html'
with open(fname, 'w', encoding='utf-8') as fi:
fi.write(d['content'])
try:
pic = await download_to_cache((web_render_local if use_local else web_render) + '/element_screenshot',
status_code=200,
headers={'Content-Type': 'application/json'},
method="POST",
post_data=html_,
attempt=1,
timeout=30,
request_private_ip=True
)
except aiohttp.ClientConnectorError:
if use_local:
pic = await download_to_cache(web_render, method='POST', headers={
'Content-Type': 'application/json',
}, post_data=html_, request_private_ip=True)
else:
return False
return pic