use screen shot

This commit is contained in:
felinae98 2021-02-08 00:25:14 +08:00
parent 80b49ae886
commit d21305e5f4
No known key found for this signature in database
GPG Key ID: 00C8B010587FF610
10 changed files with 288 additions and 201 deletions

View File

@ -1,4 +1,5 @@
FROM python:3.9 FROM python:3.9
RUN apt-get update && apt-get install chromium fonts-wqy-microhei
RUN python3 -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple RUN python3 -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple
RUN python3 -m pip install poetry && poetry config virtualenvs.create false RUN python3 -m pip install poetry && poetry config virtualenvs.create false
WORKDIR /app WORKDIR /app

413
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,7 @@ bs4 = "^0.0.1"
tinydb = "^4.3.0" tinydb = "^4.3.0"
nonebot_plugin_apscheduler = "^0.1.2" nonebot_plugin_apscheduler = "^0.1.2"
feedparser = "^6.0.2" feedparser = "^6.0.2"
pyppeteer = "^0.2.5"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
pylint = "^2.6.0" pylint = "^2.6.0"

View File

@ -23,8 +23,7 @@ class NoSuchUserException(Exception):
class NoSuchSubscribeException(Exception): class NoSuchSubscribeException(Exception):
pass pass
@Singleton class Config(metaclass=Singleton):
class Config():
migrate_version = 1 migrate_version = 1

View File

@ -7,6 +7,7 @@ from nonebot import on_command
from .platform.utils import check_sub_target from .platform.utils import check_sub_target
from .config import Config, NoSuchSubscribeException from .config import Config, NoSuchSubscribeException
from .utils import parse_text
async def check_is_owner_or_admin(bot: Bot, event: Event): async def check_is_owner_or_admin(bot: Bot, event: Event):
return await (GROUP_ADMIN | GROUP_OWNER)(bot, event) return await (GROUP_ADMIN | GROUP_OWNER)(bot, event)
@ -36,7 +37,7 @@ async def _(bot: Bot, event: Event, state: T_State):
res = '订阅的帐号为:\n' res = '订阅的帐号为:\n'
for sub in sub_list: for sub in sub_list:
res += '{} {} {}\n'.format(sub['target_type'], sub['target_name'], sub['target']) res += '{} {} {}\n'.format(sub['target_type'], sub['target_name'], sub['target'])
await query_sub.finish(res) await query_sub.finish(await parse_text(res))
del_sub = on_command("删除订阅", rule=to_me(), priority=5) del_sub = on_command("删除订阅", rule=to_me(), priority=5)
@del_sub.handle() @del_sub.handle()

View File

@ -6,8 +6,7 @@ import httpx
import json import json
import time import time
@Singleton class Bilibili(metaclass=Singleton):
class Bilibili:
def __init__(self): def __init__(self):
self.exists_posts = defaultdict(set) self.exists_posts = defaultdict(set)

View File

@ -18,8 +18,7 @@ async def get_rss_info(url) -> str:
feed = feedparser.parse(data) feed = feedparser.parse(data)
return feed.feed.title return feed.feed.title
@Singleton class Rss(metaclass=Singleton):
class Rss:
def __init__(self): def __init__(self):
self.exists_posts = defaultdict(set) self.exists_posts = defaultdict(set)

View File

@ -9,8 +9,7 @@ from nonebot import logger
from ..utils import Singleton from ..utils import Singleton
from ..post import Post from ..post import Post
@Singleton class Weibo(metaclass=Singleton):
class Weibo:
def __init__(self): def __init__(self):
self.exists_posts = defaultdict(set) self.exists_posts = defaultdict(set)

View File

@ -3,6 +3,7 @@ from pydantic import BaseSettings
class PlugConfig(BaseSettings): class PlugConfig(BaseSettings):
hk_reporter_config_path: str = "" hk_reporter_config_path: str = ""
use_pic: bool = False
class Config: class Config:
extra = 'ignore' extra = 'ignore'

View File

@ -1,12 +1,54 @@
class Singleton(object): import nonebot
from pyppeteer import launch
from html import escape
from hashlib import sha256
def __init__(self, cls): from . import plugin_config
self._cls = cls
self._instance = {} class Singleton(type):
def __call__(self): _instances = {}
if self._cls not in self._instance: def __call__(cls, *args, **kwargs):
self._instance[self._cls] = self._cls() if cls not in cls._instances:
return self._instance[self._cls] cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
supported_target_type = ('weibo', 'bilibili', 'rss') supported_target_type = ('weibo', 'bilibili', 'rss')
class Render(metaclass=Singleton):
def __init__(self):
self.page = None
async def init(self):
browser = await launch(execublePath='/usr/bin/chromium')
self.page = await browser.newPage()
async def text_to_pic(self, text: str) -> str:
hash_text = sha256(text.encode()).hexdigest()[:20]
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))
with open('/tmp/text-{}.html'.format(hash_text), 'w') as f:
f.write(html_text)
await self.page.goto('file:///tmp/text-{}.html'.format(hash_text))
div = await self.page.querySelector('div')
path = '/tmp/img-{}.png'.format(hash_text)
await div.screenshot(path=path)
return path
async def text_to_pic_cqcode(self, text:str) -> str:
path = await self.text_to_pic(text)
return '[CQ:image,file=file://{}]'.format(path)
async def _start():
r = Render()
await r.init()
nonebot.get_driver().on_startup(_start)
async def parse_text(text: str):
if plugin_config.use_pic:
r = Render()
return await r.text_to_pic_cqcode(text)
else:
return text