From 905476f9d5ceeca4340460682083147be1470789 Mon Sep 17 00:00:00 2001 From: felinae98 <731499577@qq.com> Date: Sun, 22 May 2022 21:38:18 +0800 Subject: [PATCH 1/4] add http_client --- src/plugins/nonebot_bison/platform/arknights.py | 14 +++++++------- src/plugins/nonebot_bison/platform/bilibili.py | 7 +++---- src/plugins/nonebot_bison/platform/ff14.py | 5 ++--- src/plugins/nonebot_bison/platform/ncm_artist.py | 7 +++---- src/plugins/nonebot_bison/platform/ncm_radio.py | 7 +++---- src/plugins/nonebot_bison/platform/rss.py | 6 +++--- src/plugins/nonebot_bison/platform/weibo.py | 8 ++++---- src/plugins/nonebot_bison/plugin_config.py | 3 +++ src/plugins/nonebot_bison/post.py | 5 ++--- .../nonebot_bison/{utils.py => utils/__init__.py} | 5 ++++- src/plugins/nonebot_bison/utils/http.py | 12 ++++++++++++ 11 files changed, 46 insertions(+), 33 deletions(-) rename src/plugins/nonebot_bison/{utils.py => utils/__init__.py} (94%) create mode 100644 src/plugins/nonebot_bison/utils/http.py diff --git a/src/plugins/nonebot_bison/platform/arknights.py b/src/plugins/nonebot_bison/platform/arknights.py index 4a5c523..721a425 100644 --- a/src/plugins/nonebot_bison/platform/arknights.py +++ b/src/plugins/nonebot_bison/platform/arknights.py @@ -1,12 +1,12 @@ import json from typing import Any -import httpx from bs4 import BeautifulSoup as bs from nonebot.plugin import require from ..post import Post from ..types import Category, RawPost, Target +from ..utils import http_client from .platform import CategoryNotSupport, NewMessage, StatusChange @@ -26,7 +26,7 @@ class Arknights(NewMessage): return "明日方舟游戏信息" async def get_sub_list(self, _) -> list[RawPost]: - async with httpx.AsyncClient() as client: + async with http_client() as client: raw_data = await client.get( "https://ak-conf.hypergryph.com/config/prod/announce_meta/IOS/announcement.meta.json" ) @@ -44,7 +44,7 @@ class Arknights(NewMessage): async def parse(self, raw_post: RawPost) -> Post: announce_url = raw_post["webUrl"] text = "" - async with httpx.AsyncClient() as client: + async with http_client() as client: raw_html = await client.get(announce_url) soup = bs(raw_html.text, "html.parser") pics = [] @@ -99,7 +99,7 @@ class AkVersion(StatusChange): return "明日方舟游戏信息" async def get_status(self, _): - async with httpx.AsyncClient() as client: + async with http_client() as client: res_ver = await client.get( "https://ak-conf.hypergryph.com/config/prod/official/IOS/version" ) @@ -155,7 +155,7 @@ class MonsterSiren(NewMessage): return "明日方舟游戏信息" async def get_sub_list(self, _) -> list[RawPost]: - async with httpx.AsyncClient() as client: + async with http_client() as client: raw_data = await client.get("https://monster-siren.hypergryph.com/api/news") return raw_data.json()["data"]["list"] @@ -170,7 +170,7 @@ class MonsterSiren(NewMessage): async def parse(self, raw_post: RawPost) -> Post: url = f'https://monster-siren.hypergryph.com/info/{raw_post["cid"]}' - async with httpx.AsyncClient() as client: + async with http_client() as client: res = await client.get( f'https://monster-siren.hypergryph.com/api/news/{raw_post["cid"]}' ) @@ -207,7 +207,7 @@ class TerraHistoricusComic(NewMessage): return "明日方舟游戏信息" async def get_sub_list(self, _) -> list[RawPost]: - async with httpx.AsyncClient() as client: + async with http_client() as client: raw_data = await client.get( "https://terra-historicus.hypergryph.com/api/recentUpdate" ) diff --git a/src/plugins/nonebot_bison/platform/bilibili.py b/src/plugins/nonebot_bison/platform/bilibili.py index ad21a8a..55fd9cd 100644 --- a/src/plugins/nonebot_bison/platform/bilibili.py +++ b/src/plugins/nonebot_bison/platform/bilibili.py @@ -1,10 +1,9 @@ import json from typing import Any, Optional -import httpx - from ..post import Post from ..types import Category, RawPost, Tag, Target +from ..utils import http_client from .platform import CategoryNotSupport, NewMessage @@ -28,7 +27,7 @@ class Bilibili(NewMessage): has_target = True async def get_target_name(self, target: Target) -> Optional[str]: - async with httpx.AsyncClient() as client: + async with http_client() as client: res = await client.get( "https://api.bilibili.com/x/space/acc/info", params={"mid": target} ) @@ -38,7 +37,7 @@ class Bilibili(NewMessage): return res_data["data"]["name"] async def get_sub_list(self, target: Target) -> list[RawPost]: - async with httpx.AsyncClient() as client: + async with http_client() as client: params = {"host_uid": target, "offset": 0, "need_top": 0} res = await client.get( "https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history", diff --git a/src/plugins/nonebot_bison/platform/ff14.py b/src/plugins/nonebot_bison/platform/ff14.py index 68be182..0cbc92e 100644 --- a/src/plugins/nonebot_bison/platform/ff14.py +++ b/src/plugins/nonebot_bison/platform/ff14.py @@ -1,9 +1,8 @@ from typing import Any -import httpx - from ..post import Post from ..types import RawPost, Target +from ..utils import http_client from .platform import NewMessage @@ -23,7 +22,7 @@ class FF14(NewMessage): return "最终幻想XIV官方公告" async def get_sub_list(self, _) -> list[RawPost]: - async with httpx.AsyncClient() as client: + async with http_client() as client: raw_data = await client.get( "https://ff.web.sdo.com/inc/newdata.ashx?url=List?gameCode=ff&category=5309,5310,5311,5312,5313&pageIndex=0&pageSize=5" ) diff --git a/src/plugins/nonebot_bison/platform/ncm_artist.py b/src/plugins/nonebot_bison/platform/ncm_artist.py index a30072f..3223a74 100644 --- a/src/plugins/nonebot_bison/platform/ncm_artist.py +++ b/src/plugins/nonebot_bison/platform/ncm_artist.py @@ -1,9 +1,8 @@ from typing import Any, Optional -import httpx - from ..post import Post from ..types import RawPost, Target +from ..utils import http_client from .platform import NewMessage @@ -20,7 +19,7 @@ class NcmArtist(NewMessage): has_target = True async def get_target_name(self, target: Target) -> Optional[str]: - async with httpx.AsyncClient() as client: + async with http_client() as client: res = await client.get( "https://music.163.com/api/artist/albums/{}".format(target), headers={"Referer": "https://music.163.com/"}, @@ -31,7 +30,7 @@ class NcmArtist(NewMessage): return res_data["artist"]["name"] async def get_sub_list(self, target: Target) -> list[RawPost]: - async with httpx.AsyncClient() as client: + async with http_client() as client: res = await client.get( "https://music.163.com/api/artist/albums/{}".format(target), headers={"Referer": "https://music.163.com/"}, diff --git a/src/plugins/nonebot_bison/platform/ncm_radio.py b/src/plugins/nonebot_bison/platform/ncm_radio.py index 20abb52..c43ba6d 100644 --- a/src/plugins/nonebot_bison/platform/ncm_radio.py +++ b/src/plugins/nonebot_bison/platform/ncm_radio.py @@ -1,9 +1,8 @@ from typing import Any, Optional -import httpx - from ..post import Post from ..types import RawPost, Target +from ..utils import http_client from .platform import NewMessage @@ -20,7 +19,7 @@ class NcmRadio(NewMessage): has_target = True async def get_target_name(self, target: Target) -> Optional[str]: - async with httpx.AsyncClient() as client: + async with http_client() as client: res = await client.post( "http://music.163.com/api/dj/program/byradio", headers={"Referer": "https://music.163.com/"}, @@ -32,7 +31,7 @@ class NcmRadio(NewMessage): return res_data["programs"][0]["radio"]["name"] async def get_sub_list(self, target: Target) -> list[RawPost]: - async with httpx.AsyncClient() as client: + async with http_client() as client: res = await client.post( "http://music.163.com/api/dj/program/byradio", headers={"Referer": "https://music.163.com/"}, diff --git a/src/plugins/nonebot_bison/platform/rss.py b/src/plugins/nonebot_bison/platform/rss.py index 330d93d..ed09e8a 100644 --- a/src/plugins/nonebot_bison/platform/rss.py +++ b/src/plugins/nonebot_bison/platform/rss.py @@ -2,11 +2,11 @@ import calendar from typing import Any, Optional import feedparser -import httpx from bs4 import BeautifulSoup as bs from ..post import Post from ..types import RawPost, Target +from ..utils import http_client from .platform import NewMessage @@ -23,7 +23,7 @@ class Rss(NewMessage): has_target = True async def get_target_name(self, target: Target) -> Optional[str]: - async with httpx.AsyncClient() as client: + async with http_client() as client: res = await client.get(target, timeout=10.0) feed = feedparser.parse(res.text) return feed["feed"]["title"] @@ -35,7 +35,7 @@ class Rss(NewMessage): return post.id async def get_sub_list(self, target: Target) -> list[RawPost]: - async with httpx.AsyncClient() as client: + async with http_client() as client: res = await client.get(target, timeout=10.0) feed = feedparser.parse(res) entries = feed.entries diff --git a/src/plugins/nonebot_bison/platform/weibo.py b/src/plugins/nonebot_bison/platform/weibo.py index 38cd68d..a26921f 100644 --- a/src/plugins/nonebot_bison/platform/weibo.py +++ b/src/plugins/nonebot_bison/platform/weibo.py @@ -3,12 +3,12 @@ import re from datetime import datetime from typing import Any, Optional -import httpx from bs4 import BeautifulSoup as bs from nonebot.log import logger from ..post import Post from ..types import * +from ..utils import http_client from .platform import NewMessage @@ -30,7 +30,7 @@ class Weibo(NewMessage): has_target = True async def get_target_name(self, target: Target) -> Optional[str]: - async with httpx.AsyncClient() as client: + async with http_client() as client: param = {"containerid": "100505" + target} res = await client.get( "https://m.weibo.cn/api/container/getIndex", params=param @@ -42,7 +42,7 @@ class Weibo(NewMessage): return None async def get_sub_list(self, target: Target) -> list[RawPost]: - async with httpx.AsyncClient() as client: + async with http_client() as client: params = {"containerid": "107603" + target} res = await client.get( "https://m.weibo.cn/api/container/getIndex?", params=params, timeout=4.0 @@ -128,7 +128,7 @@ class Weibo(NewMessage): retweeted = True pic_num = info["retweeted_status"]["pic_num"] if retweeted else info["pic_num"] if info["isLongText"] or pic_num > 9: - async with httpx.AsyncClient() as client: + async with http_client() as client: res = await client.get( "https://m.weibo.cn/detail/{}".format(info["mid"]), headers=header ) diff --git a/src/plugins/nonebot_bison/plugin_config.py b/src/plugins/nonebot_bison/plugin_config.py index 10ded5f..d1db0a8 100644 --- a/src/plugins/nonebot_bison/plugin_config.py +++ b/src/plugins/nonebot_bison/plugin_config.py @@ -1,3 +1,5 @@ +from typing import Optional + import nonebot from pydantic import BaseSettings @@ -15,6 +17,7 @@ class PlugConfig(BaseSettings): bison_use_pic_merge: int = 0 # 多图片时启用图片合并转发(仅限群),当bison_use_queue为False时该配置不会生效 # 0:不启用;1:首条消息单独发送,剩余照片合并转发;2以及以上:所有消息全部合并转发 bison_resend_times: int = 0 + bison_proxy: Optional[str] class Config: extra = "ignore" diff --git a/src/plugins/nonebot_bison/post.py b/src/plugins/nonebot_bison/post.py index ceca521..869db75 100644 --- a/src/plugins/nonebot_bison/post.py +++ b/src/plugins/nonebot_bison/post.py @@ -3,13 +3,12 @@ from functools import reduce from io import BytesIO from typing import Optional, Union -import httpx from nonebot.adapters.onebot.v11.message import Message, MessageSegment from nonebot.log import logger from PIL import Image from .plugin_config import plugin_config -from .utils import parse_text +from .utils import http_client, parse_text @dataclass @@ -34,7 +33,7 @@ class Post: async def _pic_url_to_image(self, data: Union[str, bytes]) -> Image.Image: pic_buffer = BytesIO() if isinstance(data, str): - async with httpx.AsyncClient() as client: + async with http_client() as client: res = await client.get(data) pic_buffer.write(res.content) else: diff --git a/src/plugins/nonebot_bison/utils.py b/src/plugins/nonebot_bison/utils/__init__.py similarity index 94% rename from src/plugins/nonebot_bison/utils.py rename to src/plugins/nonebot_bison/utils/__init__.py index 8050d59..73c8baa 100644 --- a/src/plugins/nonebot_bison/utils.py +++ b/src/plugins/nonebot_bison/utils/__init__.py @@ -8,7 +8,10 @@ from nonebot.adapters.onebot.v11.message import MessageSegment from nonebot.log import default_format, logger from nonebot.plugin import require -from .plugin_config import plugin_config +from ..plugin_config import plugin_config +from .http import http_client + +__all__ = ["http_client", "Singleton", "parse_text", "html_to_text"] class Singleton(type): diff --git a/src/plugins/nonebot_bison/utils/http.py b/src/plugins/nonebot_bison/utils/http.py new file mode 100644 index 0000000..f46af30 --- /dev/null +++ b/src/plugins/nonebot_bison/utils/http.py @@ -0,0 +1,12 @@ +import functools + +import httpx + +from ..plugin_config import plugin_config + +if plugin_config.bison_proxy: + http_client = functools.partial( + httpx.AsyncClient, proxies=plugin_config.bison_proxy + ) +else: + http_client = httpx.AsyncClient From 0e5fb87994d8387ed86b3a6a65790bc5b992625d Mon Sep 17 00:00:00 2001 From: felinae98 <731499577@qq.com> Date: Sun, 22 May 2022 21:40:31 +0800 Subject: [PATCH 2/4] update doc --- docs/usage/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/usage/README.md b/docs/usage/README.md index 4caefa8..647da48 100644 --- a/docs/usage/README.md +++ b/docs/usage/README.md @@ -136,6 +136,8 @@ sidebar: auto 启用此功能时,可能会因为待推送图片过大/过多而导致文字消息与合并转发图片消息推送间隔过大(选择模式`1`时),请谨慎考虑开启。或者选择模式`2`,使图文消息一同合并转发(可能会使消息推送延迟过长) ::: +- `BISON_PROXY`: 使用的代理连接,形如`http://:`(可选) + ## 使用 ::: warning From 3c5d958c326a46c875510a2c6b2522baccfbc268 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 22 May 2022 13:46:57 +0000 Subject: [PATCH 3/4] auto fix by pre-commit hooks --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eba4dd8..d3f0fb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 最近更新 -* No changes +- No changes ## v0.5.3 From 081b14e06545f307f32002e5d1871e991b52a8a4 Mon Sep 17 00:00:00 2001 From: felinae98 <731499577@qq.com> Date: Sun, 22 May 2022 22:50:38 +0800 Subject: [PATCH 4/4] add proxy test --- tests/test_proxy.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/test_proxy.py diff --git a/tests/test_proxy.py b/tests/test_proxy.py new file mode 100644 index 0000000..ec4a22e --- /dev/null +++ b/tests/test_proxy.py @@ -0,0 +1,20 @@ +import pytest +from nonebug import App +from nonebug.fixture import nonebug_init + + +async def test_without_proxy(app: App): + from nonebot_bison.utils import http_client + + c = http_client() + assert not c._mounts + + +@pytest.mark.parametrize( + "nonebug_init", [{"bison_proxy": "http://example.com"}], indirect=True +) +async def test_with_proxy(app: App): + from nonebot_bison.utils import http_client + + c = http_client() + assert c._mounts