mirror of
https://github.com/suyiiyii/nonebot-bison.git
synced 2025-06-05 19:36:43 +08:00
update browser
This commit is contained in:
parent
9270f01843
commit
10a2fbfa27
@ -29,6 +29,9 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
docker:
|
docker:
|
||||||
- image: cimg/python:3.9
|
- image: cimg/python:3.9
|
||||||
|
- image: browserless/chrome
|
||||||
|
environment:
|
||||||
|
HK_REPORTER_BROWSER: ws://localhost:3000
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
# - run: sed -e '41,45d' -i pyproject.toml
|
# - run: sed -e '41,45d' -i pyproject.toml
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
- 增加了简单的单元测试
|
- 增加了简单的单元测试
|
||||||
- 增加了管理员直接管理订阅的能力
|
- 增加了管理员直接管理订阅的能力
|
||||||
|
|
||||||
## [0.2.12] - 2021-06-24
|
## [0.3.0] - 2021-06-24
|
||||||
- 微博tag支持
|
- 微博tag支持
|
||||||
- 修复bug
|
- 修复bug
|
||||||
- 增加微博超话和纯文字支持
|
- 增加微博超话和纯文字支持
|
||||||
|
- 更改浏览器配置
|
||||||
|
@ -50,7 +50,11 @@ go-cqhttp镜像可使用`felinae98/go-cqhttp-ffmpeg`(数据目录为`/data`)
|
|||||||
### 配置变量
|
### 配置变量
|
||||||
* `HK_REPORTER_CONFIG_PATH` (str) 配置文件保存目录,如果不设置,则为当前目录下的`data`文件夹
|
* `HK_REPORTER_CONFIG_PATH` (str) 配置文件保存目录,如果不设置,则为当前目录下的`data`文件夹
|
||||||
* `HK_REPORTER_USE_PIC` (bool) 以图片形式发送文字(推荐在帐号被风控时使用)
|
* `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:<chromium path>`
|
||||||
|
* 使用browserless提供的服务浏览器管理服务(推荐):设置为`ws://********`
|
||||||
|
|
||||||
同时,建议配置`SUPERUSERS`环境变量便于机器人管理
|
同时,建议配置`SUPERUSERS`环境变量便于机器人管理
|
||||||
|
|
||||||
|
@ -48,5 +48,6 @@ default = true
|
|||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
markers = [
|
markers = [
|
||||||
"compare: compare fetching result with rsshub"
|
"compare: compare fetching result with rsshub",
|
||||||
|
"render: render img by chrome"
|
||||||
]
|
]
|
||||||
|
@ -7,3 +7,4 @@ from . import send
|
|||||||
from . import post
|
from . import post
|
||||||
from . import platform
|
from . import platform
|
||||||
from . import types
|
from . import types
|
||||||
|
from . import utils
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
from pydantic import BaseSettings
|
from pydantic import BaseSettings
|
||||||
|
|
||||||
|
import warnings
|
||||||
import nonebot
|
import nonebot
|
||||||
|
|
||||||
class PlugConfig(BaseSettings):
|
class PlugConfig(BaseSettings):
|
||||||
@ -6,6 +8,7 @@ class PlugConfig(BaseSettings):
|
|||||||
hk_reporter_config_path: str = ""
|
hk_reporter_config_path: str = ""
|
||||||
hk_reporter_use_pic: bool = False
|
hk_reporter_use_pic: bool = False
|
||||||
hk_reporter_use_local: bool = False
|
hk_reporter_use_local: bool = False
|
||||||
|
hk_reporter_browser: str = ''
|
||||||
hk_reporter_init_filter: bool = True
|
hk_reporter_init_filter: bool = True
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
@ -13,3 +16,5 @@ class PlugConfig(BaseSettings):
|
|||||||
|
|
||||||
global_config = nonebot.get_driver().config
|
global_config = nonebot.get_driver().config
|
||||||
plugin_config = PlugConfig(**global_config.dict())
|
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')
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from html import escape
|
from html import escape
|
||||||
import os
|
|
||||||
from tempfile import NamedTemporaryFile
|
|
||||||
from typing import Awaitable, Callable, Optional
|
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 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
|
from .plugin_config import plugin_config
|
||||||
|
|
||||||
@ -19,9 +17,6 @@ class Singleton(type):
|
|||||||
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
|
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
|
||||||
return cls._instances[cls]
|
return cls._instances[cls]
|
||||||
|
|
||||||
if not plugin_config.hk_reporter_use_local and not check_chromium():
|
|
||||||
|
|
||||||
download_chromium()
|
|
||||||
|
|
||||||
class Render(metaclass=Singleton):
|
class Render(metaclass=Singleton):
|
||||||
|
|
||||||
@ -29,6 +24,24 @@ class Render(metaclass=Singleton):
|
|||||||
self.lock = asyncio.Lock()
|
self.lock = asyncio.Lock()
|
||||||
self.browser: Browser
|
self.browser: Browser
|
||||||
self.interval_log = ''
|
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,
|
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[str]:
|
||||||
@ -51,10 +64,7 @@ class Render(metaclass=Singleton):
|
|||||||
async def do_render(self, url: str, viewport: Optional[dict] = None, target: Optional[str] = None,
|
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:
|
self.browser = await self.get_browser()
|
||||||
self.browser = await launch(executablePath='/usr/bin/chromium', args=['--no-sandbox'])
|
|
||||||
else:
|
|
||||||
self.browser = await launch(args=['--no-sandbox'])
|
|
||||||
self._inter_log('open browser')
|
self._inter_log('open browser')
|
||||||
page = await self.browser.newPage()
|
page = await self.browser.newPage()
|
||||||
if operation:
|
if operation:
|
||||||
@ -73,7 +83,7 @@ class Render(metaclass=Singleton):
|
|||||||
self._inter_log('screenshot')
|
self._inter_log('screenshot')
|
||||||
await page.close()
|
await page.close()
|
||||||
self._inter_log('close page')
|
self._inter_log('close page')
|
||||||
await self.browser.close()
|
await self.close_browser()
|
||||||
self._inter_log('close browser')
|
self._inter_log('close browser')
|
||||||
return str(data)
|
return str(data)
|
||||||
|
|
||||||
@ -81,11 +91,8 @@ class Render(metaclass=Singleton):
|
|||||||
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))
|
||||||
with NamedTemporaryFile('wt', suffix='.html', delete=False) as tmp:
|
url = 'data:text/html,{}'.format(quote(html_text))
|
||||||
tmp_path = tmp.name
|
data = await self.render(url, target='div')
|
||||||
tmp.write(html_text)
|
|
||||||
data = await self.render('file://{}'.format(tmp_path), target='div')
|
|
||||||
os.remove(tmp_path)
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
async def text_to_pic_cqcode(self, text:str) -> str:
|
async def text_to_pic_cqcode(self, text:str) -> str:
|
||||||
|
14
tests/test_render.py
Normal file
14
tests/test_render.py
Normal file
@ -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)
|
Loading…
x
Reference in New Issue
Block a user