From 10a2fbfa276247d0ae6a529b8bbaccee74ab8478 Mon Sep 17 00:00:00 2001 From: felinae98 <731499577@qq.com> Date: Tue, 6 Jul 2021 20:01:34 +0800 Subject: [PATCH] update browser --- .circleci/config.yml | 3 ++ CHANGELOG.md | 3 +- README.md | 6 ++- pyproject.toml | 3 +- src/plugins/nonebot_hk_reporter/__init__.py | 1 + .../nonebot_hk_reporter/plugin_config.py | 5 +++ src/plugins/nonebot_hk_reporter/utils.py | 45 +++++++++++-------- tests/test_render.py | 14 ++++++ 8 files changed, 58 insertions(+), 22 deletions(-) create mode 100644 tests/test_render.py diff --git a/.circleci/config.yml b/.circleci/config.yml index 1aa3473..27ab0b9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -29,6 +29,9 @@ jobs: test: docker: - image: cimg/python:3.9 + - image: browserless/chrome + environment: + HK_REPORTER_BROWSER: ws://localhost:3000 steps: - checkout # - run: sed -e '41,45d' -i pyproject.toml diff --git a/CHANGELOG.md b/CHANGELOG.md index 795ddc4..f8bbd29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ - 增加了简单的单元测试 - 增加了管理员直接管理订阅的能力 -## [0.2.12] - 2021-06-24 +## [0.3.0] - 2021-06-24 - 微博tag支持 - 修复bug - 增加微博超话和纯文字支持 +- 更改浏览器配置 diff --git a/README.md b/README.md index 153af69..0e25a6d 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,11 @@ go-cqhttp镜像可使用`felinae98/go-cqhttp-ffmpeg`(数据目录为`/data`) ### 配置变量 * `HK_REPORTER_CONFIG_PATH` (str) 配置文件保存目录,如果不设置,则为当前目录下的`data`文件夹 * `HK_REPORTER_USE_PIC` (bool) 以图片形式发送文字(推荐在帐号被风控时使用) -* `HK_REPORTER_USE_LOCAL` (bool) 使用本地chromium(文字转图片时需要),否则第一次启动会下载chromium +* ~~`HK_REPORTER_USE_LOCAL` (bool) 使用本地chromium(文字转图片时需要),否则第一次启动会下载chromium~~ +* `HK_REPORTER_BROWSER` (str) 明日方舟游戏公告和以以图片形式发送文字需要浏览器支持,如果不设置会在使用到 + 功能的时候自动下载Chromium(不推荐) + * 使用本地安装的Chromiun: 设置为`local:` + * 使用browserless提供的服务浏览器管理服务(推荐):设置为`ws://********` 同时,建议配置`SUPERUSERS`环境变量便于机器人管理 diff --git a/pyproject.toml b/pyproject.toml index 647cc09..bf3890e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,5 +48,6 @@ default = true [tool.pytest.ini_options] markers = [ - "compare: compare fetching result with rsshub" + "compare: compare fetching result with rsshub", + "render: render img by chrome" ] diff --git a/src/plugins/nonebot_hk_reporter/__init__.py b/src/plugins/nonebot_hk_reporter/__init__.py index 0d32056..b97f0b9 100644 --- a/src/plugins/nonebot_hk_reporter/__init__.py +++ b/src/plugins/nonebot_hk_reporter/__init__.py @@ -7,3 +7,4 @@ from . import send from . import post from . import platform from . import types +from . import utils diff --git a/src/plugins/nonebot_hk_reporter/plugin_config.py b/src/plugins/nonebot_hk_reporter/plugin_config.py index ca9749c..03a5bdb 100644 --- a/src/plugins/nonebot_hk_reporter/plugin_config.py +++ b/src/plugins/nonebot_hk_reporter/plugin_config.py @@ -1,4 +1,6 @@ from pydantic import BaseSettings + +import warnings import nonebot class PlugConfig(BaseSettings): @@ -6,6 +8,7 @@ class PlugConfig(BaseSettings): hk_reporter_config_path: str = "" hk_reporter_use_pic: bool = False hk_reporter_use_local: bool = False + hk_reporter_browser: str = '' hk_reporter_init_filter: bool = True class Config: @@ -13,3 +16,5 @@ class PlugConfig(BaseSettings): global_config = nonebot.get_driver().config plugin_config = PlugConfig(**global_config.dict()) +if plugin_config.hk_reporter_use_local: + warnings.warn('HK_REPORTER_USE_LOCAL is deprecated, please use HK_REPORTER_BROWSER') diff --git a/src/plugins/nonebot_hk_reporter/utils.py b/src/plugins/nonebot_hk_reporter/utils.py index 93e6d0b..7e0e475 100644 --- a/src/plugins/nonebot_hk_reporter/utils.py +++ b/src/plugins/nonebot_hk_reporter/utils.py @@ -1,14 +1,12 @@ import asyncio from html import escape -import os -from tempfile import NamedTemporaryFile from typing import Awaitable, Callable, Optional +from urllib.parse import quote -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 pyppeteer import connect, launch +from pyppeteer.browser import Browser +from pyppeteer.page import Page from .plugin_config import plugin_config @@ -19,9 +17,6 @@ class Singleton(type): cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) return cls._instances[cls] -if not plugin_config.hk_reporter_use_local and not check_chromium(): - - download_chromium() class Render(metaclass=Singleton): @@ -29,6 +24,24 @@ class Render(metaclass=Singleton): self.lock = asyncio.Lock() self.browser: Browser self.interval_log = '' + self.remote_browser = False + + async def get_browser(self) -> Browser: + if plugin_config.hk_reporter_browser: + if plugin_config.hk_reporter_browser.startswith('local:'): + path = plugin_config.hk_reporter_browser.split('local:', 1)[1] + return await launch(executablePath=path, args=['--no-sandbox']) + if plugin_config.hk_reporter_browser.startswith('ws:'): + self.remote_browser = True + return await connect(browserWSEndpoint=plugin_config.hk_reporter_browser) + raise RuntimeError('HK_REPORTER_BROWSER error') + if plugin_config.hk_reporter_use_local: + return await launch(executablePath='/usr/bin/chromium', args=['--no-sandbox']) + return await launch(args=['--no-sandbox']) + + async def close_browser(self): + if not self.remote_browser: + 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]: @@ -51,10 +64,7 @@ class Render(metaclass=Singleton): 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: - self.browser = await launch(executablePath='/usr/bin/chromium', args=['--no-sandbox']) - else: - self.browser = await launch(args=['--no-sandbox']) + self.browser = await self.get_browser() self._inter_log('open browser') page = await self.browser.newPage() if operation: @@ -73,7 +83,7 @@ class Render(metaclass=Singleton): self._inter_log('screenshot') await page.close() self._inter_log('close page') - await self.browser.close() + await self.close_browser() self._inter_log('close browser') return str(data) @@ -81,11 +91,8 @@ class Render(metaclass=Singleton): lines = text.split('\n') parsed_lines = list(map(lambda x: '

{}

'.format(escape(x)), lines)) html_text = '
{}
'.format(''.join(parsed_lines)) - with NamedTemporaryFile('wt', suffix='.html', delete=False) as tmp: - tmp_path = tmp.name - tmp.write(html_text) - data = await self.render('file://{}'.format(tmp_path), target='div') - os.remove(tmp_path) + url = 'data:text/html,{}'.format(quote(html_text)) + data = await self.render(url, target='div') return data async def text_to_pic_cqcode(self, text:str) -> str: diff --git a/tests/test_render.py b/tests/test_render.py new file mode 100644 index 0000000..f61ca19 --- /dev/null +++ b/tests/test_render.py @@ -0,0 +1,14 @@ +import pytest +import typing + +if typing.TYPE_CHECKING: + import sys + sys.path.append('./src/plugins') + import nonebot_hk_reporter + +@pytest.mark.asyncio +@pytest.mark.render +async def test_render(plugin_module: 'nonebot_hk_reporter'): + render = plugin_module.utils.Render() + res = await render.text_to_pic('a\nbbbbbbbbbbbbbbbbbbbbbb\ncd') + print(res)