mirror of
https://github.com/suyiiyii/nonebot-bison.git
synced 2025-06-05 19:36:43 +08:00
add retry for render
This commit is contained in:
parent
6947079dbf
commit
254e39f615
@ -2,11 +2,14 @@ import asyncio
|
|||||||
from html import escape
|
from html import escape
|
||||||
import os
|
import os
|
||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
|
from time import asctime
|
||||||
from typing import Awaitable, Callable, Optional
|
from typing import Awaitable, Callable, Optional
|
||||||
|
|
||||||
from pyppeteer import launch
|
from pyppeteer import launch
|
||||||
|
from pyppeteer.browser import Browser
|
||||||
from pyppeteer.chromium_downloader import check_chromium, download_chromium
|
from pyppeteer.chromium_downloader import check_chromium, download_chromium
|
||||||
from pyppeteer.page import Page
|
from pyppeteer.page import Page
|
||||||
|
from nonebot.log import logger
|
||||||
|
|
||||||
from .plugin_config import plugin_config
|
from .plugin_config import plugin_config
|
||||||
|
|
||||||
@ -28,31 +31,56 @@ class Render(metaclass=Singleton):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.lock = asyncio.Lock()
|
self.lock = asyncio.Lock()
|
||||||
|
self.browser: Browser
|
||||||
|
self.interval_log = ''
|
||||||
|
|
||||||
async def render(self, url: str, viewport: Optional[dict] = None, target: Optional[str] = None,
|
async def render(self, url: str, viewport: Optional[dict] = None, target: Optional[str] = None,
|
||||||
|
operation: Optional[Callable[[Page], Awaitable[None]]] = None) -> Optional[str]:
|
||||||
|
retry_times = 0
|
||||||
|
while retry_times < 3:
|
||||||
|
try:
|
||||||
|
return await asyncio.wait_for(self.do_render(url, viewport, target, operation), 10)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
retry_times += 1
|
||||||
|
logger.warning("render error {}\n".format(retry_times) + self.interval_log)
|
||||||
|
self.interval_log = ''
|
||||||
|
if self.browser:
|
||||||
|
await self.browser.close()
|
||||||
|
|
||||||
|
def _inter_log(self, message: str) -> None:
|
||||||
|
# self.interval_log += asctime() + '' + message + '\n'
|
||||||
|
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) -> str:
|
||||||
async with self.lock:
|
async with self.lock:
|
||||||
if plugin_config.hk_reporter_use_local:
|
if plugin_config.hk_reporter_use_local:
|
||||||
browser = await launch(executablePath='/usr/bin/chromium', args=['--no-sandbox'])
|
self.browser = await launch(executablePath='/usr/bin/chromium', args=['--no-sandbox'])
|
||||||
else:
|
else:
|
||||||
browser = await launch(args=['--no-sandbox'])
|
self.browser = await launch(args=['--no-sandbox'])
|
||||||
page = await browser.newPage()
|
self._inter_log('open browser')
|
||||||
|
page = await self.browser.newPage()
|
||||||
if operation:
|
if operation:
|
||||||
await operation(page)
|
await operation(page)
|
||||||
else:
|
else:
|
||||||
await page.goto(url)
|
await page.goto(url)
|
||||||
|
self._inter_log('open page')
|
||||||
if viewport:
|
if viewport:
|
||||||
await page.setViewport(viewport)
|
await page.setViewport(viewport)
|
||||||
|
logger._inter_log('set viewport')
|
||||||
if target:
|
if target:
|
||||||
target_ele = await page.querySelector(target)
|
target_ele = await page.querySelector(target)
|
||||||
data = await target_ele.screenshot(type='jpeg', encoding='base64')
|
data = await target_ele.screenshot(type='jpeg', encoding='base64')
|
||||||
else:
|
else:
|
||||||
data = await page.screenshot(type='jpeg', encoding='base64')
|
data = await page.screenshot(type='jpeg', encoding='base64')
|
||||||
|
self._inter_log('screenshot')
|
||||||
await page.close()
|
await page.close()
|
||||||
await browser.close()
|
self._inter_log('close page')
|
||||||
|
await self.browser.close()
|
||||||
|
self._inter_log('close browser')
|
||||||
return str(data)
|
return str(data)
|
||||||
|
|
||||||
async def text_to_pic(self, text: str) -> str:
|
async def text_to_pic(self, text: str) -> Optional[str]:
|
||||||
lines = text.split('\n')
|
lines = text.split('\n')
|
||||||
parsed_lines = list(map(lambda x: '<p>{}</p>'.format(escape(x)), lines))
|
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))
|
html_text = '<div style="width:17em;padding:1em">{}</div>'.format(''.join(parsed_lines))
|
||||||
@ -66,9 +94,12 @@ class Render(metaclass=Singleton):
|
|||||||
async def text_to_pic_cqcode(self, text:str) -> str:
|
async def text_to_pic_cqcode(self, text:str) -> str:
|
||||||
data = await self.text_to_pic(text)
|
data = await self.text_to_pic(text)
|
||||||
# logger.debug('file size: {}'.format(len(data)))
|
# logger.debug('file size: {}'.format(len(data)))
|
||||||
code = '[CQ:image,file=base64://{}]'.format(data)
|
if data:
|
||||||
# logger.debug(code)
|
code = '[CQ:image,file=base64://{}]'.format(data)
|
||||||
return code
|
# logger.debug(code)
|
||||||
|
return code
|
||||||
|
else:
|
||||||
|
return '生成图片错误'
|
||||||
|
|
||||||
async def parse_text(text: str) -> str:
|
async def parse_text(text: str) -> str:
|
||||||
'return raw text if don\'t use pic, otherwise return rendered opcode'
|
'return raw text if don\'t use pic, otherwise return rendered opcode'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user