drop base64://

This commit is contained in:
felinae98 2021-09-07 10:47:49 +08:00
parent 7570f65ddf
commit b53c6bdca6
No known key found for this signature in database
GPG Key ID: 00C8B010587FF610
5 changed files with 423 additions and 236 deletions

590
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -20,14 +20,14 @@ classifiers = [
[tool.poetry.dependencies]
python = "^3.9"
nonebot2 = "^2.0.0-alpha.8"
nonebot2 = "^2.0.0-alpha.15"
httpx = ">=0.16.1 <1.0.0"
bs4 = "^0.0.1"
tinydb = "^4.3.0"
feedparser = "^6.0.2"
pyppeteer = "^0.2.5"
pillow = "^8.1.0"
nonebot-adapter-cqhttp = "^2.0.0-alpha.13"
nonebot-adapter-cqhttp = "^2.0.0-alpha.15"
apscheduler = "^3.7.0"
[tool.poetry.dev-dependencies]

View File

@ -50,7 +50,7 @@ class Arknights(NewMessage, NoTargetMixin):
render = Render()
viewport = {'width': 320, 'height': 6400, 'deviceScaleFactor': 3}
pic_data = await render.render(announce_url, viewport=viewport, target='div.main')
pics.append('base64://{}'.format(pic_data))
pics.append(pic_data)
elif (pic := soup.find('img', class_='banner-image')):
pics.append(pic['src'])
else:
@ -84,7 +84,7 @@ class AkVersion(NoTargetMixin, StatusChange):
if old_status.get('preAnnounceType') == 2 and new_status.get('preAnnounceType') == 0:
res.append(Post('arknights', text='开始维护!', target_name='明日方舟更新信息'))
elif old_status.get('preAnnounceType') == 0 and new_status.get('preAnnounceType') == 2:
res.append(Post('arknights', text='维护结束!冲!', target_name='明日方舟更新信息'))
res.append(Post('arknights', text='维护结束!冲!(可能不太准确)', target_name='明日方舟更新信息'))
if old_status.get('clientVersion') != new_status.get('clientVersion'):
res.append(Post('arknights', text='游戏本体更新(大更新)', target_name='明日方舟更新信息'))
if old_status.get('resVersion') != new_status.get('resVersion'):

View File

@ -1,11 +1,12 @@
import base64
from dataclasses import dataclass, field
from io import BytesIO
from typing import Optional
from typing import Optional, Union
from PIL import Image
import httpx
from nonebot import logger
from nonebot.adapters.cqhttp.message import Message, MessageSegment
from .plugin_config import plugin_config
from .utils import parse_text
@ -19,7 +20,8 @@ class Post:
target_name: Optional[str] = None
compress: bool = False
override_use_pic: Optional[bool] = None
pics: list[str] = field(default_factory=list)
pics: list[Union[str,bytes]] = field(default_factory=list)
extra_msg = list[Message]
_message: Optional[list] = None
@ -28,11 +30,14 @@ class Post:
return self.override_use_pic
return plugin_config.hk_reporter_use_pic
async def _pic_url_to_image(self, url: str) -> Image.Image:
async with httpx.AsyncClient() as client:
res = await client.get(url)
async def _pic_url_to_image(self, data: Union[str, bytes]) -> Image.Image:
pic_buffer = BytesIO()
pic_buffer.write(res.content)
if isinstance(data, str):
async with httpx.AsyncClient() as client:
res = await client.get(data)
pic_buffer.write(res.content)
else:
pic_buffer.write(data)
return Image.open(pic_buffer)
def _check_image_square(self, size: tuple[int, int]) -> bool:
@ -93,9 +98,8 @@ class Post:
))
target_io = BytesIO()
target.save(target_io, 'JPEG')
b64image = 'base64://' + base64.b64encode(target_io.getvalue()).decode()
self.pics = self.pics[matrix[0] * matrix[1]: ]
self.pics.insert(0, b64image)
self.pics.insert(0, target_io.getvalue())
async def generate_messages(self):
if self._message is None:
@ -110,15 +114,19 @@ class Post:
if self._use_pic():
msgs.append(await parse_text(text))
if not self.target_type == 'rss' and self.url:
msgs.append(self.url)
msgs.append(MessageSegment.text(self.url))
else:
if self.url:
text += ' \n详情: {}'.format(self.url)
msgs.append(text)
msgs.append(MessageSegment.text(text))
for pic in self.pics:
msgs.append("[CQ:image,file={url}]".format(url=pic))
# if isinstance(pic, bytes):
# pic = 'base64://' + base64.b64encode(pic).decode()
# msgs.append(Message("[CQ:image,file={url}]".format(url=pic)))
msgs.append(MessageSegment.image(pic))
if self.compress:
msgs = [''.join(msgs)]
msgs = Message([msgs])
msgs += self.extra_msg
self._message = msgs
return self._message
@ -128,5 +136,5 @@ class Post:
self.target_name,
self.text if len(self.text) < 500 else self.text[:500] + '...',
self.url,
', '.join(map(lambda x: 'b64img' if x.startswith('base64') else x, self.pics))
', '.join(map(lambda x: 'b64img' if isinstance(x, bytes) or x.startswith('base64') else x, self.pics))
)

