🎨 修复bug,移除plugins文件夹

This commit is contained in:
HibiKier
2024-08-29 22:01:34 +08:00
parent e10fee74b3
commit 625f17a708
146 changed files with 580 additions and 18320 deletions
@@ -1,20 +1,18 @@
import time
from datetime import datetime, timedelta, timezone
from datetime import datetime, timezone, timedelta
from nonebot.adapters import Bot
# from nonebot.adapters.discord import Bot as DiscordBot
# from nonebot.adapters.dodo import Bot as DodoBot
from nonebot.adapters.dodo.models import MemberInfo
# from nonebot.adapters.kaiheila import Bot as KaiheilaBot
from nonebot.adapters.onebot.v11 import Bot as v11Bot
from nonebot.adapters.onebot.v12 import Bot as v12Bot
from zhenxun.configs.config import Config
from zhenxun.models.group_member_info import GroupInfoUser
from zhenxun.models.level_user import LevelUser
from zhenxun.services.log import logger
from zhenxun.configs.config import Config
from zhenxun.models.level_user import LevelUser
from zhenxun.models.group_member_info import GroupInfoUser
# from nonebot.adapters.discord import Bot as DiscordBot
# from nonebot.adapters.dodo import Bot as DodoBot
class MemberUpdateManage:
@@ -98,29 +96,27 @@ class MemberUpdateManage:
user_id = str(user_info["user_id"])
nickname = user_info["card"] or user_info["nickname"]
role = user_info["role"]
if default_auth:
if role in ["owner", "admin"] and not await LevelUser.is_group_flag(
user_id, group_id
):
if role == "owner":
await LevelUser.set_level(user_id, group_id, default_auth + 1)
else:
await LevelUser.set_level(user_id, group_id, default_auth)
if (
default_auth
and role in ["owner", "admin"]
and not await LevelUser.is_group_flag(user_id, group_id)
):
if role == "owner":
await LevelUser.set_level(user_id, group_id, default_auth + 1)
else:
await LevelUser.set_level(user_id, group_id, default_auth)
if user_id in bot.config.superusers:
await LevelUser.set_level(user_id, group_id, 9)
join_time = datetime.strptime(
time.strftime(
"%Y-%m-%d %H:%M:%S", time.localtime(user_info["join_time"])
),
"%Y-%m-%d %H:%M:%S",
).replace(tzinfo=timezone(timedelta(hours=8)))
join_time = datetime.fromtimestamp(
user_info["join_time"], timezone(timedelta(hours=8))
)
if cnt := db_user_uid.count(user_id):
users = [u for u in db_user if u.user_id == user_id]
user = users[0]
if cnt > 1:
for u in users[1:]:
delete_list.append(u.id)
if nickname != uid2name.get(user_id):
user = users[0]
user.user_name = nickname
update_list.append(user)
else:
@@ -156,7 +152,7 @@ class MemberUpdateManage:
user_id__in=delete_member_list, group_id=group_id
).delete()
logger.info(
f"删除已退群用户", "更新群组成员信息", group_id=group_id, platform="qq"
"删除已退群用户", "更新群组成员信息", group_id=group_id, platform="qq"
)
@classmethod
@@ -165,7 +161,8 @@ class MemberUpdateManage:
pass
# exist_member_list = []
# default_auth = Config.get_config("admin_bot_manage", "ADMIN_DEFAULT_AUTH")
# group_member_list: list[GetGroupMemberInfoResp] = await bot.get_group_member_list(
# group_member_list: list[GetGroupMemberInfoResp] =
# await bot.get_group_member_list(
# group_id=group_id
# )
# for user_info in group_member_list:
@@ -180,7 +177,8 @@ class MemberUpdateManage:
# if str(user_id) in bot.config.superusers:
# await LevelUser.set_level(str(user_id), group_id, 9)
# join_time = datetime.strptime(
# time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(user_info["join_time"])),
# time.strftime("%Y-%m-%d %H:%M:%S",
# time.localtime(user_info["join_time"])),
# "%Y-%m-%d %H:%M:%S",
# )
# await GroupInfoUser.update_or_create(
@@ -194,7 +192,8 @@ class MemberUpdateManage:
# },
# )
# exist_member_list.append(str(user_id))
# logger.debug("更新成功", "更新群组成员信息", session=user_id, group_id=group_id)
# logger.debug("更新成功", "更新群组成员信息",
# session=user_id, group_id=group_id)
# if delete_member_list := list(
# set(exist_member_list).difference(
# set(await GroupInfoUser.get_group_member_id_list(group_id))
@@ -1,14 +1,14 @@
from nonebot.rule import to_me
from nonebot.adapters import Bot
from nonebot.permission import SUPERUSER
from nonebot.plugin import PluginMetadata
from nonebot.rule import to_me
from nonebot_plugin_alconna import Alconna, Args, Match, on_alconna
from nonebot_plugin_session import EventSession
from nonebot_plugin_alconna import Args, Match, Alconna, on_alconna
from zhenxun.configs.utils import PluginExtraData, RegisterConfig
from zhenxun.services.log import logger
from zhenxun.utils.enum import PluginType
from zhenxun.utils.message import MessageUtils
from zhenxun.configs.utils import RegisterConfig, PluginExtraData
from ._data_source import UpdateManage
@@ -32,12 +32,6 @@ __plugin_meta__ = PluginMetadata(
help="是否检测更新版本",
default_value=True,
),
RegisterConfig(
key="UPDATE_REMIND",
value=True,
help="是否检测更新版本",
default_value=True,
),
],
).dict(),
)
+21 -19
View File
@@ -3,9 +3,9 @@ from pathlib import Path
import nonebot
from nonebot.adapters import Bot
from zhenxun.models.group_console import GroupConsole
from zhenxun.services.log import logger
from zhenxun.utils.platform import PlatformUtils
from zhenxun.models.group_console import GroupConsole
nonebot.load_plugins(str(Path(__file__).parent.resolve()))
@@ -20,22 +20,24 @@ async def _(bot: Bot):
参数:
bot: Bot
"""
if PlatformUtils.get_platform(bot) == "qq":
logger.debug(f"更新Bot: {bot.self_id} 的群认证...")
group_list, _ = await PlatformUtils.get_group_list(bot)
db_group_list = await GroupConsole.all().values_list("group_id", flat=True)
create_list = []
update_id = []
for group in group_list:
if group.group_id not in db_group_list:
group.group_flag = 1
create_list.append(group)
else:
update_id.append(group.group_id)
if create_list:
await GroupConsole.bulk_create(create_list, 10)
if PlatformUtils.get_platform(bot) != "qq":
return
logger.debug(f"更新Bot: {bot.self_id} 的群认证...")
group_list, _ = await PlatformUtils.get_group_list(bot)
db_group_list = await GroupConsole.all().values_list("group_id", flat=True)
create_list = []
update_id = []
for group in group_list:
if group.group_id not in db_group_list:
group.group_flag = 1
create_list.append(group)
else:
await GroupConsole.filter(group_id__in=update_id).update(group_flag=1)
logger.debug(
f"更新Bot: {bot.self_id} 的群认证完成,共创建 {len(create_list)} 条数据,共修改 {len(update_id)} 条数据..."
)
update_id.append(group.group_id)
if create_list:
await GroupConsole.bulk_create(create_list, 10)
else:
await GroupConsole.filter(group_id__in=update_id).update(group_flag=1)
logger.debug(
f"更新Bot: {bot.self_id} 的群认证完成,共创建 {len(create_list)} 条数据,"
"共修改 {len(update_id)} 条数据..."
)
+63 -58
View File
@@ -1,23 +1,24 @@
import nonebot
import aiofiles
import ujson as json
from nonebot import get_loaded_plugins
from nonebot.drivers import Driver
from nonebot.plugin import Plugin
from ruamel.yaml import YAML
from nonebot.plugin import Plugin
from nonebot.drivers import Driver
from nonebot import get_loaded_plugins
from zhenxun.services.log import logger
from zhenxun.models.task_info import TaskInfo
from zhenxun.configs.path_config import DATA_PATH
from zhenxun.configs.utils import PluginExtraData, PluginSetting
from zhenxun.models.group_console import GroupConsole
from zhenxun.models.plugin_info import PluginInfo
from zhenxun.models.plugin_limit import PluginLimit
from zhenxun.models.task_info import TaskInfo
from zhenxun.services.log import logger
from zhenxun.models.group_console import GroupConsole
from zhenxun.configs.utils import PluginSetting, PluginExtraData
from zhenxun.utils.enum import (
BlockType,
PluginType,
LimitCheckType,
LimitWatchType,
PluginLimitType,
PluginType,
)
_yaml = YAML(pure=True)
@@ -31,7 +32,7 @@ async def _handle_setting(
plugin: Plugin,
plugin_list: list[PluginInfo],
limit_list: list[PluginLimit],
task_list: list[TaskInfo],
task_list: list[tuple[bool, TaskInfo]],
):
"""处理插件设置
@@ -40,8 +41,7 @@ async def _handle_setting(
plugin_list: 插件列表
limit_list: 插件限制列表
"""
metadata = plugin.metadata
if metadata:
if metadata := plugin.metadata:
extra = metadata.extra
extra_data = PluginExtraData(**extra)
logger.debug(f"{metadata.name}:{plugin.name} -> {extra}", "初始化插件数据")
@@ -71,30 +71,34 @@ async def _handle_setting(
)
)
if extra_data.limits:
for limit in extra_data.limits:
limit_list.append(
PluginLimit(
module=plugin.name,
module_path=plugin.module_name,
limit_type=limit._type,
watch_type=limit.watch_type,
status=limit.status,
check_type=limit.check_type,
result=limit.result,
cd=getattr(limit, "cd", None),
max_count=getattr(limit, "max_count", None),
)
limit_list.extend(
PluginLimit(
module=plugin.name,
module_path=plugin.module_name,
limit_type=limit._type,
watch_type=limit.watch_type,
status=limit.status,
check_type=limit.check_type,
result=limit.result,
cd=getattr(limit, "cd", None),
max_count=getattr(limit, "max_count", None),
)
for limit in extra_data.limits
)
if extra_data.tasks:
for task in extra_data.tasks:
task_list.append((task.create_status,
task_list.extend(
(
task.create_status,
TaskInfo(
module=task.module,
name=task.name,
status=task.status,
run_time=task.run_time,
)
))
default_status=task.default_status,
),
)
for task in extra_data.tasks
)
@driver.on_startup
@@ -104,7 +108,7 @@ async def _():
"""
plugin_list: list[PluginInfo] = []
limit_list: list[PluginLimit] = []
task_list: list[TaskInfo] = []
task_list = []
module2id = {}
load_plugin = []
if module_list := await PluginInfo.all().values("id", "module_path"):
@@ -132,14 +136,15 @@ async def _():
update_list.append(plugin)
if create_list:
await PluginInfo.bulk_create(create_list, 10)
if update_list:
# TODO: 批量更新无法更新plugin_type: tortoise.exceptions.OperationalError: column "superuser" does not exist
pass
# await PluginInfo.bulk_update(
# update_list,
# ["name", "author", "version", "admin_level", "plugin_type"],
# 10,
# )
# if update_list:
# # TODO: 批量更新无法更新plugin_type: tortoise.exceptions.OperationalError:
# column "superuser" does not exist
# pass
# await PluginInfo.bulk_update(
# update_list,
# ["name", "author", "version", "admin_level", "plugin_type"],
# 10,
# )
if limit_list:
limit_create = []
plugins = []
@@ -147,8 +152,8 @@ async def _():
plugins = await PluginInfo.filter(module_path__in=module_path_list).all()
if plugins:
for limit in limit_list:
if l := [p for p in plugins if p.module_path == limit.module_path]:
plugin = l[0]
if lmt := [p for p in plugins if p.module_path == limit.module_path]:
plugin = lmt[0]
limit_type_list = [
_limit.limit_type for _limit in await plugin.plugin_limit.all() # type: ignore
]
@@ -170,7 +175,7 @@ async def _():
task.id = module_dict[task.module]
update_list.append(task)
if create_list:
_create_list = [t[1] for t in create_list]
_create_list = [t[1] for t in create_list]
await TaskInfo.bulk_create(_create_list, 10)
if block := [t[1].module for t in create_list if not t[0]]:
block_task = ",".join(block) + ","
@@ -202,14 +207,14 @@ async def limit_migration():
count_file = DATA_PATH / "configs" / "plugins2count.yaml"
limit_data: dict[str, list[tuple[str, dict]]] = {}
if cd_file.exists():
with open(cd_file, encoding="utf8") as f:
if data := _yaml.load(f):
async with aiofiles.open(cd_file, encoding="utf8") as f:
if data := _yaml.load(await f.read()):
for k in data["PluginCdLimit"]:
limit_data[k] = [("CD", data["PluginCdLimit"][k])]
cd_file.unlink()
if block_file.exists():
with open(block_file, encoding="utf8") as f:
if data := _yaml.load(f):
async with aiofiles.open(block_file, encoding="utf8") as f:
if data := _yaml.load(await f.read()):
for k in data["PluginBlockLimit"]:
if k in limit_data:
limit_data[k].append(("BLOCK", data["PluginBlockLimit"][k]))
@@ -217,8 +222,8 @@ async def limit_migration():
limit_data[k] = [("BLOCK", data["PluginBlockLimit"][k])]
block_file.unlink()
if count_file.exists():
with open(count_file, encoding="utf8") as f:
if data := _yaml.load(f):
async with aiofiles.open(count_file, encoding="utf8") as f:
if data := _yaml.load(await f.read()):
for k in data["PluginCountLimit"]:
if k in limit_data:
limit_data[k].append(("COUNT", data["PluginCountLimit"][k]))
@@ -294,7 +299,8 @@ async def limit_migration():
max_count=_limit.get("max_count"),
)
)
# TODO: 批量错误 tortoise.exceptions.OperationalError: syntax error at or near "ALL"
# TODO: 批量错误 tortoise.exceptions.OperationalError:
# syntax error at or near "ALL"
# if update_list:
# await PluginLimit.bulk_update(
# update_list,
@@ -318,8 +324,8 @@ async def plugin_migration():
setting_file = DATA_PATH / "configs" / "plugins2settings.yaml"
plugin_file = DATA_PATH / "manager" / "plugins_manager.json"
if setting_file.exists():
with open(setting_file, encoding="utf8") as f:
if data := _yaml.load(f):
async with aiofiles.open(setting_file, encoding="utf8") as f:
if data := _yaml.load(await f.read()):
logger.info("开始迁移插件setting数据...")
data = data["PluginSettings"]
plugins = await PluginInfo.filter(module__in=data.keys())
@@ -349,8 +355,8 @@ async def plugin_migration():
setting_file.unlink()
logger.info("迁移插件setting数据完成!")
if plugin_file.exists():
with open(plugin_file, encoding="utf8") as f:
if data := json.load(f):
async with aiofiles.open(plugin_file, encoding="utf8") as f:
if data := json.loads(await f.read()):
logger.info("开始迁移插件数据...")
plugins = await PluginInfo.filter(module__in=data.keys())
for plugin in plugins:
@@ -366,7 +372,8 @@ async def plugin_migration():
block_type = BlockType.GROUP
plugin.block_type = block_type
await plugin.save(update_fields=["status", "block_type"])
# TODO: tortoise.exceptions.OperationalError: syntax error at or near "ALL"
# TODO: tortoise.exceptions.OperationalError: syntax error at
# or near "ALL"
# await PluginInfo.bulk_update(plugins, ["status", "block_type"], 10)
plugin_file.unlink()
logger.info("迁移插件数据完成!")
@@ -378,22 +385,20 @@ async def group_migration():
"""
group_file = DATA_PATH / "manager" / "group_manager.json"
if group_file.exists():
with open(group_file, encoding="utf8") as f:
if data := json.load(f):
async with aiofiles.open(group_file, encoding="utf8") as f:
if data := json.loads(await f.read()):
logger.info("开始迁移群组数据...")
update_list = []
create_list = []
white_group = data["white_group"]
close_task = data["close_task"]
old_group_list: dict = data["group_manager"]
if close_task:
if close_task := data["close_task"]:
"""全局被动关闭"""
await TaskInfo.filter(module__in=close_task).update(status=False)
group_list = await GroupConsole.filter(
group_id__in=old_group_list.keys()
)
for old_group_id in old_group_list:
old_group = old_group_list[old_group_id]
for old_group_id, old_group in old_group_list.items():
block_plugin = ""
block_task = ""
status = old_group.get("status", True)
@@ -19,11 +19,11 @@ from nonebot.adapters.onebot.v12 import (
from zhenxun.services.log import logger
from zhenxun.utils.utils import FreqLimiter
from zhenxun.models.task_info import TaskInfo
from zhenxun.utils.message import MessageUtils
from zhenxun.models.fg_request import FgRequest
from zhenxun.models.level_user import LevelUser
from zhenxun.models.plugin_info import PluginInfo
from zhenxun.utils.common_utils import CommonUtils
from zhenxun.configs.config import Config, BotConfig
from zhenxun.models.group_console import GroupConsole
from zhenxun.models.group_member_info import GroupInfoUser
@@ -242,7 +242,7 @@ async def _(bot: Bot, event: GroupIncreaseNoticeEvent | GroupMemberIncreaseEvent
img_file = path / f"{i}.png"
if img_file.exists():
msg_list.append(img_file)
if not await TaskInfo.is_block("group_welcome", group_id):
if not await CommonUtils.is_block("group_welcome", group_id):
logger.info("发送群欢迎消息...", "入群检测", group_id=group_id)
if msg_list:
await MessageUtils.build_message(msg_list).send()
@@ -314,5 +314,5 @@ async def _(bot: Bot, event: GroupDecreaseNoticeEvent | GroupMemberDecreaseEvent
)
operator_name = operator["card"] or operator["nickname"]
result = f"{user_name} 被 {operator_name} 送走了."
if not await TaskInfo.is_block("refund_group_remind", str(event.group_id)):
if not await CommonUtils.is_block("refund_group_remind", str(event.group_id)):
await group_decrease_handle.send(f"{result}")
@@ -3,19 +3,20 @@ import shutil
import subprocess
from pathlib import Path
import aiofiles
import ujson as json
from zhenxun.models.plugin_info import PluginInfo
from zhenxun.services.log import logger
from zhenxun.utils.http_utils import AsyncHttpx
from zhenxun.utils.image_utils import BuildImage, ImageTemplate, RowStyle
from zhenxun.models.plugin_info import PluginInfo
from zhenxun.utils.image_utils import RowStyle, BuildImage, ImageTemplate
from .config import (
BASE_PATH,
CONFIG_INDEX_CDN_URL,
CONFIG_INDEX_URL,
CONFIG_URL,
DOWNLOAD_URL,
CONFIG_INDEX_URL,
CONFIG_INDEX_CDN_URL,
)
@@ -30,17 +31,16 @@ def row_style(column: str, text: str) -> RowStyle:
RowStyle: RowStyle
"""
style = RowStyle()
if column in ["-"]:
if text == "已安装":
style.font_color = "#67C23A"
if column == "-" and text == "已安装":
style.font_color = "#67C23A"
return style
async def recurrence_get_url(
url: str,
data_list: list[tuple[str, str]],
ignore_list: list[str] = [],
api_url: str = None,
ignore_list: list[str] | None = None,
api_url: str | None = None,
):
"""递归获取目录下所有文件
@@ -51,14 +51,15 @@ async def recurrence_get_url(
异常:
ValueError: 访问错误
"""
if ignore_list is None:
ignore_list = []
logger.debug(f"访问插件下载信息 URL: {url}", "插件管理")
res = await AsyncHttpx.get(url)
if res.status_code != 200:
raise ValueError(f"访问错误, code: {res.status_code}")
json_data = res.json()
if isinstance(json_data, list):
for v in json_data:
data_list.append((v.get("download_url"), v["path"]))
data_list.extend((v.get("download_url"), v["path"]) for v in json_data)
else:
data_list.append((json_data.get("download_url"), json_data["path"]))
for download_url, path in data_list:
@@ -69,7 +70,7 @@ async def recurrence_get_url(
await recurrence_get_url(_url, data_list, ignore_list, api_url)
async def download_file(url: str, _is: bool = False, api_url: str = None):
async def download_file(url: str, _is: bool = False, api_url: str | None = None):
"""下载文件
参数:
@@ -88,14 +89,13 @@ async def download_file(url: str, _is: bool = False, api_url: str = None):
base_path = "zhenxun/plugins/" if _is else "zhenxun/"
file = Path(f"{base_path}{path}")
file.parent.mkdir(parents=True, exist_ok=True)
print(download_url)
r = await AsyncHttpx.get(download_url)
if r.status_code != 200:
raise ValueError(f"文件下载错误, code: {r.status_code}")
content = r.text.replace("\r\n", "\n") # 统一换行符为 UNIX 风格
with open(file, "w", encoding="utf8") as f:
async with aiofiles.open(file, "w", encoding="utf8") as f:
logger.debug(f"写入文件: {file}", "插件管理")
f.write(content)
await f.write(content)
def install_requirement(plugin_path: Path):
@@ -116,22 +116,23 @@ def install_requirement(plugin_path: Path):
result = subprocess.run(
["pip", "install", "-r", str(existing_requirements)],
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
capture_output=True,
text=True,
)
logger.debug(
f"Successfully installed dependencies for plugin: {plugin_path.name}. Output:\n{result.stdout}",
"Successfully installed dependencies for"
f" plugin: {plugin_path.name}. Output:\n{result.stdout}",
"插件管理",
)
except subprocess.CalledProcessError as e:
except subprocess.CalledProcessError:
logger.error(
f"Failed to install dependencies for plugin: {plugin_path.name}. Error:\n{e.stderr}"
f"Failed to install dependencies for plugin: {plugin_path.name}. "
" Error:\n{e.stderr}"
)
class ShopManage:
type2name = {
type2name = { # noqa: RUF012
"NORMAL": "普通插件",
"ADMIN": "管理员插件",
"SUPERUSER": "超级用户插件",
@@ -169,9 +170,8 @@ class ShopManage:
@classmethod
def version_check(cls, plugin_info: dict, suc_plugin: dict[str, str]):
module = plugin_info["module"]
if module in suc_plugin:
if plugin_info["version"] != suc_plugin[module]:
return f"{suc_plugin[module]} (有更新->{plugin_info['version']})"
if module in suc_plugin and plugin_info["version"] != suc_plugin[module]:
return f"{suc_plugin[module]} (有更新->{plugin_info['version']})"
return plugin_info["version"]
@classmethod
@@ -226,7 +226,7 @@ class ShopManage:
]
return await ImageTemplate.table_page(
"插件列表",
f"通过安装/卸载插件 ID 来管理插件",
"通过安装/卸载插件 ID 来管理插件",
column_name,
data_list,
text_style=row_style,
@@ -254,7 +254,9 @@ class ShopManage:
logger.debug(f"尝试下载插件 URL: {url_path}", "插件管理")
github_url = plugin_info.get("github_url")
if github_url:
github_path = re.search(r"github\.com/([^/]+/[^/]+)", github_url).group(1)
if not (r := re.search(r"github\.com/([^/]+/[^/]+)", github_url)):
return "github地址格式错误"
github_path = r[1]
api_url = f"https://api.github.com/repos/{github_path}/contents/"
download_url = f"{api_url}{url_path}?ref=main"
else:
@@ -265,28 +267,27 @@ class ShopManage:
# 安装依赖
plugin_path = BASE_PATH / "/".join(module_path_split)
if url_path and github_url:
if url_path and github_url and api_url:
plugin_path = BASE_PATH / "plugins" / "/".join(module_path_split)
res = await AsyncHttpx.get(api_url)
if res.status_code != 200:
return f"访问错误, code: {res.status_code}"
json_data = res.json()
requirement_file = next(
if requirement_file := next(
(
v
for v in json_data
if v["name"] in ["requirements.txt", "requirement.txt"]
),
None,
)
if requirement_file:
):
r = await AsyncHttpx.get(requirement_file.get("download_url"))
if r.status_code != 200:
raise ValueError(f"文件下载错误, code: {r.status_code}")
requirement_path = plugin_path / requirement_file["name"]
with open(requirement_path, "w", encoding="utf8") as f:
async with aiofiles.open(requirement_path, "w", encoding="utf8") as f:
logger.debug(f"写入文件: {requirement_path}", "插件管理")
f.write(r.text)
await f.write(r.text)
install_requirement(plugin_path)
@@ -308,8 +309,7 @@ class ShopManage:
plugin_key = list(data.keys())[plugin_id]
plugin_info = data[plugin_key]
path = BASE_PATH
github_url = plugin_info.get("github_url")
if github_url:
if plugin_info.get("github_url"):
path = BASE_PATH / "plugins"
for p in plugin_info["module_path"].split("."):
path = path / p
@@ -335,7 +335,6 @@ class ShopManage:
BuildImage | str: 返回消息
"""
data: dict = await cls.__get_data()
column_name = ["-", "ID", "名称", "简介", "作者", "版本", "类型"]
for k in data.copy():
if data[k]["plugin_type"]:
data[k]["plugin_type"] = cls.type2name[data[k]["plugin_type"]]
@@ -364,9 +363,10 @@ class ShopManage:
]
if not data_list:
return "未找到相关插件..."
column_name = ["-", "ID", "名称", "简介", "作者", "版本", "类型"]
return await ImageTemplate.table_page(
"插件列表",
f"通过添加/移除插件 ID 来管理插件",
"通过添加/移除插件 ID 来管理插件",
column_name,
data_list,
text_style=row_style,
@@ -394,7 +394,9 @@ class ShopManage:
logger.debug(f"尝试下载插件 URL: {url_path}", "插件管理")
github_url = plugin_info.get("github_url")
if github_url:
github_path = re.search(r"github\.com/([^/]+/[^/]+)", github_url).group(1)
if not (r := re.search(r"github\.com/([^/]+/[^/]+)", github_url)):
return "github地址格式错误..."
github_path = r[1]
api_url = f"https://api.github.com/repos/{github_path}/contents/"
download_url = f"{api_url}{url_path}?ref=main"
else:
@@ -405,28 +407,27 @@ class ShopManage:
# 安装依赖
plugin_path = BASE_PATH / "/".join(module_path_split)
if url_path and github_url:
if url_path and github_url and api_url:
plugin_path = BASE_PATH / "plugins" / "/".join(module_path_split)
res = await AsyncHttpx.get(api_url)
if res.status_code != 200:
return f"访问错误, code: {res.status_code}"
json_data = res.json()
requirement_file = next(
if requirement_file := next(
(
v
for v in json_data
if v["name"] in ["requirements.txt", "requirement.txt"]
),
None,
)
if requirement_file:
):
r = await AsyncHttpx.get(requirement_file.get("download_url"))
if r.status_code != 200:
raise ValueError(f"文件下载错误, code: {r.status_code}")
requirement_path = plugin_path / requirement_file["name"]
with open(requirement_path, "w", encoding="utf8") as f:
async with aiofiles.open(requirement_path, "w", encoding="utf8") as f:
logger.debug(f"写入文件: {requirement_path}", "插件管理")
f.write(r.text)
await f.write(r.text)
install_requirement(plugin_path)
+82 -73
View File
@@ -1,25 +1,27 @@
import time
from datetime import datetime
import nonebot
from nonebot import on_message, on_request
from nonebot.adapters.onebot.v11 import ActionFailed
from nonebot.adapters.onebot.v11 import Bot as v11Bot
from nonebot.adapters.onebot.v11 import FriendRequestEvent, GroupRequestEvent
from nonebot.adapters.onebot.v12 import Bot as v12Bot
from nonebot.plugin import PluginMetadata
from nonebot_plugin_apscheduler import scheduler
from nonebot import on_message, on_request
from nonebot_plugin_session import EventSession
from nonebot_plugin_apscheduler import scheduler
from nonebot.adapters.onebot.v11 import Bot as v11Bot
from nonebot.adapters.onebot.v12 import Bot as v12Bot
from nonebot.adapters.onebot.v11 import (
ActionFailed,
GroupRequestEvent,
FriendRequestEvent,
)
from zhenxun.configs.config import BotConfig, Config
from zhenxun.configs.utils import PluginExtraData, RegisterConfig
from zhenxun.models.fg_request import FgRequest
from zhenxun.models.friend_user import FriendUser
from zhenxun.models.group_console import GroupConsole
from zhenxun.services.log import logger
from zhenxun.utils.enum import PluginType, RequestHandleType, RequestType
from zhenxun.utils.message import MessageUtils
from zhenxun.models.fg_request import FgRequest
from zhenxun.utils.platform import PlatformUtils
from zhenxun.models.friend_user import FriendUser
from zhenxun.configs.config import Config, BotConfig
from zhenxun.models.group_console import GroupConsole
from zhenxun.configs.utils import RegisterConfig, PluginExtraData
from zhenxun.utils.enum import PluginType, RequestType, RequestHandleType
base_config = Config.get("invite_manager")
@@ -46,13 +48,11 @@ __plugin_meta__ = PluginMetadata(
class Timer:
data: dict[str, float] = {}
data: dict[str, float] = {} # noqa: RUF012
@classmethod
def check(cls, uid: int | str):
if uid not in cls.data:
return True
return time.time() - cls.data[uid] > 5 * 60
return True if uid not in cls.data else time.time() - cls.data[uid] > 5 * 60
@classmethod
def clear(cls):
@@ -71,7 +71,7 @@ _t = on_message(priority=999, block=False, rule=lambda: False)
async def _(bot: v12Bot | v11Bot, event: FriendRequestEvent, session: EventSession):
superuser = BotConfig.get_superuser("qq")
if event.user_id and Timer.check(event.user_id):
logger.debug(f"收录好友请求...", "好友请求", target=event.user_id)
logger.debug("收录好友请求...", "好友请求", target=event.user_id)
user = await bot.get_stranger_info(user_id=event.user_id)
nickname = user["nickname"]
# sex = user["sex"]
@@ -87,7 +87,7 @@ async def _(bot: v12Bot | v11Bot, event: FriendRequestEvent, session: EventSessi
).send(target=PlatformUtils.get_target(bot, superuser))
if base_config.get("AUTO_ADD_FRIEND"):
logger.debug(
f"已开启好友请求自动同意,成功通过该请求",
"已开启好友请求自动同意,成功通过该请求",
"好友请求",
target=event.user_id,
)
@@ -112,22 +112,33 @@ async def _(bot: v12Bot | v11Bot, event: FriendRequestEvent, session: EventSessi
comment=comment,
)
else:
logger.debug(f"好友请求五分钟内重复, 已忽略", "好友请求", target=event.user_id)
logger.debug("好友请求五分钟内重复, 已忽略", "好友请求", target=event.user_id)
@group_req.handle()
async def _(bot: v12Bot | v11Bot, event: GroupRequestEvent, session: EventSession):
superuser = BotConfig.get_superuser("qq")
# 邀请
if event.sub_type == "invite":
if str(event.user_id) in bot.config.superusers:
try:
logger.debug(
f"超级用户自动同意加入群聊",
"超级用户自动同意加入群聊",
"群聊请求",
session=event.user_id,
target=event.group_id,
)
group, _ = await GroupConsole.update_or_create(
group_id=str(event.group_id),
defaults={
"group_name": "",
"max_member_count": 0,
"member_count": 0,
"group_flag": 1,
},
)
await bot.set_group_add_request(
flag=event.flag, sub_type="invite", approve=True
)
if isinstance(bot, v11Bot):
group_info = await bot.get_group_info(group_id=event.group_id)
max_member_count = group_info["max_member_count"]
@@ -136,17 +147,11 @@ async def _(bot: v12Bot | v11Bot, event: GroupRequestEvent, session: EventSessio
group_info = await bot.get_group_info(group_id=str(event.group_id))
max_member_count = 0
member_count = 0
await GroupConsole.update_or_create(
group_id=str(event.group_id),
defaults={
"group_name": group_info["group_name"],
"max_member_count": max_member_count,
"member_count": member_count,
"group_flag": 1,
},
)
await bot.set_group_add_request(
flag=event.flag, sub_type="invite", approve=True
group.max_member_count = max_member_count
group.member_count = member_count
group.group_name = group_info["group_name"]
await group.save(
update_fields=["group_name", "max_member_count", "member_count"]
)
except ActionFailed as e:
logger.error(
@@ -156,47 +161,47 @@ async def _(bot: v12Bot | v11Bot, event: GroupRequestEvent, session: EventSessio
target=event.group_id,
e=e,
)
elif Timer.check(f"{event.user_id}:{event.group_id}"):
logger.debug(
f"收录 用户[{event.user_id}] 群聊[{event.group_id}] 群聊请求",
"群聊请求",
target=event.group_id,
)
nickname = await FriendUser.get_user_name(str(event.user_id))
await PlatformUtils.send_superuser(
bot,
f"*****一份入群申请*****\n申请人:{nickname}({event.user_id})\n群聊:"
f"{event.group_id}\n邀请日期:{datetime.now().replace(microsecond=0)}",
superuser,
)
await bot.send_private_msg(
user_id=event.user_id,
message=f"想要邀请我偷偷入群嘛~已经提醒{BotConfig.self_nickname}的管理员大人了\n"
"请确保已经群主或群管理沟通过!\n"
"等待管理员处理吧!",
)
# 旧请求全部设置为过期
await FgRequest.filter(
request_type=RequestType.GROUP,
user_id=str(event.user_id),
group_id=str(event.group_id),
handle_type__isnull=True,
).update(handle_type=RequestHandleType.EXPIRE)
await FgRequest.create(
request_type=RequestType.GROUP,
platform=session.platform,
bot_id=bot.self_id,
flag=event.flag,
user_id=str(event.user_id),
nickname=nickname,
group_id=str(event.group_id),
)
else:
if Timer.check(f"{event.user_id}:{event.group_id}"):
logger.debug(
f"收录 用户[{event.user_id}] 群聊[{event.group_id}] 群聊请求",
"群聊请求",
target=event.group_id,
)
nickname = await FriendUser.get_user_name(str(event.user_id))
await PlatformUtils.send_superuser(
bot,
f"*****一份入群申请*****\n申请人:{nickname}({event.user_id})\n群聊:{event.group_id}\n邀请日期:{datetime.now().replace(microsecond=0)}",
superuser,
)
await bot.send_private_msg(
user_id=event.user_id,
message=f"想要邀请我偷偷入群嘛~已经提醒{BotConfig.self_nickname}的管理员大人了\n"
"请确保已经群主或群管理沟通过!\n"
"等待管理员处理吧!",
)
# 旧请求全部设置为过期
await FgRequest.filter(
request_type=RequestType.GROUP,
user_id=str(event.user_id),
group_id=str(event.group_id),
handle_type__isnull=True,
).update(handle_type=RequestHandleType.EXPIRE)
await FgRequest.create(
request_type=RequestType.GROUP,
platform=session.platform,
bot_id=bot.self_id,
flag=event.flag,
user_id=str(event.user_id),
nickname=nickname,
group_id=str(event.group_id),
)
else:
logger.debug(
f"群聊请求五分钟内重复, 已忽略",
"群聊请求",
target=f"{event.user_id}:{event.group_id}",
)
logger.debug(
"群聊请求五分钟内重复, 已忽略",
"群聊请求",
target=f"{event.user_id}:{event.group_id}",
)
@scheduler.scheduled_job(
@@ -205,3 +210,7 @@ async def _(bot: v12Bot | v11Bot, event: GroupRequestEvent, session: EventSessio
)
async def _():
Timer.clear()
async def _():
Timer.clear()
@@ -3,8 +3,8 @@ from pathlib import Path
from nonebot_plugin_apscheduler import scheduler
from zhenxun.configs.config import Config
from zhenxun.services.log import logger
from zhenxun.configs.config import Config
Config.add_plugin_config(
"_backup",
@@ -18,14 +18,7 @@ Config.add_plugin_config(
Config.add_plugin_config(
"_backup",
"BACKUP_DIR_OR_FILE",
[
"data/black_word",
"data/configs",
"data/statistics",
"data/word_bank",
"data/manager",
"configs",
],
["data"],
help="备份的文件夹或文件",
default_value=[],
type=list[str],
@@ -39,24 +32,25 @@ Config.add_plugin_config(
minute=25,
)
async def _():
if Config.get_config("_backup", "BACKUP_FLAG"):
_backup_path = Path() / "backup"
_backup_path.mkdir(exist_ok=True, parents=True)
if backup_dir_or_file := Config.get_config("_backup", "BACKUP_DIR_OR_FILE"):
for path_file in backup_dir_or_file:
try:
path = Path(path_file)
_p = _backup_path / path_file
if path.exists():
if path.is_dir():
if _p.exists():
shutil.rmtree(_p, ignore_errors=True)
shutil.copytree(path_file, _p)
else:
if _p.exists():
_p.unlink()
shutil.copy(path_file, _p)
logger.debug(f"已完成自动备份:{path_file}", "自动备份")
except Exception as e:
logger.error(f"自动备份文件 {path_file} 发生错误", "自动备份", e=e)
logger.info("自动备份成功...", "自动备份")
if not Config.get_config("_backup", "BACKUP_FLAG"):
return
_backup_path = Path() / "backup"
_backup_path.mkdir(exist_ok=True, parents=True)
if backup_dir_or_file := Config.get_config("_backup", "BACKUP_DIR_OR_FILE"):
for path_file in backup_dir_or_file:
try:
path = Path(path_file)
_p = _backup_path / path_file
if path.exists():
if path.is_dir():
if _p.exists():
shutil.rmtree(_p, ignore_errors=True)
shutil.copytree(path_file, _p)
else:
if _p.exists():
_p.unlink()
shutil.copy(path_file, _p)
logger.debug(f"已完成自动备份:{path_file}", "自动备份")
except Exception as e:
logger.error(f"自动备份文件 {path_file} 发生错误", "自动备份", e=e)
logger.info("自动备份成功...", "自动备份")
+6 -5
View File
@@ -2,14 +2,15 @@ import nonebot
from nonebot.plugin import PluginMetadata
from nonebot_plugin_apscheduler import scheduler
from zhenxun.configs.config import BotConfig
from zhenxun.configs.path_config import IMAGE_PATH
from zhenxun.configs.utils import PluginExtraData, Task
from zhenxun.models.task_info import TaskInfo
from zhenxun.services.log import logger
from zhenxun.utils.enum import PluginType
from zhenxun.configs.config import BotConfig
from zhenxun.models.task_info import TaskInfo
from zhenxun.utils.message import MessageUtils
from zhenxun.configs.path_config import IMAGE_PATH
from zhenxun.utils.common_utils import CommonUtils
from zhenxun.utils.platform import broadcast_group
from zhenxun.configs.utils import Task, PluginExtraData
__plugin_meta__ = PluginMetadata(
name="早晚安被动技能",
@@ -37,7 +38,7 @@ async def _():
async def check(group_id: str) -> bool:
return not await TaskInfo.is_block("morning_goodnight", group_id)
return not await CommonUtils.is_block("morning_goodnight", group_id)
# 早上好
@@ -1,5 +1,6 @@
import nonebot_plugin_alconna as alc
from nonebot.adapters import Bot
import nonebot_plugin_alconna as alc
from nonebot_plugin_session import EventSession
# from nonebot.adapters.discord import Bot as DiscordBot
# from nonebot.adapters.dodo import Bot as DodoBot
@@ -7,12 +8,11 @@ from nonebot.adapters import Bot
# from nonebot.adapters.onebot.v11 import Bot as v11Bot
# from nonebot.adapters.onebot.v12 import Bot as v12Bot
from nonebot_plugin_alconna import Image, UniMsg
from nonebot_plugin_session import EventSession
from zhenxun.models.task_info import TaskInfo
from zhenxun.services.log import logger
from zhenxun.utils.message import MessageUtils
from zhenxun.utils.platform import PlatformUtils
from zhenxun.utils.common_utils import CommonUtils
class BroadcastManage:
@@ -42,7 +42,7 @@ class BroadcastManage:
error_count = 0
for group in group_list:
try:
if not await TaskInfo.is_block(
if not await CommonUtils.is_block(
group.group_id,
"broadcast", # group.channel_id
):
+16 -16
View File
@@ -1,19 +1,19 @@
import os
from datetime import datetime, timedelta
import contextlib
from pathlib import Path
import secrets
from datetime import datetime, timezone, timedelta
import psutil
import ujson as json
from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from jose import JWTError, jwt
from nonebot.utils import run_sync
from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from zhenxun.configs.config import Config
from zhenxun.configs.path_config import DATA_PATH
from .base_model import SystemFolderSize, SystemStatus, User
from .base_model import User, SystemStatus, SystemFolderSize
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
@@ -24,10 +24,8 @@ token_file = DATA_PATH / "web_ui" / "token.json"
token_file.parent.mkdir(parents=True, exist_ok=True)
token_data = {"token": []}
if token_file.exists():
try:
token_data = json.load(open(token_file, "r", encoding="utf8"))
except json.JSONDecodeError:
pass
with contextlib.suppress(json.JSONDecodeError):
token_data = json.load(open(token_file, encoding="utf8"))
def get_user(uname: str) -> User | None:
@@ -52,7 +50,7 @@ def create_token(user: User, expires_delta: timedelta | None = None):
user: 用户信息
expires_delta: 过期时间.
"""
expire = datetime.utcnow() + (expires_delta or timedelta(minutes=15))
expire = datetime.now(timezone.utc) + (expires_delta or timedelta(minutes=15))
return jwt.encode(
claims={"sub": user.username, "exp": expire},
key=Config.get_config("web-ui", "secret"),
@@ -71,8 +69,10 @@ def authentication():
# if token not in token_data["token"]:
def inner(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, Config.get_config("web-ui", "secret"), algorithms=[ALGORITHM])
username, expire = payload.get("sub"), payload.get("exp")
payload = jwt.decode(
token, Config.get_config("web-ui", "secret"), algorithms=[ALGORITHM]
)
username, _ = payload.get("sub"), payload.get("exp")
user = get_user(username) # type: ignore
if user is None:
raise JWTError
@@ -90,10 +90,10 @@ def _get_dir_size(dir_path: Path) -> float:
参数:
dir_path: 文件夹路径
"""
size = 0
for root, dirs, files in os.walk(dir_path):
size += sum([os.path.getsize(os.path.join(root, name)) for name in files])
return size
return sum(
sum(os.path.getsize(os.path.join(root, name)) for name in files)
for root, dirs, files in os.walk(dir_path)
)
@run_sync