mirror of
https://github.com/suyiiyii/nonebot-bison.git
synced 2025-07-14 12:03:00 +08:00
Merge branch 'main' into arknights
This commit is contained in:
commit
bd078e233d
@ -30,6 +30,7 @@
|
||||
## 使用方法
|
||||
|
||||
### 使用以及部署
|
||||
**!!本项目需要Python3.9及以上**
|
||||
本项目可作为单独插件使用,仅包含订阅相关功能(绝对simple和stupid),也可直接克隆项目进行使用(包含自动同意superuser,自动接受入群邀请等功能)
|
||||
作为插件使用请安装`nonebot-hk-reporter`包,并在`bot.py`中加载`nonebot_hk_reporter`插件;或直接克隆本项目进行使用
|
||||
配置与安装请参考[nonebot2文档](https://v2.nonebot.dev/)
|
||||
@ -77,6 +78,12 @@ go-cqhttp镜像可使用`felinae98/go-cqhttp-ffmpeg`(数据目录为`/data`)
|
||||
* 通过图片发送文本,防止风控
|
||||
* 使用队列限制发送频率
|
||||
|
||||
# FAQ
|
||||
1. 报错`TypeError: 'type' object is not subscriptable`
|
||||
本项目使用了Python 3.9的语法,请将Python版本升级到3.9及以上,推荐使用docker部署
|
||||
2. bot不理我
|
||||
请确认自己是群主或者管理员,并且检查`COMMAND_START`环境变量是否设为`[""]`
|
||||
|
||||
## 鸣谢
|
||||
* [`go-cqhttp`](https://github.com/Mrs4s/go-cqhttp):简单又完善的 cqhttp 实现
|
||||
* [`NoneBot2`](https://github.com/nonebot/nonebot2):超好用的开发框架
|
||||
|
@ -1,6 +1,7 @@
|
||||
from .bilibili import Bilibili
|
||||
from .rss import Rss
|
||||
from .weibo import Weibo
|
||||
from .wechat import Wechat
|
||||
from .utils import check_sub_target
|
||||
from .platform import PlatformNoTarget
|
||||
from .utils import platform_manager
|
||||
|
@ -6,6 +6,7 @@ from .arkninghts import Arknights
|
||||
from .weibo import Weibo
|
||||
from .bilibili import Bilibili
|
||||
from .rss import Rss
|
||||
from .wechat import Wechat
|
||||
from .platform import PlatformProto
|
||||
from ..config import Config
|
||||
from ..post import Post
|
||||
@ -19,6 +20,7 @@ platform_manager: dict[str, PlatformProto] = {
|
||||
'weibo': Weibo(),
|
||||
'rss': Rss(),
|
||||
'arknights': Arknights()
|
||||
'wechat': Wechat(),
|
||||
}
|
||||
|
||||
async def fetch_and_send(target_type: str):
|
||||
|
75
src/plugins/nonebot_hk_reporter/platform/wechat.py
Normal file
75
src/plugins/nonebot_hk_reporter/platform/wechat.py
Normal file
@ -0,0 +1,75 @@
|
||||
from datetime import datetime
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
from typing import Any, Optional
|
||||
|
||||
from bs4 import BeautifulSoup as bs
|
||||
import httpx
|
||||
|
||||
from ..post import Post
|
||||
from ..types import *
|
||||
from .platform import Platform
|
||||
|
||||
|
||||
class Wechat(Platform):
|
||||
|
||||
categories = {}
|
||||
enable_tag = False
|
||||
platform_name = 'wechat'
|
||||
|
||||
@classmethod
|
||||
def _get_query_url(cls, target: Target):
|
||||
return 'https://weixin.sogou.com/weixin?type=1&s_from=input&query={}&ie=utf8&_sug_=n&_sug_type_='.format(target)
|
||||
|
||||
@classmethod
|
||||
async def _get_target_soup(cls, target: Target) -> Optional[bs]:
|
||||
target_url = cls._get_query_url(target)
|
||||
async with httpx.AsyncClient() as client:
|
||||
res = await client.get(target_url)
|
||||
soup = bs(res.text, 'html.parser')
|
||||
blocks = soup.find(class_='news-list2').find_all('li',recursive=False)
|
||||
for block in blocks:
|
||||
if block.find(string=[target]):
|
||||
return block
|
||||
|
||||
@classmethod
|
||||
async def get_account_name(cls, target: Target) -> Optional[str]:
|
||||
if not (block := await cls._get_target_soup(target)):
|
||||
return None
|
||||
return block.find('p', class_='tit').find('a').text
|
||||
|
||||
async def get_sub_list(self, target: Target) -> list[RawPost]:
|
||||
block = await self._get_target_soup(target)
|
||||
if (last_post_dt := block.find('dt', string='最近文章:')):
|
||||
post = {
|
||||
'title': last_post_dt.find_parent().find('a').text,
|
||||
'target': target,
|
||||
'page_url': self._get_query_url(target),
|
||||
'name': block.find('p', class_='tit').find('a').text
|
||||
}
|
||||
return [post]
|
||||
else:
|
||||
return []
|
||||
|
||||
def get_id(self, post: RawPost) -> Any:
|
||||
return post['title']
|
||||
|
||||
def get_date(self, post: RawPost):
|
||||
return None
|
||||
|
||||
def get_tags(self, post: RawPost):
|
||||
return None
|
||||
|
||||
def get_category(self, post: RawPost):
|
||||
return None
|
||||
|
||||
async def parse(self, raw_post: RawPost) -> Post:
|
||||
# TODO get content of post
|
||||
return Post(target_type='wechat',
|
||||
text='{}\n详细内容请自行查看公众号'.format(raw_post['title']),
|
||||
target_name=raw_post['name'],
|
||||
pics=[],
|
||||
url=''
|
||||
)
|
||||
|
@ -22,6 +22,10 @@ async def rss_check():
|
||||
async def arknights_check():
|
||||
await fetch_and_send('arknights')
|
||||
|
||||
@scheduler.scheduled_job('interval', seconds=30)
|
||||
async def wechat_check():
|
||||
await fetch_and_send('wechat')
|
||||
|
||||
@scheduler.scheduled_job('interval', seconds=1)
|
||||
async def _():
|
||||
await do_send_msgs()
|
||||
|
@ -1,10 +1,11 @@
|
||||
import os
|
||||
import asyncio
|
||||
from typing import Optional
|
||||
from typing import Awaitable, Callable, Optional
|
||||
import nonebot
|
||||
from nonebot import logger
|
||||
import base64
|
||||
from pyppeteer import launch
|
||||
from pyppeteer.page import Page
|
||||
from pyppeteer.chromium_downloader import check_chromium, download_chromium
|
||||
from html import escape
|
||||
from hashlib import sha256
|
||||
@ -19,7 +20,7 @@ class Singleton(type):
|
||||
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
|
||||
return cls._instances[cls]
|
||||
|
||||
supported_target_type = ('weibo', 'bilibili', 'rss', 'arknights')
|
||||
supported_target_type = ('weibo', 'bilibili', 'rss', 'arknights', 'wechat')
|
||||
|
||||
if not plugin_config.hk_reporter_use_local and not check_chromium():
|
||||
os.environ['PYPPETEER_DOWNLOAD_HOST'] = 'http://npm.taobao.org/mirrors'
|
||||
@ -30,14 +31,18 @@ class Render(metaclass=Singleton):
|
||||
def __init__(self):
|
||||
self.lock = asyncio.Lock()
|
||||
|
||||
async def render(self, url: str, viewport: Optional[dict] = None, target: Optional[str] = None) -> str:
|
||||
async def 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'])
|
||||
else:
|
||||
browser = await launch(args=['--no-sandbox'])
|
||||
page = await browser.newPage()
|
||||
await page.goto(url)
|
||||
if operation:
|
||||
await operation(page)
|
||||
else:
|
||||
await page.goto(url)
|
||||
if viewport:
|
||||
await page.setViewport(viewport)
|
||||
if target:
|
||||
|
Loading…
x
Reference in New Issue
Block a user