View File

@ -3,6 +3,7 @@ import base64
from html import escape
from typing import Awaitable, Callable, Optional
from urllib.parse import quote
from nonebot.adapters.cqhttp.message import MessageSegment
from nonebot.log import logger
from pyppeteer import connect, launch
@ -45,7 +46,7 @@ class Render(metaclass=Singleton):
await self.browser.close()
async def render(self, url: str, viewport: Optional[dict] = None, target: Optional[str] = None,
operation: Optional[Callable[[Page], Awaitable[None]]] = None) -> Optional[str]:
operation: Optional[Callable[[Page], Awaitable[None]]] = None) -> Optional[bytes]:
retry_times = 0
while retry_times < 3:
try:
@ -63,7 +64,7 @@ class Render(metaclass=Singleton):
logger.debug(message)
async def do_render(self, url: str, viewport: Optional[dict] = None, target: Optional[str] = None,
operation: Optional[Callable[[Page], Awaitable[None]]] = None) -> str:
operation: Optional[Callable[[Page], Awaitable[None]]] = None) -> Optional[bytes]:
async with self.lock:
self.browser = await self.get_browser()
self._inter_log('open browser')
@ -78,17 +79,20 @@ class Render(metaclass=Singleton):
self._inter_log('set viewport')
if target:
target_ele = await page.querySelector(target)
data = await target_ele.screenshot(type='jpeg', encoding='base64')
if not target_ele:
return None
data = await target_ele.screenshot(type='jpeg', encoding='binary')
else:
data = await page.screenshot(type='jpeg', encoding='base64')
data = await page.screenshot(type='jpeg', encoding='binary')
self._inter_log('screenshot')
await page.close()
self._inter_log('close page')
await self.close_browser()
self._inter_log('close browser')
return str(data)
assert(isinstance(data, bytes))
return data
async def text_to_pic(self, text: str) -> Optional[str]:
async def text_to_pic(self, text: str) -> Optional[bytes]:
lines = text.split('\n')
parsed_lines = list(map(lambda x: '<p>{}</p>'.format(escape(x)), lines))
html_text = '<div style="width:17em;padding:1em">{}</div>'.format(''.join(parsed_lines))
@ -96,20 +100,19 @@ class Render(metaclass=Singleton):
data = await self.render(url, target='div')
return data
async def text_to_pic_cqcode(self, text:str) -> str:
async def text_to_pic_cqcode(self, text:str) -> MessageSegment:
data = await self.text_to_pic(text)
# logger.debug('file size: {}'.format(len(data)))
if data:
code = '[CQ:image,file=base64://{}]'.format(data)
# logger.debug(code)
return code
return MessageSegment.image(data)
else:
return '生成图片错误'
return MessageSegment.text('生成图片错误')
async def parse_text(text: str) -> str:
async def parse_text(text: str) -> MessageSegment:
'return raw text if don\'t use pic, otherwise return rendered opcode'
if plugin_config.hk_reporter_use_pic:
render = Render()
return await render.text_to_pic_cqcode(text)
else:
return text
return MessageSegment.text(text)