mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-15 14:22:55 +08:00
Merge branch 'main' into feature/refactor-base
This commit is contained in:
commit
c6de1cd779
@ -1 +1 @@
|
|||||||
__version__: v0.2.4-e363d29
|
__version__: v0.2.4-4291cda
|
||||||
|
|||||||
22
poetry.lock
generated
22
poetry.lock
generated
@ -2227,23 +2227,23 @@ reference = "aliyun"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nonebot-plugin-alconna"
|
name = "nonebot-plugin-alconna"
|
||||||
version = "0.53.1"
|
version = "0.54.1"
|
||||||
description = "Alconna Adapter for Nonebot"
|
description = "Alconna Adapter for Nonebot"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
files = [
|
files = [
|
||||||
{file = "nonebot_plugin_alconna-0.53.1-py3-none-any.whl", hash = "sha256:a7734d4c7f1b2fedec586b7d235da119ffaa23d0e17a8aa0a0acc0e76a1662d0"},
|
{file = "nonebot_plugin_alconna-0.54.1-py3-none-any.whl", hash = "sha256:4edb4b081cd64ce37717c7a92d31aadd2cf287a5a0adc2ac86ed82d9bcad5048"},
|
||||||
{file = "nonebot_plugin_alconna-0.53.1.tar.gz", hash = "sha256:dc9eef228bb819d05ce9816f8a5a1bead455ee85d1ea7d5e409f9fb11665805e"},
|
{file = "nonebot_plugin_alconna-0.54.1.tar.gz", hash = "sha256:66fae03120b8eff25bb0027d65f149e399aa6f73c7585ebdd388d1904cecdeee"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
arclet-alconna = ">=1.8.31,<2.0"
|
arclet-alconna = ">=1.8.35,<2.0"
|
||||||
arclet-alconna-tools = ">=0.7.10"
|
arclet-alconna-tools = ">=0.7.10"
|
||||||
importlib-metadata = ">=4.13.0"
|
importlib-metadata = ">=4.13.0"
|
||||||
nepattern = ">=0.7.4,<1.0"
|
nepattern = ">=0.7.7,<1.0"
|
||||||
nonebot-plugin-waiter = ">=0.6.0"
|
nonebot-plugin-waiter = ">=0.6.0"
|
||||||
nonebot2 = ">=2.3.0"
|
nonebot2 = ">=2.3.0"
|
||||||
tarina = ">=0.6.3,<0.7"
|
tarina = ">=0.6.8,<0.7"
|
||||||
|
|
||||||
[package.source]
|
[package.source]
|
||||||
type = "legacy"
|
type = "legacy"
|
||||||
@ -2420,13 +2420,13 @@ reference = "aliyun"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nonebug"
|
name = "nonebug"
|
||||||
version = "0.3.7"
|
version = "0.4.3"
|
||||||
description = "nonebot2 test framework"
|
description = "nonebot2 test framework"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8,<4.0"
|
python-versions = ">=3.9,<4.0"
|
||||||
files = [
|
files = [
|
||||||
{file = "nonebug-0.3.7-py3-none-any.whl", hash = "sha256:c39f462aafe20660602a8b789a575db6c9346ab5b6f1985eb9d98b861528299a"},
|
{file = "nonebug-0.4.3-py3-none-any.whl", hash = "sha256:eb9b2c8ab3d45459a4f00ebdaae90729e9e9628575c0685fca4c871dd4cfd425"},
|
||||||
{file = "nonebug-0.3.7.tar.gz", hash = "sha256:8a75183400681f34eafc7caa2bb6dd511c3b5660c59264f1c379a088c7ac2247"},
|
{file = "nonebug-0.4.3.tar.gz", hash = "sha256:e9592d2c7a42b76f4a336f98726cba92e1300f6bab155c8822e865919786f10c"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@ -4932,4 +4932,4 @@ reference = "aliyun"
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.10"
|
python-versions = "^3.10"
|
||||||
content-hash = "d2be32cc7ba17b302a015de327b8e8d815bee185400547f4024fd93e141d3ac8"
|
content-hash = "37341271bbd43fcb6af878cb09491459cf21b13c24659a5fd94f9c2b5248a5d8"
|
||||||
|
|||||||
@ -50,7 +50,7 @@ nonebot-plugin-uninfo = "^0.4.1"
|
|||||||
nonebot-plugin-alconna = "^0.54.0"
|
nonebot-plugin-alconna = "^0.54.0"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
nonebug = "^0.4.2"
|
nonebug = "^0.4"
|
||||||
pytest-cov = "^5.0.0"
|
pytest-cov = "^5.0.0"
|
||||||
pytest-mock = "^3.6.1"
|
pytest-mock = "^3.6.1"
|
||||||
pytest-asyncio = "^0.23.5"
|
pytest-asyncio = "^0.23.5"
|
||||||
@ -137,6 +137,7 @@ disableBytesTypePromotions = true
|
|||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
asyncio_mode = "auto"
|
asyncio_mode = "auto"
|
||||||
|
asyncio_default_fixture_loop_scope = "session"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core>=1.0.0"]
|
requires = ["poetry-core>=1.0.0"]
|
||||||
|
|||||||
@ -57,7 +57,7 @@ nonebot-adapter-discord==0.1.8 ; python_version >= "3.10" and python_version < "
|
|||||||
nonebot-adapter-dodo==0.1.4 ; python_version >= "3.10" and python_version < "4.0"
|
nonebot-adapter-dodo==0.1.4 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
nonebot-adapter-kaiheila==0.3.4 ; python_version >= "3.10" and python_version < "4.0"
|
nonebot-adapter-kaiheila==0.3.4 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
nonebot-adapter-onebot==2.4.6 ; python_version >= "3.10" and python_version < "4.0"
|
nonebot-adapter-onebot==2.4.6 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
nonebot-plugin-alconna==0.53.1 ; python_version >= "3.10" and python_version < "4.0"
|
nonebot-plugin-alconna==0.54.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
nonebot-plugin-apscheduler==0.3.0 ; python_version >= "3.10" and python_version < "4.0"
|
nonebot-plugin-apscheduler==0.3.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
nonebot-plugin-htmlrender==0.3.5 ; python_version >= "3.10" and python_version < "4.0"
|
nonebot-plugin-htmlrender==0.3.5 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
nonebot-plugin-session==0.2.3 ; python_version >= "3.10" and python_version < "4.0"
|
nonebot-plugin-session==0.2.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
|
|||||||
@ -8,6 +8,7 @@ from nonebug import NONEBOT_INIT_KWARGS
|
|||||||
from nonebug.app import App
|
from nonebug.app import App
|
||||||
from nonebug.mixin.process import MatcherContext
|
from nonebug.mixin.process import MatcherContext
|
||||||
import pytest
|
import pytest
|
||||||
|
from pytest_asyncio import is_async_test
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
from respx import MockRouter
|
from respx import MockRouter
|
||||||
|
|
||||||
@ -22,6 +23,13 @@ def get_response_json(path: str) -> dict:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def pytest_collection_modifyitems(items: list[pytest.Item]):
|
||||||
|
pytest_asyncio_tests = (item for item in items if is_async_test(item))
|
||||||
|
session_scope_marker = pytest.mark.asyncio(loop_scope="session")
|
||||||
|
for async_test in pytest_asyncio_tests:
|
||||||
|
async_test.add_marker(session_scope_marker, append=False)
|
||||||
|
|
||||||
|
|
||||||
def pytest_configure(config: pytest.Config) -> None:
|
def pytest_configure(config: pytest.Config) -> None:
|
||||||
config.stash[NONEBOT_INIT_KWARGS] = {
|
config.stash[NONEBOT_INIT_KWARGS] = {
|
||||||
"driver": "~fastapi+~httpx+~websockets",
|
"driver": "~fastapi+~httpx+~websockets",
|
||||||
|
|||||||
@ -2,7 +2,7 @@ from nonebot import on_notice
|
|||||||
from nonebot.adapters.onebot.v11 import PokeNotifyEvent
|
from nonebot.adapters.onebot.v11 import PokeNotifyEvent
|
||||||
from nonebot.permission import SUPERUSER
|
from nonebot.permission import SUPERUSER
|
||||||
from nonebot.plugin import PluginMetadata
|
from nonebot.plugin import PluginMetadata
|
||||||
from nonebot.rule import to_me
|
from nonebot.rule import Rule, to_me
|
||||||
from nonebot_plugin_alconna import Alconna, on_alconna
|
from nonebot_plugin_alconna import Alconna, on_alconna
|
||||||
from nonebot_plugin_htmlrender import template_to_pic
|
from nonebot_plugin_htmlrender import template_to_pic
|
||||||
|
|
||||||
@ -41,9 +41,32 @@ __plugin_meta__ = PluginMetadata(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def commandRule() -> Rule:
|
||||||
|
return Rule(lambda: Config.get_config("check", "type") in {"message", "mix"})
|
||||||
|
|
||||||
|
|
||||||
|
def noticeRule() -> Rule:
|
||||||
|
return Rule(lambda: Config.get_config("check", "type") in {"poke", "mix"})
|
||||||
|
|
||||||
|
|
||||||
|
_self_check_matcher = _self_check_matcher = on_alconna(
|
||||||
|
Alconna("自检"),
|
||||||
|
rule=to_me() & commandRule(),
|
||||||
|
permission=SUPERUSER,
|
||||||
|
block=True,
|
||||||
|
priority=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
_self_check_poke_matcher = on_notice(
|
||||||
|
priority=5,
|
||||||
|
permission=SUPERUSER,
|
||||||
|
block=False,
|
||||||
|
rule=notice_rule(PokeNotifyEvent) & to_me() & noticeRule(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def handle_self_check():
|
async def handle_self_check():
|
||||||
try:
|
try:
|
||||||
logger.info("触发自检")
|
|
||||||
data = await get_status_info()
|
data = await get_status_info()
|
||||||
image = await template_to_pic(
|
image = await template_to_pic(
|
||||||
template_path=str((TEMPLATE_PATH / "check").absolute()),
|
template_path=str((TEMPLATE_PATH / "check").absolute()),
|
||||||
@ -56,34 +79,17 @@ async def handle_self_check():
|
|||||||
wait=2,
|
wait=2,
|
||||||
)
|
)
|
||||||
await MessageUtils.build_message(image).send()
|
await MessageUtils.build_message(image).send()
|
||||||
logger.info("自检成功")
|
logger.info("自检成功", "自检")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await MessageUtils.build_message(f"自检失败: {e}").send()
|
await MessageUtils.build_message(f"自检失败: {e}").send()
|
||||||
logger.error("自检失败", e=e)
|
logger.error("自检失败", "自检", e=e)
|
||||||
|
|
||||||
|
|
||||||
check_type = Config.get_config("check", "type")
|
@_self_check_matcher.handle()
|
||||||
|
async def handle_message_check():
|
||||||
if check_type in {"message", "mix"}:
|
await handle_self_check()
|
||||||
# message
|
|
||||||
_self_check_matcher = on_alconna(
|
|
||||||
Alconna("自检"), rule=to_me(), permission=SUPERUSER, block=True, priority=1
|
|
||||||
)
|
|
||||||
|
|
||||||
@_self_check_matcher.handle()
|
|
||||||
async def handle_message_check():
|
|
||||||
await handle_self_check()
|
|
||||||
|
|
||||||
|
|
||||||
if check_type in {"poke", "mix"}:
|
@_self_check_poke_matcher.handle()
|
||||||
# poke
|
async def handle_poke_check():
|
||||||
_self_check_poke_matcher = on_notice(
|
await handle_self_check()
|
||||||
priority=5,
|
|
||||||
permission=SUPERUSER,
|
|
||||||
block=False,
|
|
||||||
rule=notice_rule(PokeNotifyEvent) & to_me(),
|
|
||||||
)
|
|
||||||
|
|
||||||
@_self_check_poke_matcher.handle()
|
|
||||||
async def handle_poke_check(event: PokeNotifyEvent):
|
|
||||||
await handle_self_check()
|
|
||||||
|
|||||||
@ -27,17 +27,18 @@ async def create_help_img(session: Uninfo, group_id: str | None):
|
|||||||
session: Uninfo
|
session: Uninfo
|
||||||
group_id: 群号
|
group_id: 群号
|
||||||
"""
|
"""
|
||||||
help_type: str = base_config.get("type")
|
help_type = base_config.get("type", "").strip().lower()
|
||||||
if help_type.lower() == "html":
|
|
||||||
result = BuildImage.open(await build_html_image(group_id))
|
match help_type:
|
||||||
elif help_type.lower() == "zhenxun":
|
case "html":
|
||||||
result = BuildImage.open(await build_zhenxun_image(session, group_id))
|
result = BuildImage.open(await build_html_image(group_id))
|
||||||
else:
|
case "zhenxun":
|
||||||
result = await build_normal_image(group_id)
|
result = BuildImage.open(await build_zhenxun_image(session, group_id))
|
||||||
if group_id:
|
case _:
|
||||||
await result.save(GROUP_HELP_PATH / f"{group_id}.png")
|
result = await build_normal_image(group_id)
|
||||||
else:
|
|
||||||
await result.save(SIMPLE_HELP_IMAGE)
|
save_path = GROUP_HELP_PATH / f"{group_id}.png" if group_id else SIMPLE_HELP_IMAGE
|
||||||
|
await result.save(save_path)
|
||||||
|
|
||||||
|
|
||||||
async def get_user_allow_help(user_id: str) -> list[PluginType]:
|
async def get_user_allow_help(user_id: str) -> list[PluginType]:
|
||||||
|
|||||||
@ -229,12 +229,15 @@ class ShopManage:
|
|||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
raise ValueError("所有API获取插件文件失败,请检查网络连接")
|
raise ValueError("所有API获取插件文件失败,请检查网络连接")
|
||||||
|
if module_path == ".":
|
||||||
|
module_path = ""
|
||||||
files = repo_api.get_files(
|
files = repo_api.get_files(
|
||||||
module_path=module_path.replace(".", "/") + ("" if is_dir else ".py"),
|
module_path=module_path.replace(".", "/") + ("" if is_dir else ".py"),
|
||||||
is_dir=is_dir,
|
is_dir=is_dir,
|
||||||
)
|
)
|
||||||
download_urls = [await repo_info.get_raw_download_urls(file) for file in files]
|
download_urls = [await repo_info.get_raw_download_urls(file) for file in files]
|
||||||
base_path = BASE_PATH / "plugins" if is_external else BASE_PATH
|
base_path = BASE_PATH / "plugins" if is_external else BASE_PATH
|
||||||
|
base_path = base_path if module_path else base_path / repo_info.repo
|
||||||
download_paths: list[Path | str] = [base_path / file for file in files]
|
download_paths: list[Path | str] = [base_path / file for file in files]
|
||||||
logger.debug(f"插件下载路径: {download_paths}", "插件管理")
|
logger.debug(f"插件下载路径: {download_paths}", "插件管理")
|
||||||
result = await AsyncHttpx.gather_download_file(download_urls, download_paths)
|
result = await AsyncHttpx.gather_download_file(download_urls, download_paths)
|
||||||
|
|||||||
@ -173,7 +173,9 @@ async def _(
|
|||||||
bot, event, session, message, name.result, num.result, ""
|
bot, event, session, message, name.result, num.result, ""
|
||||||
)
|
)
|
||||||
logger.info(
|
logger.info(
|
||||||
f"使用道具 {name}, 数量: {num}", arparma.header_result, session=session
|
f"使用道具 {name.result}, 数量: {num.result}",
|
||||||
|
arparma.header_result,
|
||||||
|
session=session,
|
||||||
)
|
)
|
||||||
if isinstance(result, str):
|
if isinstance(result, str):
|
||||||
await MessageUtils.build_message(result).send(reply_to=True)
|
await MessageUtils.build_message(result).send(reply_to=True)
|
||||||
|
|||||||
@ -106,8 +106,8 @@ class JsdelivrStrategy:
|
|||||||
def get_file_paths(self, module_path: str, is_dir: bool = True) -> list[str]:
|
def get_file_paths(self, module_path: str, is_dir: bool = True) -> list[str]:
|
||||||
"""获取文件路径"""
|
"""获取文件路径"""
|
||||||
paths = module_path.split("/")
|
paths = module_path.split("/")
|
||||||
filename = "" if is_dir else paths[-1]
|
filename = "" if is_dir and module_path else paths[-1]
|
||||||
paths = paths if is_dir else paths[:-1]
|
paths = paths if is_dir and module_path else paths[:-1]
|
||||||
cur_file = self.body
|
cur_file = self.body
|
||||||
for path in paths: # 导航到正确的目录
|
for path in paths: # 导航到正确的目录
|
||||||
cur_file = next(
|
cur_file = next(
|
||||||
@ -141,7 +141,8 @@ class JsdelivrStrategy:
|
|||||||
]
|
]
|
||||||
return []
|
return []
|
||||||
|
|
||||||
return collect_files(cur_file, "/".join(paths), filename)
|
files = collect_files(cur_file, "/".join(paths), filename)
|
||||||
|
return files if module_path else [f[1:] for f in files]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@cached(ttl=CACHED_API_TTL)
|
@cached(ttl=CACHED_API_TTL)
|
||||||
@ -208,7 +209,7 @@ class GitHubStrategy:
|
|||||||
for file in tree_info.tree
|
for file in tree_info.tree
|
||||||
if file.type == TreeType.FILE
|
if file.type == TreeType.FILE
|
||||||
and file.path.startswith(module_path)
|
and file.path.startswith(module_path)
|
||||||
and (not is_dir or file.path[len(module_path)] == "/")
|
and (not is_dir or file.path[len(module_path)] == "/" or not module_path)
|
||||||
]
|
]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user