add retry for render

This commit is contained in:
felinae98 2021-04-29 18:39:36 +08:00
parent 6947079dbf
commit 254e39f615
No known key found for this signature in database
GPG Key ID: 00C8B010587FF610

View File

@ -2,11 +2,14 @@ import asyncio
from html import escape
import os
from tempfile import NamedTemporaryFile
from time import asctime
from typing import Awaitable, Callable, Optional
from pyppeteer import launch
from pyppeteer.browser import Browser
from pyppeteer.chromium_downloader import check_chromium, download_chromium
from pyppeteer.page import Page
from nonebot.log import logger
from .plugin_config import plugin_config
@ -28,31 +31,56 @@ class Render(metaclass=Singleton):
def __init__(self):
self.lock = asyncio.Lock()
self.browser: Browser
self.interval_log = ''
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:
async with self.lock:
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:
browser = await launch(args=['--no-sandbox'])
page = await browser.newPage()
self.browser = await launch(args=['--no-sandbox'])
self._inter_log('open browser')
page = await self.browser.newPage()
if operation:
await operation(page)
else:
await page.goto(url)
self._inter_log('open page')
if viewport:
await page.setViewport(viewport)
logger._inter_log('set viewport')
if target:
target_ele = await page.querySelector(target)
data = await target_ele.screenshot(type='jpeg', encoding='base64')
else:
data = await page.screenshot(type='jpeg', encoding='base64')
self._inter_log('screenshot')
await page.close()
await browser.close()
self._inter_log('close page')
await self.browser.close()
self._inter_log('close browser')
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')
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))
@ -66,9 +94,12 @@ class Render(metaclass=Singleton):
async def text_to_pic_cqcode(self, text:str) -> str:
data = await self.text_to_pic(text)
# logger.debug('file size: {}'.format(len(data)))
code = '[CQ:image,file=base64://{}]'.format(data)
# logger.debug(code)
return code
if data:
code = '[CQ:image,file=base64://{}]'.format(data)
# logger.debug(code)
return code
else:
return '生成图片错误'
async def parse_text(text: str) -> str:
'return raw text if don\'t use pic, otherwise return rendered opcode'