mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-10-04 03:10:01 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
216d32cf21 | ||
|
|
248fae4fe6 | ||
|
|
b479b6839d | ||
|
|
1a4e1e9515 | ||
|
|
e5160a4ee8 | ||
|
|
56ea3964a7 | ||
|
|
ad73778286 | ||
|
|
3e548f48c8 | ||
|
|
ae466931fa | ||
|
|
68052b526f | ||
|
|
903b5b88a7 | ||
|
|
007823d6b2 | ||
|
|
db5c4fb349 | ||
|
|
c37901290a | ||
|
|
da67f1f6f8 | ||
|
|
5172fa69e5 | ||
|
|
dd7280cd0d | ||
|
|
0d0f522c88 | ||
|
|
5429e6ed5c | ||
|
|
9db69fa05b | ||
|
|
3b8d52bcb5 | ||
|
|
807f39a336 | ||
|
|
fea2f30461 | ||
|
|
5d97e3f95f | ||
|
|
63e6ca3e99 | ||
|
|
b11590ec3c | ||
|
|
3a43ed6919 | ||
|
|
15ce9c91fb | ||
|
|
0e8d7537d4 | ||
|
|
1fca0787be | ||
|
|
af30285c00 | ||
|
|
a84cab7afd | ||
|
|
593573ddfb | ||
|
|
e9e9f81bdb | ||
|
|
61f624841b | ||
|
|
4bb38a2730 | ||
|
|
d4ec0df00c | ||
|
|
c8a7d855f8 | ||
|
|
73a126dcd5 | ||
|
|
0736533389 | ||
|
|
2695d658ab | ||
|
|
947166e793 | ||
|
|
80c49a7cf5 | ||
|
|
55bfa8f669 | ||
|
|
74ade14f5e | ||
|
|
c9b5218ebc | ||
|
|
b324b2bd65 | ||
|
|
35c038efa2 | ||
|
|
caa404d58d | ||
|
|
830103b9d5 | ||
|
|
6e18379597 | ||
|
|
6effbacb28 | ||
|
|
a20a1a0234 | ||
|
|
3667724061 | ||
|
|
785179e4a7 | ||
|
|
715338f821 | ||
|
|
7d5a82ab6d | ||
|
|
e764cfcc1c | ||
|
|
363acf37bc | ||
|
|
5fd687c1e4 | ||
|
|
dbedcbb93d | ||
|
|
9e9611f11f | ||
|
|
44002838da | ||
|
|
4daab8459f | ||
|
|
5a002f75cc | ||
|
|
a2180a1365 | ||
|
|
7b836acf36 | ||
|
|
a112a561cc | ||
|
|
6dcc2a69f4 |
@@ -140,6 +140,7 @@ cython_debug/
|
|||||||
|
|
||||||
test.py
|
test.py
|
||||||
server_ip.py
|
server_ip.py
|
||||||
|
game_utils.py
|
||||||
member_activity_handle.py
|
member_activity_handle.py
|
||||||
Yu-Gi-Oh/
|
Yu-Gi-Oh/
|
||||||
csgo/
|
csgo/
|
||||||
|
|||||||
@@ -243,6 +243,50 @@ __Docker 最新版本由 [Sakuracio](https://github.com/Sakuracio) 提供__
|
|||||||
|
|
||||||
## 更新
|
## 更新
|
||||||
|
|
||||||
|
### 2022/6/19 \[v0.1.6.0]
|
||||||
|
|
||||||
|
* 暂时使用hook修复webui中plugins2setting修改时会改变plugins2setting.cmd为字符串
|
||||||
|
* 修复原神树脂重复提醒的bug [@pull/828](https://github.com/HibiKier/zhenxun_bot/pull/828)
|
||||||
|
* 词条优化问题展示,修改含机器人昵称和@逻辑 [@pull/835](https://github.com/HibiKier/zhenxun_bot/pull/835)
|
||||||
|
|
||||||
|
### 2022/6/18
|
||||||
|
|
||||||
|
* 修复昵称系统`BLACK_WORD`为空时造成报错
|
||||||
|
* 修复特殊头像时背景透明化出错
|
||||||
|
* 修复text2image纯文本时换行时颜色不统一
|
||||||
|
* 优化webUI,当有插件出错时不会影响其他插件显示
|
||||||
|
* 优化Config类型注释 [@pull/830](https://github.com/HibiKier/zhenxun_bot/pull/830)
|
||||||
|
* 优化browser
|
||||||
|
|
||||||
|
### 2022/6/17
|
||||||
|
|
||||||
|
* 修复wordbank的一些小问题 @pull/820
|
||||||
|
|
||||||
|
### 2022/6/14
|
||||||
|
|
||||||
|
* AsyncHttpx提供可关闭 ssl 验证参数 [@pull/812](https://github.com/HibiKier/zhenxun_bot/pull/812)
|
||||||
|
* fix: 自动更新群组 [@pull/810](https://github.com/HibiKier/zhenxun_bot/pull/810)
|
||||||
|
* fix: 修复添加词条时对answer中图片的处理 [@pull/806](https://github.com/HibiKier/zhenxun_bot/pull/806)
|
||||||
|
* 修复pix中指定num无法生效
|
||||||
|
* 替换了bt URL
|
||||||
|
|
||||||
|
### 2022/6/13
|
||||||
|
|
||||||
|
* Windows 重启适配 [@pull/804](https://github.com/HibiKier/zhenxun_bot/pull/804)
|
||||||
|
* 色图等提供修改md5方法 [@pull/800](https://github.com/HibiKier/zhenxun_bot/pull/800)
|
||||||
|
* webui中token.json文件写入补充 [@pull/798](https://github.com/HibiKier/zhenxun_bot/pull/798)
|
||||||
|
* 修复识图某些图片可能会出错
|
||||||
|
|
||||||
|
### 2022/6/11
|
||||||
|
|
||||||
|
* pix当只有一个tag时且为数字时可以通过添加'#'防止判定为数量
|
||||||
|
|
||||||
|
### 2022/6/9
|
||||||
|
|
||||||
|
* 修复b站订阅同群二人以上相同订阅时发送多次信息
|
||||||
|
* 修复超级用户帮助中缺少了 ‘插件商店’ 相关帮助
|
||||||
|
* 昵称系统提供了详细帮助
|
||||||
|
|
||||||
### 2022/6/5 \[v0.1.5.9]
|
### 2022/6/5 \[v0.1.5.9]
|
||||||
|
|
||||||
* webui修复plugin2setting中cmd从list转变为str
|
* webui修复plugin2setting中cmd从list转变为str
|
||||||
@@ -252,7 +296,6 @@ __Docker 最新版本由 [Sakuracio](https://github.com/Sakuracio) 提供__
|
|||||||
|
|
||||||
### 2022/6/3
|
### 2022/6/3
|
||||||
|
|
||||||
* 修复了webUI插件相关API问题
|
|
||||||
* 插件仓库在已安装插件边上会提示\[已安装]
|
* 插件仓库在已安装插件边上会提示\[已安装]
|
||||||
* 修复ShopRegister kwargs某些字段无效
|
* 修复ShopRegister kwargs某些字段无效
|
||||||
* 调整了一下查看所有请求中的年龄绘制 [@pull/745](https://github.com/HibiKier/zhenxun_bot/pull/745)
|
* 调整了一下查看所有请求中的年龄绘制 [@pull/745](https://github.com/HibiKier/zhenxun_bot/pull/745)
|
||||||
@@ -284,7 +327,6 @@ __Docker 最新版本由 [Sakuracio](https://github.com/Sakuracio) 提供__
|
|||||||
* 新增自动更新插件```UPDATE_REMIND```:新版本提醒,原配置项```AUTO_UPDATE_ZHENXUN```改为自动更新升级
|
* 新增自动更新插件```UPDATE_REMIND```:新版本提醒,原配置项```AUTO_UPDATE_ZHENXUN```改为自动更新升级
|
||||||
* black_word新增当群权限为-1时不再检测该群
|
* black_word新增当群权限为-1时不再检测该群
|
||||||
* 修复非超级用户绑定原神cookie会被black_word阻拦
|
* 修复非超级用户绑定原神cookie会被black_word阻拦
|
||||||
* 修复webui中plugins2setting修改时会改变plugins2setting.cmd为字符串
|
|
||||||
* 修复微博热搜报错,发红包小bug [@pull/688](https://github.com/HibiKier/zhenxun_bot/pull/688)
|
* 修复微博热搜报错,发红包小bug [@pull/688](https://github.com/HibiKier/zhenxun_bot/pull/688)
|
||||||
* 更多的中文提示
|
* 更多的中文提示
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
__version__: v0.1.5.9
|
__version__: v0.1.6.0
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from nonebot import on_message
|
|||||||
from services.log import logger
|
from services.log import logger
|
||||||
from models.group_info import GroupInfo
|
from models.group_info import GroupInfo
|
||||||
from models.friend_user import FriendUser
|
from models.friend_user import FriendUser
|
||||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
from nonebot.adapters.onebot.v11 import ActionFailed
|
||||||
from configs.config import NICKNAME, Config
|
from configs.config import NICKNAME, Config
|
||||||
from utils.manager import group_manager
|
from utils.manager import group_manager
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -107,6 +107,7 @@ async def _():
|
|||||||
group_info["group_name"],
|
group_info["group_name"],
|
||||||
group_info["max_member_count"],
|
group_info["max_member_count"],
|
||||||
group_info["member_count"],
|
group_info["member_count"],
|
||||||
|
1
|
||||||
)
|
)
|
||||||
logger.info(f"自动更新群组 {g} 信息成功")
|
logger.info(f"自动更新群组 {g} 信息成功")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ from datetime import datetime
|
|||||||
from services.log import logger
|
from services.log import logger
|
||||||
from nonebot.adapters.onebot.v11 import (
|
from nonebot.adapters.onebot.v11 import (
|
||||||
Bot,
|
Bot,
|
||||||
|
ActionFailed,
|
||||||
GroupIncreaseNoticeEvent,
|
GroupIncreaseNoticeEvent,
|
||||||
GroupDecreaseNoticeEvent,
|
GroupDecreaseNoticeEvent,
|
||||||
)
|
)
|
||||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
|
||||||
from utils.manager import group_manager, plugins2settings_manager, requests_manager
|
from utils.manager import group_manager, plugins2settings_manager, requests_manager
|
||||||
from configs.config import NICKNAME
|
from configs.config import NICKNAME
|
||||||
from models.group_info import GroupInfo
|
from models.group_info import GroupInfo
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
from nonebot.matcher import Matcher
|
from nonebot.matcher import Matcher
|
||||||
from nonebot.message import run_preprocessor, run_postprocessor, IgnoredException
|
from nonebot.message import run_preprocessor, run_postprocessor, IgnoredException
|
||||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
|
||||||
from models.friend_user import FriendUser
|
from models.friend_user import FriendUser
|
||||||
from models.group_member_info import GroupInfoUser
|
from models.group_member_info import GroupInfoUser
|
||||||
from models.bag_user import BagUser
|
from models.bag_user import BagUser
|
||||||
@@ -23,6 +22,7 @@ from nonebot.typing import T_State
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
from nonebot.adapters.onebot.v11 import (
|
from nonebot.adapters.onebot.v11 import (
|
||||||
Bot,
|
Bot,
|
||||||
|
ActionFailed,
|
||||||
MessageEvent,
|
MessageEvent,
|
||||||
GroupMessageEvent,
|
GroupMessageEvent,
|
||||||
PokeNotifyEvent,
|
PokeNotifyEvent,
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
from nonebot.matcher import Matcher
|
from nonebot.matcher import Matcher
|
||||||
from nonebot.message import run_preprocessor, IgnoredException
|
from nonebot.message import run_preprocessor, IgnoredException
|
||||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
|
||||||
from nonebot.typing import T_State
|
from nonebot.typing import T_State
|
||||||
from nonebot.adapters.onebot.v11 import (
|
from nonebot.adapters.onebot.v11 import (
|
||||||
Bot,
|
Bot,
|
||||||
Event,
|
Event,
|
||||||
MessageEvent,
|
MessageEvent,
|
||||||
|
ActionFailed,
|
||||||
PokeNotifyEvent,
|
PokeNotifyEvent,
|
||||||
GroupMessageEvent,
|
GroupMessageEvent,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
from nonebot.matcher import Matcher
|
from nonebot.matcher import Matcher
|
||||||
from nonebot.message import run_preprocessor, IgnoredException
|
from nonebot.message import run_preprocessor, IgnoredException
|
||||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
|
||||||
from nonebot.typing import T_State
|
from nonebot.typing import T_State
|
||||||
from nonebot.adapters.onebot.v11 import (
|
from nonebot.adapters.onebot.v11 import (
|
||||||
Bot,
|
Bot,
|
||||||
|
ActionFailed,
|
||||||
MessageEvent,
|
MessageEvent,
|
||||||
GroupMessageEvent,
|
GroupMessageEvent,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from nonebot import on_request, on_message
|
from nonebot import on_request, on_message
|
||||||
from nonebot.adapters.onebot.v11 import (
|
from nonebot.adapters.onebot.v11 import (
|
||||||
Bot,
|
Bot,
|
||||||
|
ActionFailed,
|
||||||
FriendRequestEvent,
|
FriendRequestEvent,
|
||||||
GroupRequestEvent,
|
GroupRequestEvent,
|
||||||
MessageEvent,
|
MessageEvent,
|
||||||
@@ -8,7 +9,6 @@ from nonebot.adapters.onebot.v11 import (
|
|||||||
from models.friend_user import FriendUser
|
from models.friend_user import FriendUser
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from configs.config import NICKNAME, Config
|
from configs.config import NICKNAME, Config
|
||||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
|
||||||
from utils.manager import requests_manager
|
from utils.manager import requests_manager
|
||||||
from models.group_info import GroupInfo
|
from models.group_info import GroupInfo
|
||||||
from utils.utils import scheduler
|
from utils.utils import scheduler
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ __plugin_des__ = "区区昵称,才不想叫呢!"
|
|||||||
__plugin_cmd__ = ["以后叫我 [昵称]", f"{NICKNAME}我是谁"]
|
__plugin_cmd__ = ["以后叫我 [昵称]", f"{NICKNAME}我是谁"]
|
||||||
__plugin_version__ = 0.1
|
__plugin_version__ = 0.1
|
||||||
__plugin_author__ = "HibiKier"
|
__plugin_author__ = "HibiKier"
|
||||||
|
__plugin_settings__ = {
|
||||||
|
"level": 5,
|
||||||
|
"default_status": True,
|
||||||
|
"limit_superuser": False,
|
||||||
|
"cmd": ["昵称", "昵称系统"],
|
||||||
|
}
|
||||||
__plugin_configs__ = {
|
__plugin_configs__ = {
|
||||||
"BLACK_WORD": {
|
"BLACK_WORD": {
|
||||||
"value": ["爸", "爹", "爷", "父亲"],
|
"value": ["爸", "爹", "爷", "父亲"],
|
||||||
@@ -57,8 +63,9 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
|||||||
await nickname.finish("笨蛋!休想占用我的名字!#", at_sender=True)
|
await nickname.finish("笨蛋!休想占用我的名字!#", at_sender=True)
|
||||||
_tmp = ""
|
_tmp = ""
|
||||||
black_word = Config.get_config("nickname", "BLACK_WORD")
|
black_word = Config.get_config("nickname", "BLACK_WORD")
|
||||||
for x in msg:
|
if black_word:
|
||||||
_tmp += "*" if x in black_word else x
|
for x in msg:
|
||||||
|
_tmp += "*" if x in black_word else x
|
||||||
msg = _tmp
|
msg = _tmp
|
||||||
if isinstance(event, GroupMessageEvent):
|
if isinstance(event, GroupMessageEvent):
|
||||||
if await GroupInfoUser.set_group_member_nickname(
|
if await GroupInfoUser.set_group_member_nickname(
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ usage:
|
|||||||
卸载插件 [name/id]
|
卸载插件 [name/id]
|
||||||
""".strip()
|
""".strip()
|
||||||
__plugin_des__ = "从真寻适配仓库中下载插件"
|
__plugin_des__ = "从真寻适配仓库中下载插件"
|
||||||
__plugin_cmd__ = [""]
|
__plugin_cmd__ = ["查看插件仓库", "更新插件仓库", "安装插件 [name/id]", "卸载插件 [name/id]"]
|
||||||
__plugin_version__ = 0.1
|
__plugin_version__ = 0.1
|
||||||
__plugin_author__ = "HibiKier"
|
__plugin_author__ = "HibiKier"
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ async def install_plugin(name: str) -> str:
|
|||||||
json.dump(data[name], f, ensure_ascii=False, indent=4)
|
json.dump(data[name], f, ensure_ascii=False, indent=4)
|
||||||
logger.debug("移动插件文件夹完成...")
|
logger.debug("移动插件文件夹完成...")
|
||||||
logger.info(f"成功安装插件 {name} 成功!\n{tmp}")
|
logger.info(f"成功安装插件 {name} 成功!\n{tmp}")
|
||||||
return f"成功安装插件 {name},请重启bot!"
|
return f"成功安装插件 {name},请重启真寻!"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"安装插件 {name} 失败 {type(e)}:{e}")
|
logger.error(f"安装插件 {name} 失败 {type(e)}:{e}")
|
||||||
return f"安装插件 {name} 失败 {type(e)}:{e}"
|
return f"安装插件 {name} 失败 {type(e)}:{e}"
|
||||||
@@ -130,12 +130,17 @@ async def show_plugin_repo() -> Union[int, str]:
|
|||||||
"download_url": plugin_info[key]["download_url"],
|
"download_url": plugin_info[key]["download_url"],
|
||||||
"github_url": plugin_info[key]["github_url"],
|
"github_url": plugin_info[key]["github_url"],
|
||||||
}
|
}
|
||||||
|
status = ""
|
||||||
|
version = ""
|
||||||
|
if key in load_plugin_list:
|
||||||
|
status = "<f font_color=#1a7e30>[已安装]</f>"
|
||||||
|
version = f"<f font_color=#1a7e30>[{plugins_manager.get_data()[key]['version']}]</f>"
|
||||||
s = (
|
s = (
|
||||||
f'id:{i+1}\n名称:{plugin_info[key]["plugin_name"]}'
|
f'id:{i+1}\n名称:{plugin_info[key]["plugin_name"]}'
|
||||||
f' \t\t{"<f font_color=#1a7e30>[已安装]</f>" if key in load_plugin_list else ""}\n'
|
f' \t\t{status}\n'
|
||||||
f"模块:{key}\n"
|
f"模块:{key}\n"
|
||||||
f'作者:{plugin_info[key]["author"]}\n'
|
f'作者:{plugin_info[key]["author"]}\n'
|
||||||
f'版本:{plugin_info[key]["version"]}\n'
|
f'版本:{plugin_info[key]["version"]} \t\t{version}\n'
|
||||||
f'简介:{plugin_info[key]["introduction"]}\n'
|
f'简介:{plugin_info[key]["introduction"]}\n'
|
||||||
f"-------------------"
|
f"-------------------"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GROUP, GroupMessageEvent, Message
|
from nonebot.adapters.onebot.v11 import (
|
||||||
|
Bot,
|
||||||
|
MessageEvent,
|
||||||
|
GROUP,
|
||||||
|
GroupMessageEvent,
|
||||||
|
Message,
|
||||||
|
ActionFailed,
|
||||||
|
)
|
||||||
from nonebot import on_command, on_regex
|
from nonebot import on_command, on_regex
|
||||||
from nonebot.permission import SUPERUSER
|
from nonebot.permission import SUPERUSER
|
||||||
from nonebot.typing import T_State
|
from nonebot.typing import T_State
|
||||||
@@ -8,7 +15,6 @@ from utils.manager import group_manager, plugins2settings_manager
|
|||||||
from models.group_info import GroupInfo
|
from models.group_info import GroupInfo
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
from configs.config import NICKNAME
|
from configs.config import NICKNAME
|
||||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
|
||||||
from nonebot.params import Command, CommandArg
|
from nonebot.params import Command, CommandArg
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
@@ -137,9 +143,7 @@ async def _():
|
|||||||
async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
|
async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
|
||||||
cmd = cmd[0]
|
cmd = cmd[0]
|
||||||
msg = arg.extract_plain_text().strip().split()
|
msg = arg.extract_plain_text().strip().split()
|
||||||
all_group = [
|
all_group = [g["group_id"] for g in await bot.get_group_list()]
|
||||||
g["group_id"] for g in await bot.get_group_list()
|
|
||||||
]
|
|
||||||
group_list = []
|
group_list = []
|
||||||
for group in msg:
|
for group in msg:
|
||||||
if is_number(group) and int(group) in all_group:
|
if is_number(group) and int(group) in all_group:
|
||||||
@@ -151,9 +155,7 @@ async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandAr
|
|||||||
else:
|
else:
|
||||||
group_manager.delete_group_white_list(group)
|
group_manager.delete_group_white_list(group)
|
||||||
group_list = [str(x) for x in group_list]
|
group_list = [str(x) for x in group_list]
|
||||||
await manager_group_whitelist.send(
|
await manager_group_whitelist.send("已成功将 " + "\n".join(group_list) + " " + cmd)
|
||||||
"已成功将 " + "\n".join(group_list) + " " + cmd
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
await manager_group_whitelist.send(f"添加失败,请检查{NICKNAME}是否已加入这些群聊或重复添加/删除群白单名")
|
await manager_group_whitelist.send(f"添加失败,请检查{NICKNAME}是否已加入这些群聊或重复添加/删除群白单名")
|
||||||
|
|
||||||
@@ -199,6 +201,4 @@ async def _(bot: Bot, cmd: Tuple[str, ...] = Command(), arg: Message = CommandAr
|
|||||||
else:
|
else:
|
||||||
if await GroupInfo.get_group_info(group_id):
|
if await GroupInfo.get_group_info(group_id):
|
||||||
await GroupInfo.set_group_flag(group_id, 0)
|
await GroupInfo.set_group_flag(group_id, 0)
|
||||||
await group_auth.send(
|
await group_auth.send(f"已为 {group_id} {cmd[:2]}群认证..")
|
||||||
f'已为 {group_id} {cmd[:2]}群认证..'
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -94,12 +94,13 @@ class ConfigsManager:
|
|||||||
del self._data[module]
|
del self._data[module]
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def set_config(self, module: str, key: str, value: str):
|
def set_config(self, module: str, key: str, value: Any , save_simple_data: bool = False):
|
||||||
"""
|
"""
|
||||||
设置配置值
|
设置配置值
|
||||||
:param module: 模块名
|
:param module: 模块名
|
||||||
:param key: 配置名称
|
:param key: 配置名称
|
||||||
:param value: 值
|
:param value: 值
|
||||||
|
:param save_simple_data: 同时保存至config.yaml
|
||||||
"""
|
"""
|
||||||
if module in self._data.keys():
|
if module in self._data.keys():
|
||||||
if (
|
if (
|
||||||
@@ -108,7 +109,7 @@ class ConfigsManager:
|
|||||||
):
|
):
|
||||||
self._data[module][key]["value"] = value
|
self._data[module][key]["value"] = value
|
||||||
self._simple_data[module][key] = value
|
self._simple_data[module][key] = value
|
||||||
self.save()
|
self.save(save_simple_data = save_simple_data)
|
||||||
|
|
||||||
def set_help(self, module: str, key: str, help_: str):
|
def set_help(self, module: str, key: str, help_: str):
|
||||||
"""
|
"""
|
||||||
@@ -122,7 +123,7 @@ class ConfigsManager:
|
|||||||
self._data[module][key]["help"] = help_
|
self._data[module][key]["help"] = help_
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def set_default_value(self, module: str, key: str, value: str):
|
def set_default_value(self, module: str, key: str, value: Any):
|
||||||
"""
|
"""
|
||||||
设置配置默认值
|
设置配置默认值
|
||||||
:param module: 模块名
|
:param module: 模块名
|
||||||
|
|||||||
@@ -228,12 +228,14 @@ async def send_sub_msg(rst: str, sub: BilibiliSub, bot: Bot):
|
|||||||
:param sub: BilibiliSub
|
:param sub: BilibiliSub
|
||||||
:param bot: Bot
|
:param bot: Bot
|
||||||
"""
|
"""
|
||||||
|
temp_group = []
|
||||||
if rst:
|
if rst:
|
||||||
for x in sub.sub_users.split(",")[:-1]:
|
for x in sub.sub_users.split(",")[:-1]:
|
||||||
try:
|
try:
|
||||||
if ":" in x:
|
if ":" in x and x.split(":")[1] not in temp_group:
|
||||||
|
temp_group.append(x.split(":")[1])
|
||||||
await bot.send_group_msg(
|
await bot.send_group_msg(
|
||||||
group_id=int(x.split(":")[1]), message=Message(rst)
|
group_id=int(x.split(":")[1]), message=Message(rst)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
await bot.send_private_msg(user_id=int(x), message=Message(rst))
|
await bot.send_private_msg(user_id=int(x), message=Message(rst))
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from configs.config import Config
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
from models.ban_user import BanUser
|
from models.ban_user import BanUser
|
||||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
from nonebot.adapters.onebot.v11 import ActionFailed
|
||||||
from models.group_member_info import GroupInfoUser
|
from models.group_member_info import GroupInfoUser
|
||||||
from utils.http_utils import AsyncHttpx
|
from utils.http_utils import AsyncHttpx
|
||||||
import random
|
import random
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import platform
|
|||||||
# asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
# asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
||||||
|
|
||||||
|
|
||||||
url = "http://www.eclzz.win"
|
url = "http://www.eclzz.one/"
|
||||||
|
|
||||||
|
|
||||||
async def get_bt_info(keyword: str, page: int):
|
async def get_bt_info(keyword: str, page: int):
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from .data_source import check_update, get_latest_version_data
|
|||||||
from services.log import logger
|
from services.log import logger
|
||||||
from utils.utils import scheduler, get_bot
|
from utils.utils import scheduler, get_bot
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from configs.config import Config
|
from configs.config import NICKNAME, Config
|
||||||
from nonebot.rule import to_me
|
from nonebot.rule import to_me
|
||||||
from nonebot.params import ArgStr
|
from nonebot.params import ArgStr
|
||||||
import platform
|
import platform
|
||||||
@@ -71,18 +71,18 @@ async def _(bot: Bot):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@restart.handle()
|
|
||||||
async def _():
|
|
||||||
if str(platform.system()).lower() == "windows":
|
|
||||||
await restart.finish("暂无windows重启脚本...")
|
|
||||||
|
|
||||||
|
@restart.got("flag", prompt=f"确定是否重启{NICKNAME}?确定请回复[是|好|确定](重启失败咱们将失去联系,请谨慎!)")
|
||||||
@restart.got("flag", prompt="确定是否重启真寻?确定请回复[是|好|确定](重启失败咱们将失去联系,请谨慎!)")
|
|
||||||
async def _(flag: str = ArgStr("flag")):
|
async def _(flag: str = ArgStr("flag")):
|
||||||
if flag.lower() in ["true", "是", "好", "确定", "确定是"]:
|
if flag.lower() in ["true", "是", "好", "确定", "确定是"]:
|
||||||
await restart.send("开始重启真寻..请稍等...")
|
await restart.send(f"开始重启{NICKNAME}..请稍等...")
|
||||||
open("is_restart", "w")
|
open("is_restart", "w")
|
||||||
os.system("./restart.sh")
|
if str(platform.system()).lower() == "windows":
|
||||||
|
import sys
|
||||||
|
python = sys.executable
|
||||||
|
os.execl(python, python, *sys.argv)
|
||||||
|
else:
|
||||||
|
os.system("./restart.sh")
|
||||||
else:
|
else:
|
||||||
await restart.send("已取消操作...")
|
await restart.send("已取消操作...")
|
||||||
|
|
||||||
@@ -126,5 +126,5 @@ async def _():
|
|||||||
if code == 200:
|
if code == 200:
|
||||||
await bot.send_private_msg(
|
await bot.send_private_msg(
|
||||||
user_id=int(list(bot.config.superusers)[0]),
|
user_id=int(list(bot.config.superusers)[0]),
|
||||||
message=f"更新完毕,请重启真寻....",
|
message=f"更新完毕,请重启{NICKNAME}....",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ def _file_handle(latest_version: str) -> str:
|
|||||||
if backup_file.exists():
|
if backup_file.exists():
|
||||||
backup_file.unlink()
|
backup_file.unlink()
|
||||||
if file not in [config_file, config_path_file]:
|
if file not in [config_file, config_path_file]:
|
||||||
os.rename(file.absolute(), backup_file.absolute())
|
shutil.move(file.absolute(), backup_file.absolute())
|
||||||
else:
|
else:
|
||||||
with open(file, "r", encoding="utf8") as rf:
|
with open(file, "r", encoding="utf8") as rf:
|
||||||
data = rf.read()
|
data = rf.read()
|
||||||
@@ -174,7 +174,7 @@ def _file_handle(latest_version: str) -> str:
|
|||||||
old_file = Path() / file
|
old_file = Path() / file
|
||||||
if old_file not in [config_file, config_path_file] and file != "configs":
|
if old_file not in [config_file, config_path_file] and file != "configs":
|
||||||
if not old_file.exists() and new_file.exists():
|
if not old_file.exists() and new_file.exists():
|
||||||
os.rename(new_file.absolute(), old_file.absolute())
|
shutil.move(new_file.absolute(), old_file.absolute())
|
||||||
logger.info(f"已更新文件:{file}")
|
logger.info(f"已更新文件:{file}")
|
||||||
# except Exception as e:
|
# except Exception as e:
|
||||||
# error = f'{type(e)}:{e}'
|
# error = f'{type(e)}:{e}'
|
||||||
|
|||||||
@@ -149,12 +149,12 @@ async def _remind(user_id: int, uid: str):
|
|||||||
if current_resin < max_resin:
|
if current_resin < max_resin:
|
||||||
user_manager.remove(uid)
|
user_manager.remove(uid)
|
||||||
user_manager.remove_overflow(uid)
|
user_manager.remove_overflow(uid)
|
||||||
if current_resin <= max_resin - 40:
|
if current_resin < max_resin - 40:
|
||||||
next_time = now + timedelta(minutes=(max_resin - 40 - current_resin + 1) * 8, seconds=10)
|
next_time = now + timedelta(minutes=(max_resin - 40 - current_resin) * 8)
|
||||||
elif max_resin - 40 < current_resin <= max_resin - 20:
|
elif max_resin - 40 <= current_resin < max_resin - 20:
|
||||||
next_time = now + timedelta(minutes=(max_resin - 20 - current_resin + 1) * 8, seconds=10)
|
next_time = now + timedelta(minutes=(max_resin - 20 - current_resin) * 8)
|
||||||
elif max_resin - 20 < current_resin < max_resin:
|
elif max_resin - 20 <= current_resin < max_resin:
|
||||||
next_time = now + timedelta(minutes=(max_resin - current_resin) * 8, seconds=10)
|
next_time = now + timedelta(minutes=(max_resin - current_resin) * 8)
|
||||||
elif current_resin == max_resin:
|
elif current_resin == max_resin:
|
||||||
custom_overflow_resin = Config.get_config("resin_remind", "CUSTOM_RESIN_OVERFLOW_REMIND")
|
custom_overflow_resin = Config.get_config("resin_remind", "CUSTOM_RESIN_OVERFLOW_REMIND")
|
||||||
if user_manager.is_overflow(uid) and custom_overflow_resin:
|
if user_manager.is_overflow(uid) and custom_overflow_resin:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from nonebot import on_command, on_notice
|
from nonebot import on_command, on_notice
|
||||||
from nonebot.adapters.onebot.v11 import (
|
from nonebot.adapters.onebot.v11 import (
|
||||||
Bot,
|
Bot,
|
||||||
|
ActionFailed,
|
||||||
GroupMessageEvent,
|
GroupMessageEvent,
|
||||||
PokeNotifyEvent,
|
PokeNotifyEvent,
|
||||||
Message
|
Message
|
||||||
@@ -24,7 +25,6 @@ from nonebot.rule import to_me
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from configs.config import NICKNAME
|
from configs.config import NICKNAME
|
||||||
from apscheduler.jobstores.base import JobLookupError
|
from apscheduler.jobstores.base import JobLookupError
|
||||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
|
||||||
from nonebot.params import CommandArg
|
from nonebot.params import CommandArg
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
|
|||||||
+14
-11
@@ -1,8 +1,7 @@
|
|||||||
from nonebot import on_message, on_command
|
from nonebot import on_message, on_command
|
||||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message
|
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message, ActionFailed
|
||||||
from nonebot.adapters.onebot.v11.permission import GROUP
|
from nonebot.adapters.onebot.v11.permission import GROUP
|
||||||
from utils.utils import is_number, get_message_img, get_message_text
|
from utils.utils import is_number, get_message_img, get_message_text
|
||||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
|
||||||
from configs.path_config import DATA_PATH, TEMP_PATH
|
from configs.path_config import DATA_PATH, TEMP_PATH
|
||||||
from utils.image_utils import get_img_hash
|
from utils.image_utils import get_img_hash
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
@@ -72,9 +71,7 @@ def save_data():
|
|||||||
|
|
||||||
|
|
||||||
async def download_img_and_hash(url, group_id) -> str:
|
async def download_img_and_hash(url, group_id) -> str:
|
||||||
if await AsyncHttpx.download_file(
|
if await AsyncHttpx.download_file(url, TEMP_PATH / f"mute_{group_id}_img.jpg"):
|
||||||
url, TEMP_PATH / f"mute_{group_id}_img.jpg"
|
|
||||||
):
|
|
||||||
return str(get_img_hash(TEMP_PATH / f"mute_{group_id}_img.jpg"))
|
return str(get_img_hash(TEMP_PATH / f"mute_{group_id}_img.jpg"))
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
@@ -133,11 +130,19 @@ async def _(bot: Bot, event: GroupMessageEvent):
|
|||||||
|
|
||||||
|
|
||||||
@mute_setting.handle()
|
@mute_setting.handle()
|
||||||
async def _(event: GroupMessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
|
async def _(
|
||||||
|
event: GroupMessageEvent,
|
||||||
|
cmd: Tuple[str, ...] = Command(),
|
||||||
|
arg: Message = CommandArg(),
|
||||||
|
):
|
||||||
global mute_data
|
global mute_data
|
||||||
group_id = str(event.group_id)
|
group_id = str(event.group_id)
|
||||||
if not mute_data.get(group_id):
|
if not mute_data.get(group_id):
|
||||||
mute_data[group_id] = {"count": Config.get_config("mute", "MUTE_DEFAULT_COUNT"), "time": Config.get_config("mute", "MUTE_DEFAULT_TIME"), "duration": Config.get_config("mute", "MUTE_DEFAULT_DURATION")}
|
mute_data[group_id] = {
|
||||||
|
"count": Config.get_config("mute", "MUTE_DEFAULT_COUNT"),
|
||||||
|
"time": Config.get_config("mute", "MUTE_DEFAULT_TIME"),
|
||||||
|
"duration": Config.get_config("mute", "MUTE_DEFAULT_DURATION"),
|
||||||
|
}
|
||||||
msg = arg.extract_plain_text().strip()
|
msg = arg.extract_plain_text().strip()
|
||||||
if cmd[0] == "刷屏检测设置":
|
if cmd[0] == "刷屏检测设置":
|
||||||
await mute_setting.finish(
|
await mute_setting.finish(
|
||||||
@@ -157,8 +162,6 @@ async def _(event: GroupMessageEvent, cmd: Tuple[str, ...] = Command(), arg: Mes
|
|||||||
if cmd[0] == "设置刷屏禁言时长":
|
if cmd[0] == "设置刷屏禁言时长":
|
||||||
mute_data[group_id]["duration"] = int(msg)
|
mute_data[group_id]["duration"] = int(msg)
|
||||||
msg += " 分钟"
|
msg += " 分钟"
|
||||||
await mute_setting.send(f'刷屏检测:{cmd[0]}为 {msg}')
|
await mute_setting.send(f"刷屏检测:{cmd[0]}为 {msg}")
|
||||||
logger.info(
|
logger.info(f"USER {event.user_id} GROUP {group_id} {cmd[0]}:{msg}")
|
||||||
f'USER {event.user_id} GROUP {group_id} {cmd[0]}:{msg}'
|
|
||||||
)
|
|
||||||
save_data()
|
save_data()
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from .models.open_cases_user import OpenCasesUser
|
|||||||
from services.log import logger
|
from services.log import logger
|
||||||
from utils.utils import get_bot, cn2py
|
from utils.utils import get_bot, cn2py
|
||||||
from asyncio.exceptions import TimeoutError
|
from asyncio.exceptions import TimeoutError
|
||||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
from nonebot.adapters.onebot.v11 import ActionFailed
|
||||||
from configs.config import Config
|
from configs.config import Config
|
||||||
from utils.manager import group_manager
|
from utils.manager import group_manager
|
||||||
from .config import *
|
from .config import *
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
# from nonebot import on_message
|
# from nonebot import on_message
|
||||||
# from services.log import logger
|
# from services.log import logger
|
||||||
# from nonebot.adapters.onebot.v11 import GroupMessageEvent
|
# from nonebot.adapters.onebot.v11 import GroupMessageEvent, ActionFailed
|
||||||
# from utils.utils import get_message_json, get_local_proxy, is_number, get_message_text
|
# from utils.utils import get_message_json, get_local_proxy, is_number, get_message_text
|
||||||
# from nonebot.adapters.onebot.v11.permission import GROUP
|
# from nonebot.adapters.onebot.v11.permission import GROUP
|
||||||
# from utils.message_builder import image
|
# from utils.message_builder import image
|
||||||
# from nonebot.adapters.onebot.v11.exception import ActionFailed
|
|
||||||
# from utils.image_utils import BuildImage
|
# from utils.image_utils import BuildImage
|
||||||
# from utils.browser import get_browser
|
# from utils.browser import get_browser
|
||||||
# from configs.path_config import IMAGE_PATH
|
# from configs.path_config import IMAGE_PATH
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from asyncio.locks import Semaphore
|
|||||||
from asyncio.exceptions import TimeoutError
|
from asyncio.exceptions import TimeoutError
|
||||||
from ._model.pixiv import Pixiv
|
from ._model.pixiv import Pixiv
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
from utils.utils import change_pixiv_image_links
|
from utils.utils import change_pixiv_image_links, change_img_md5
|
||||||
from utils.image_utils import BuildImage
|
from utils.image_utils import BuildImage
|
||||||
from utils.http_utils import AsyncHttpx
|
from utils.http_utils import AsyncHttpx
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
@@ -238,6 +238,7 @@ async def get_image(img_url: str, user_id: int) -> Optional[str]:
|
|||||||
TEMP_PATH / f"pix_{user_id}_{img_url.split('/')[-1][:-4]}.jpg", "wb"
|
TEMP_PATH / f"pix_{user_id}_{img_url.split('/')[-1][:-4]}.jpg", "wb"
|
||||||
) as f:
|
) as f:
|
||||||
await f.write(response.content)
|
await f.write(response.content)
|
||||||
|
change_img_md5(TEMP_PATH / f"pix_{user_id}_{img_url.split('/')[-1][:-4]}.jpg")
|
||||||
return TEMP_PATH / f"pix_{user_id}_{img_url.split('/')[-1][:-4]}.jpg"
|
return TEMP_PATH / f"pix_{user_id}_{img_url.split('/')[-1][:-4]}.jpg"
|
||||||
except TimeoutError:
|
except TimeoutError:
|
||||||
logger.warning(f"PIX:{img_url} 图片下载超时...")
|
logger.warning(f"PIX:{img_url} 图片下载超时...")
|
||||||
|
|||||||
@@ -20,6 +20,11 @@ usage:
|
|||||||
pix ?*[tags]: 通过 tag 获取相似图片,不含tag时随机抽取
|
pix ?*[tags]: 通过 tag 获取相似图片,不含tag时随机抽取
|
||||||
pid [uid]: 通过uid获取图片
|
pid [uid]: 通过uid获取图片
|
||||||
pix pid[pid]: 查看图库中指定pid图片
|
pix pid[pid]: 查看图库中指定pid图片
|
||||||
|
示例:pix 萝莉 白丝
|
||||||
|
示例:pix 萝莉 白丝 10 (10为数量)
|
||||||
|
示例:pix #02 (当tag只有1个tag且为数字时,使用#标记,否则将被判定为数量)
|
||||||
|
示例:pix 34582394 (查询指定uid图片)
|
||||||
|
示例:pix pid:12323423 (查询指定pid图片)
|
||||||
""".strip()
|
""".strip()
|
||||||
__plugin_superuser_usage__ = """
|
__plugin_superuser_usage__ = """
|
||||||
usage:
|
usage:
|
||||||
@@ -88,9 +93,12 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
|||||||
nsfw_tag == 2 and not Config.get_config("pix", "ALLOW_GROUP_R18")
|
nsfw_tag == 2 and not Config.get_config("pix", "ALLOW_GROUP_R18")
|
||||||
):
|
):
|
||||||
await pix.finish("你不能看这些噢,这些都是是留给管理员看的...")
|
await pix.finish("你不能看这些噢,这些都是是留给管理员看的...")
|
||||||
if n := len(x) == 1 and is_number(x[0]) and int(x[0]) < 100:
|
if (n := len(x)) == 1:
|
||||||
num = int(x[0])
|
if is_number(x[0]) and int(x[0]) < 100:
|
||||||
keyword = ""
|
num = int(x[0])
|
||||||
|
keyword = ""
|
||||||
|
elif x[0].startswith("#"):
|
||||||
|
keyword = x[0][1:]
|
||||||
elif n > 1:
|
elif n > 1:
|
||||||
if is_number(x[-1]):
|
if is_number(x[-1]):
|
||||||
num = int(x[-1])
|
num = int(x[-1])
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GroupMessageEvent, Message
|
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GroupMessageEvent, Message, NetworkError
|
||||||
from nonebot.matcher import Matcher
|
from nonebot.matcher import Matcher
|
||||||
from nonebot.params import CommandArg
|
from nonebot.params import CommandArg
|
||||||
from nonebot import on_command
|
from nonebot import on_command
|
||||||
from utils.utils import is_number
|
from utils.utils import is_number
|
||||||
from .data_source import get_pixiv_urls, download_pixiv_imgs, search_pixiv_urls
|
from .data_source import get_pixiv_urls, download_pixiv_imgs, search_pixiv_urls
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
from nonebot.adapters.onebot.v11.exception import NetworkError
|
|
||||||
from asyncio.exceptions import TimeoutError
|
from asyncio.exceptions import TimeoutError
|
||||||
from utils.message_builder import custom_forward_msg
|
from utils.message_builder import custom_forward_msg
|
||||||
from configs.config import Config
|
from configs.config import Config
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from configs.path_config import IMAGE_PATH
|
from configs.path_config import IMAGE_PATH
|
||||||
from utils.message_builder import image
|
from utils.message_builder import image
|
||||||
|
from utils.utils import change_img_md5
|
||||||
from asyncio.exceptions import TimeoutError
|
from asyncio.exceptions import TimeoutError
|
||||||
from configs.config import Config
|
from configs.config import Config
|
||||||
from utils.http_utils import AsyncHttpx
|
from utils.http_utils import AsyncHttpx
|
||||||
@@ -143,6 +144,7 @@ async def download_pixiv_imgs(
|
|||||||
file,
|
file,
|
||||||
timeout=Config.get_config("pixiv_rank_search", "TIMEOUT"),
|
timeout=Config.get_config("pixiv_rank_search", "TIMEOUT"),
|
||||||
):
|
):
|
||||||
|
change_img_md5(file)
|
||||||
if forward_msg_index is not None:
|
if forward_msg_index is not None:
|
||||||
result += image(
|
result += image(
|
||||||
f"{user_id}_{forward_msg_index}_{index}_pixiv.jpg",
|
f"{user_id}_{forward_msg_index}_{index}_pixiv.jpg",
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from services import logger
|
||||||
from utils.http_utils import AsyncHttpx
|
from utils.http_utils import AsyncHttpx
|
||||||
from configs.config import Config
|
from configs.config import Config
|
||||||
from configs.path_config import TEMP_PATH
|
from configs.path_config import TEMP_PATH
|
||||||
@@ -39,12 +40,18 @@ async def get_saucenao_image(url: str) -> Union[str, List[str]]:
|
|||||||
):
|
):
|
||||||
msg_list.append(image(TEMP_PATH / f"saucenao_search_{index}.jpg"))
|
msg_list.append(image(TEMP_PATH / f"saucenao_search_{index}.jpg"))
|
||||||
for info in data:
|
for info in data:
|
||||||
similarity = info["header"]["similarity"]
|
try:
|
||||||
tmp = f"相似度:{similarity}%\n"
|
similarity = info["header"]["similarity"]
|
||||||
for x in info["data"].keys():
|
tmp = f"相似度:{similarity}%\n"
|
||||||
if x != "ext_urls":
|
for x in info["data"].keys():
|
||||||
tmp += f"{x}:{info['data'][x]}\n"
|
if x != "ext_urls":
|
||||||
if "source" not in info["data"].keys():
|
tmp += f"{x}:{info['data'][x]}\n"
|
||||||
tmp += f'source:{info["data"]["ext_urls"][0]}\n'
|
try:
|
||||||
msg_list.append(tmp[:-1])
|
if "source" not in info["data"].keys():
|
||||||
|
tmp += f'source:{info["data"]["ext_urls"][0]}\n'
|
||||||
|
except KeyError:
|
||||||
|
tmp += f'source:{info["header"]["thumbnail"]}\n'
|
||||||
|
msg_list.append(tmp[:-1])
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"识图获取图片信息发生错误 {type(e)}:{e}")
|
||||||
return msg_list
|
return msg_list
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ from utils.utils import (
|
|||||||
from nonebot.typing import T_State
|
from nonebot.typing import T_State
|
||||||
from nonebot.adapters.onebot.v11 import (
|
from nonebot.adapters.onebot.v11 import (
|
||||||
Bot,
|
Bot,
|
||||||
|
ActionFailed,
|
||||||
MessageEvent,
|
MessageEvent,
|
||||||
GroupMessageEvent,
|
GroupMessageEvent,
|
||||||
PrivateMessageEvent,
|
PrivateMessageEvent,
|
||||||
@@ -30,7 +31,6 @@ from .data_source import (
|
|||||||
add_data_to_database,
|
add_data_to_database,
|
||||||
get_setu_count,
|
get_setu_count,
|
||||||
)
|
)
|
||||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
|
||||||
from configs.config import Config, NICKNAME
|
from configs.config import Config, NICKNAME
|
||||||
from utils.manager import withdraw_message_manager
|
from utils.manager import withdraw_message_manager
|
||||||
from nonebot.params import CommandArg, Command, RegexGroup
|
from nonebot.params import CommandArg, Command, RegexGroup
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from configs.path_config import IMAGE_PATH, TEMP_PATH
|
|||||||
from utils.message_builder import image
|
from utils.message_builder import image
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
from utils.image_utils import get_img_hash, compressed_image
|
from utils.image_utils import get_img_hash, compressed_image
|
||||||
|
from utils.utils import change_img_md5
|
||||||
from asyncpg.exceptions import UniqueViolationError
|
from asyncpg.exceptions import UniqueViolationError
|
||||||
from asyncio.exceptions import TimeoutError
|
from asyncio.exceptions import TimeoutError
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
@@ -111,6 +112,7 @@ async def search_online_setu(
|
|||||||
path_ / f"{index}.jpg",
|
path_ / f"{index}.jpg",
|
||||||
)
|
)
|
||||||
logger.info(f"下载 lolicon 图片 {url_} 成功, id:{index}")
|
logger.info(f"下载 lolicon 图片 {url_} 成功, id:{index}")
|
||||||
|
change_img_md5(path_ / file_name)
|
||||||
return image(path_ / file_name), index
|
return image(path_ / file_name), index
|
||||||
except TimeoutError:
|
except TimeoutError:
|
||||||
pass
|
pass
|
||||||
@@ -128,6 +130,7 @@ async def check_local_exists_or_download(setu_image: Setu) -> "MessageSegment, i
|
|||||||
path_ = r18_path if setu_image.is_r18 else path
|
path_ = r18_path if setu_image.is_r18 else path
|
||||||
file = IMAGE_PATH / path_ / f"{setu_image.local_id}.jpg"
|
file = IMAGE_PATH / path_ / f"{setu_image.local_id}.jpg"
|
||||||
if file.exists():
|
if file.exists():
|
||||||
|
change_img_md5(file)
|
||||||
return image(f"{setu_image.local_id}.jpg", path_), 200
|
return image(f"{setu_image.local_id}.jpg", path_), 200
|
||||||
return await search_online_setu(setu_image.img_url, id_, path_)
|
return await search_online_setu(setu_image.img_url, id_, path_)
|
||||||
|
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ async def _(
|
|||||||
result += image(b64=pic2b64(img))
|
result += image(b64=pic2b64(img))
|
||||||
if method in ["模糊效果", "6"]:
|
if method in ["模糊效果", "6"]:
|
||||||
for i in range(index):
|
for i in range(index):
|
||||||
img = Image.open(TEMP_PATH / f"temp/{event.user_id}_{i}_update.png").filter(
|
img = Image.open(TEMP_PATH / f"{event.user_id}_{i}_update.png").filter(
|
||||||
ImageFilter.BLUR
|
ImageFilter.BLUR
|
||||||
)
|
)
|
||||||
result += image(b64=pic2b64(img))
|
result += image(b64=pic2b64(img))
|
||||||
|
|||||||
+25
-15
@@ -1,20 +1,30 @@
|
|||||||
from configs.config import Config as gConfig
|
from configs.config import Config as gConfig
|
||||||
from .api import *
|
from .api import *
|
||||||
from .auth import *
|
from .auth import *
|
||||||
|
from nonebot.matcher import Matcher
|
||||||
|
from nonebot.message import run_preprocessor, IgnoredException
|
||||||
gConfig.add_plugin_config(
|
from utils.manager import plugins2settings_manager
|
||||||
"web-ui",
|
from nonebot.typing import T_State
|
||||||
"username",
|
from nonebot.adapters.onebot.v11 import (
|
||||||
"admin",
|
Bot,
|
||||||
name="web-ui",
|
MessageEvent
|
||||||
help_="前端管理用户名"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
gConfig.add_plugin_config(
|
|
||||||
"web-ui",
|
gConfig.add_plugin_config("web-ui", "username", "admin", name="web-ui", help_="前端管理用户名")
|
||||||
"password",
|
|
||||||
None,
|
gConfig.add_plugin_config("web-ui", "password", None, name="web-ui", help_="前端管理密码")
|
||||||
name="web-ui",
|
|
||||||
help_="前端管理密码"
|
|
||||||
)
|
# 使用webui访问api后plugins2settings中的cmd字段将从list变为str
|
||||||
|
# 暂时找不到原因
|
||||||
|
# 先使用hook修复
|
||||||
|
@run_preprocessor
|
||||||
|
async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
|
||||||
|
for module in plugins2settings_manager.keys():
|
||||||
|
if isinstance(plugins2settings_manager.get_plugin_data(module).get("cmd"), str):
|
||||||
|
plugins2settings_manager.set_module_data(
|
||||||
|
module,
|
||||||
|
"cmd",
|
||||||
|
plugins2settings_manager.get_plugin_data(module).get("cmd").split(","),
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from pydantic import ValidationError
|
||||||
|
|
||||||
from configs.config import Config
|
from configs.config import Config
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
from utils.manager import (plugins2block_manager, plugins2cd_manager,
|
from utils.manager import (plugins2block_manager, plugins2cd_manager,
|
||||||
@@ -85,6 +87,10 @@ def _(type_: Optional[str], user: User = Depends(token_to_user)) -> Result:
|
|||||||
id_ += 1
|
id_ += 1
|
||||||
data["plugin_config"] = tmp
|
data["plugin_config"] = tmp
|
||||||
plugin_list.append(Plugin(**data))
|
plugin_list.append(Plugin(**data))
|
||||||
|
except (AttributeError, ValidationError) as e:
|
||||||
|
logger.error(
|
||||||
|
f"WEB_UI GET /webui/plugins model:{model} 发生错误 {type(e)}:{e}"
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(
|
logger.error(
|
||||||
f"WEB_UI GET /webui/plugins model:{model} 发生错误 {type(e)}:{e}"
|
f"WEB_UI GET /webui/plugins model:{model} 发生错误 {type(e)}:{e}"
|
||||||
@@ -137,6 +143,8 @@ def _(plugin: Plugin, user: User = Depends(token_to_user)) -> Result:
|
|||||||
else:
|
else:
|
||||||
if plugin.plugin_settings:
|
if plugin.plugin_settings:
|
||||||
for key, value in plugin.plugin_settings:
|
for key, value in plugin.plugin_settings:
|
||||||
|
if key == "cmd":
|
||||||
|
value = value.split(",")
|
||||||
plugins2settings_manager.set_module_data(plugin.model, key, value)
|
plugins2settings_manager.set_module_data(plugin.model, key, value)
|
||||||
if plugin.plugin_manager:
|
if plugin.plugin_manager:
|
||||||
for key, value in plugin.plugin_manager:
|
for key, value in plugin.plugin_manager:
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ async def login_get_token(form_data: OAuth2PasswordRequestForm = Depends()):
|
|||||||
token_data["token"].append(access_token)
|
token_data["token"].append(access_token)
|
||||||
if len(token_data["token"]) > 3:
|
if len(token_data["token"]) > 3:
|
||||||
token_data["token"] = token_data["token"][1:]
|
token_data["token"] = token_data["token"][1:]
|
||||||
|
with open(token_file, 'w', encoding="utf8") as f:
|
||||||
|
json.dump(token_data, f, ensure_ascii=False, indent=4)
|
||||||
return {"access_token": access_token, "token_type": "bearer"}
|
return {"access_token": access_token, "token_type": "bearer"}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ async def _(event: MessageEvent, arg: Message = CommandArg()):
|
|||||||
msg_sp = msg.split("<|>")
|
msg_sp = msg.split("<|>")
|
||||||
w, h = w2b.size
|
w, h = w2b.size
|
||||||
add_h, font_size = init_h_font_size(h)
|
add_h, font_size = init_h_font_size(h)
|
||||||
bg = BuildImage(w, h + add_h, color="black", font_size=font_size)
|
bg = BuildImage(w, h + add_h, color="black", font_size=int(font_size))
|
||||||
bg.paste(w2b)
|
bg.paste(w2b)
|
||||||
chinese_msg = formalization_msg(msg)
|
chinese_msg = formalization_msg(msg)
|
||||||
if not bg.check_font_size(chinese_msg):
|
if not bg.check_font_size(chinese_msg):
|
||||||
|
|||||||
@@ -1,20 +1,18 @@
|
|||||||
import re
|
import re
|
||||||
|
from nonebot.adapters.onebot.v11 import GroupMessageEvent, Event
|
||||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Event
|
|
||||||
from utils.utils import get_message_img_file
|
from utils.utils import get_message_img_file
|
||||||
from nonebot.typing import T_State
|
|
||||||
from .model import WordBank
|
from .model import WordBank
|
||||||
|
|
||||||
|
|
||||||
async def check(bot: Bot, event: Event, state: T_State) -> bool:
|
async def check(event: Event) -> bool:
|
||||||
if isinstance(event, GroupMessageEvent):
|
if isinstance(event, GroupMessageEvent):
|
||||||
msg = event.raw_message
|
msg = event.raw_message
|
||||||
list_img = get_message_img_file(event.json())
|
list_img = get_message_img_file(event.json())
|
||||||
if list_img:
|
if list_img:
|
||||||
for img_file in list_img:
|
for img_file in list_img:
|
||||||
strinfo = re.compile(f"{img_file},subType=\d*]")
|
strinfo = re.compile(f"{img_file},.*?]")
|
||||||
msg = strinfo.sub(f'{img_file}]', msg)
|
msg = strinfo.sub(f'{img_file}]', msg)
|
||||||
return bool(
|
strinfo_face = re.compile(f",type=sticker]")
|
||||||
await WordBank.check(event.group_id, msg, event.is_tome())
|
msg = strinfo_face.sub(f']', msg)
|
||||||
)
|
return bool(await WordBank.check(event.group_id, msg,))
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
from utils.message_builder import image, at
|
from utils.message_builder import image, at, face
|
||||||
|
from typing import Tuple
|
||||||
from ._rule import check
|
from ._rule import check
|
||||||
from .model import WordBank
|
from .model import WordBank
|
||||||
from configs.path_config import DATA_PATH
|
from configs.path_config import DATA_PATH
|
||||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent
|
from nonebot.adapters.onebot.v11 import GroupMessageEvent
|
||||||
from utils.utils import get_message_at, get_message_img
|
from utils.utils import get_message_at, get_message_img, change_img_md5
|
||||||
from nonebot import on_message
|
from nonebot import on_message
|
||||||
from models.group_member_info import GroupInfoUser
|
from models.group_member_info import GroupInfoUser
|
||||||
from utils.utils import get_message_img_file, is_number
|
from utils.utils import get_message_img_file, is_number
|
||||||
@@ -23,16 +24,16 @@ async def _(event: GroupMessageEvent):
|
|||||||
list_img = get_message_img_file(event.json())
|
list_img = get_message_img_file(event.json())
|
||||||
if list_img:
|
if list_img:
|
||||||
for img_file in list_img:
|
for img_file in list_img:
|
||||||
strinfo = re.compile(f"{img_file},subType=\d*]")
|
strinfo = re.compile(f"{img_file},.*?]")
|
||||||
msg = strinfo.sub(f'{img_file}]', msg)
|
msg = strinfo.sub(f'{img_file}]', msg)
|
||||||
q = await WordBank.check(
|
strinfo_face = re.compile(f",type=sticker]")
|
||||||
event.group_id, msg, event.is_tome()
|
msg = strinfo_face.sub(f']', msg)
|
||||||
)
|
q = await WordBank.check(event.group_id, msg, )
|
||||||
await message_handle.send(await get_one_answer(event, q.format, q.answer))
|
await message_handle.send(await get_one_answer(event, q.format, q.answer))
|
||||||
|
|
||||||
|
|
||||||
# 处理单条回答
|
# 处理单条回答
|
||||||
async def get_one_answer(event, format, _answer, all=1):
|
async def get_one_answer(event, format: str, _answer: str, all: bool = True) -> str:
|
||||||
path = data_dir / f"{event.group_id}"
|
path = data_dir / f"{event.group_id}"
|
||||||
placeholder_list = (
|
placeholder_list = (
|
||||||
[
|
[
|
||||||
@@ -50,12 +51,13 @@ async def get_one_answer(event, format, _answer, all=1):
|
|||||||
else:
|
else:
|
||||||
for idx, placeholder in placeholder_list:
|
for idx, placeholder in placeholder_list:
|
||||||
if placeholder.endswith("jpg"):
|
if placeholder.endswith("jpg"):
|
||||||
|
change_img_md5(path / placeholder)
|
||||||
answer += _a[: _a.find(f"[__placeholder_{idx}]")] + image(
|
answer += _a[: _a.find(f"[__placeholder_{idx}]")] + image(
|
||||||
path / placeholder
|
path / placeholder
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if all == 1:
|
if all:
|
||||||
answer += _a[: _a.find(f"[__placeholder_{idx}]")] + at(placeholder)
|
answer += _a[: _a.find(f"[__placeholder_{idx}]")] + at(int(placeholder))
|
||||||
else:
|
else:
|
||||||
q = await GroupInfoUser.get_member_info(
|
q = await GroupInfoUser.get_member_info(
|
||||||
int(placeholder), event.group_id)
|
int(placeholder), event.group_id)
|
||||||
@@ -65,7 +67,7 @@ async def get_one_answer(event, format, _answer, all=1):
|
|||||||
|
|
||||||
|
|
||||||
# 处理单条问题
|
# 处理单条问题
|
||||||
async def get_one_problem(event, problem):
|
async def get_one_problem(event, problem: str, ) -> Tuple[str, str]:
|
||||||
strinfo = re.compile(f",subType=\d")
|
strinfo = re.compile(f",subType=\d")
|
||||||
problem = strinfo.sub('', problem)
|
problem = strinfo.sub('', problem)
|
||||||
_problem = problem
|
_problem = problem
|
||||||
@@ -93,7 +95,7 @@ async def get_one_problem(event, problem):
|
|||||||
|
|
||||||
|
|
||||||
# 显示单条数据库问题
|
# 显示单条数据库问题
|
||||||
async def get_one_image_problem(event, problem):
|
async def get_one_image_problem(event, problem: str) -> str:
|
||||||
path = data_dir / f"{event.group_id}" / "problem"
|
path = data_dir / f"{event.group_id}" / "problem"
|
||||||
placeholder_list = []
|
placeholder_list = []
|
||||||
idx = 0
|
idx = 0
|
||||||
@@ -127,3 +129,19 @@ async def get_one_image_problem(event, problem):
|
|||||||
_p = _p[_p.find(f"[__placeholder_{idx}]") + len(f"[__placeholder_{idx}]"):]
|
_p = _p[_p.find(f"[__placeholder_{idx}]") + len(f"[__placeholder_{idx}]"):]
|
||||||
|
|
||||||
return problem + _p
|
return problem + _p
|
||||||
|
|
||||||
|
|
||||||
|
# 替换cq码
|
||||||
|
async def replace_cq(group_id, msg: str, is_face: bool = True) -> str:
|
||||||
|
strinfo_img = re.compile(f"\[CQ:image.*?]")
|
||||||
|
msg = strinfo_img.sub('[图片]', msg)
|
||||||
|
at_list = re.findall(rf"\[CQ:at,qq=(.*?)]", msg)
|
||||||
|
if at_list:
|
||||||
|
for ats in at_list:
|
||||||
|
q = await GroupInfoUser.get_member_info(
|
||||||
|
int(ats), group_id)
|
||||||
|
msg = msg.replace(f'[CQ:at,qq={ats}]', "@" + q.user_name)
|
||||||
|
if is_face:
|
||||||
|
strinfo_face = re.compile(f"\[CQ:face,id=.*?]")
|
||||||
|
msg = strinfo_face.sub('[表情]', msg)
|
||||||
|
return msg
|
||||||
|
|||||||
+22
-42
@@ -1,9 +1,7 @@
|
|||||||
from services.db_context import db
|
from services.db_context import db
|
||||||
from typing import Optional, List, Union, Tuple
|
from typing import Optional, List, Union, Tuple
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
|
||||||
from configs.path_config import DATA_PATH
|
from configs.path_config import DATA_PATH
|
||||||
import re
|
|
||||||
import random
|
import random
|
||||||
from configs.config import Config
|
from configs.config import Config
|
||||||
|
|
||||||
@@ -125,58 +123,40 @@ class WordBank(db.Model):
|
|||||||
q.sort()
|
q.sort()
|
||||||
_tmp = []
|
_tmp = []
|
||||||
for problem in q:
|
for problem in q:
|
||||||
if "[_to_me" in problem:
|
|
||||||
r = re.search(r"\[_to_me\|(.*?)](.*)", problem)
|
|
||||||
if r:
|
|
||||||
bot_name = r.group(1)
|
|
||||||
problem = problem.replace(f"[_to_me|{bot_name}]", bot_name)
|
|
||||||
_tmp.append(problem)
|
_tmp.append(problem)
|
||||||
return list(set(_tmp))
|
return list(set(_tmp))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def check(cls, group_id: int, problem: str, is_tome: bool = False) -> Optional["WordBank"]:
|
async def check(cls, group_id: int, problem: str) -> Optional["WordBank"]:
|
||||||
"""
|
"""
|
||||||
检测词条并随机返回
|
检测词条并随机返回
|
||||||
:param group_id: 群号
|
:param group_id: 群号
|
||||||
:param problem: 问题
|
:param problem: 问题
|
||||||
:param is_tome:是否at真寻
|
|
||||||
"""
|
"""
|
||||||
if is_tome:
|
if problem:
|
||||||
|
FUZZY = Config.get_config("word_bank", "WORD_BANK_FUZZY")
|
||||||
|
KEY = Config.get_config("word_bank", "WORD_BANK_KEY")
|
||||||
q = await cls.query.where(
|
q = await cls.query.where(
|
||||||
(cls.group_id == group_id)
|
(cls.group_id == group_id) & (cls.problem == problem)
|
||||||
).gino.all()
|
).gino.all()
|
||||||
q = [x for x in q if "[_to_me" in x.problem]
|
if KEY and FUZZY:
|
||||||
if q:
|
q_fuzzy = await cls.query.where(
|
||||||
for x in q:
|
(cls.group_id == group_id) & (cls.search_type == 2) & (
|
||||||
r = re.search(r"\[_to_me\|(.*?)](.*)", x.problem)
|
cls.problem.contains(f'{problem}'))).gino.all()
|
||||||
if r and r.group(2) == problem:
|
q_key = await cls.query.where((cls.group_id == group_id) & (cls.search_type == 1)).gino.all()
|
||||||
return x
|
q_key = [x for x in q_key if str(x.problem) in (problem)]
|
||||||
return None
|
q += q_fuzzy + q_key
|
||||||
|
elif FUZZY:
|
||||||
|
q_fuzzy = await cls.query.where(
|
||||||
|
(cls.group_id == group_id) & (cls.search_type == 2) & (
|
||||||
|
cls.problem.contains(f'{problem}'))).gino.all()
|
||||||
|
q += q_fuzzy
|
||||||
|
elif KEY:
|
||||||
|
q_key = await cls.query.where((cls.group_id == group_id) & (cls.search_type == 1)).gino.all()
|
||||||
|
q_key = [x for x in q_key if str(x.problem) in (problem)]
|
||||||
|
q += q_key
|
||||||
else:
|
else:
|
||||||
if problem:
|
return None
|
||||||
FUZZY = Config.get_config("word_bank", "WORD_BANK_FUZZY")
|
|
||||||
KEY = Config.get_config("word_bank", "WORD_BANK_KEY")
|
|
||||||
q = await cls.query.where(
|
|
||||||
(cls.group_id == group_id) & (cls.problem == problem)
|
|
||||||
).gino.all()
|
|
||||||
if KEY and FUZZY:
|
|
||||||
q_fuzzy = await cls.query.where(
|
|
||||||
(cls.group_id == group_id) & (cls.search_type == 2) & (
|
|
||||||
cls.problem.contains(f'{problem}'))).gino.all()
|
|
||||||
q_key = await cls.query.where((cls.group_id == group_id) & (cls.search_type == 1)).gino.all()
|
|
||||||
q_key = [x for x in q_key if str(x.problem) in (problem)]
|
|
||||||
q += q_fuzzy + q_key
|
|
||||||
elif FUZZY:
|
|
||||||
q_fuzzy = await cls.query.where(
|
|
||||||
(cls.group_id == group_id) & (cls.search_type == 2) & (
|
|
||||||
cls.problem.contains(f'{problem}'))).gino.all()
|
|
||||||
q += q_fuzzy
|
|
||||||
elif KEY:
|
|
||||||
q_key = await cls.query.where((cls.group_id == group_id) & (cls.search_type == 1)).gino.all()
|
|
||||||
q_key = [x for x in q_key if str(x.problem) in (problem)]
|
|
||||||
q += q_key
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
return random.choice(q) if q else None
|
return random.choice(q) if q else None
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,13 @@ from utils.http_utils import AsyncHttpx
|
|||||||
from ._data_source import WordBankBuilder
|
from ._data_source import WordBankBuilder
|
||||||
from utils.message_builder import image
|
from utils.message_builder import image
|
||||||
from utils.image_utils import text2image
|
from utils.image_utils import text2image
|
||||||
from .message_handle import get_one_answer, get_one_problem, get_one_image_problem
|
from .message_handle import get_one_answer, get_one_problem, get_one_image_problem, replace_cq
|
||||||
from .model import WordBank
|
from .model import WordBank
|
||||||
from nonebot.adapters.onebot.v11 import (
|
from nonebot.adapters.onebot.v11 import (
|
||||||
Bot,
|
Bot,
|
||||||
GroupMessageEvent,
|
GroupMessageEvent,
|
||||||
Message
|
Message
|
||||||
)
|
)
|
||||||
from nonebot.typing import T_State
|
|
||||||
from nonebot import on_command
|
from nonebot import on_command
|
||||||
import random
|
import random
|
||||||
import os
|
import os
|
||||||
@@ -69,7 +68,7 @@ show_word = on_command("显示词条", aliases={"查看词条"}, priority=5, blo
|
|||||||
|
|
||||||
|
|
||||||
@add_word.handle()
|
@add_word.handle()
|
||||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State, arg: Message = CommandArg()):
|
async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||||
msg = str(arg)
|
msg = str(arg)
|
||||||
r = re.search(r"问(.+)\s?答([\s\S]*)", msg)
|
r = re.search(r"问(.+)\s?答([\s\S]*)", msg)
|
||||||
if not r:
|
if not r:
|
||||||
@@ -81,12 +80,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State, arg: Message = C
|
|||||||
if not answer:
|
if not answer:
|
||||||
await add_word.finish("未检测到词条回答...")
|
await add_word.finish("未检测到词条回答...")
|
||||||
idx = 0
|
idx = 0
|
||||||
for n in bot.config.nickname:
|
_problem = problem
|
||||||
if n and problem.startswith(n):
|
|
||||||
_problem = f"[_to_me|{n}]" + problem[len(n):]
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
_problem = problem
|
|
||||||
search_type = 0
|
search_type = 0
|
||||||
if re.search("^关键字|词(.*)", msg):
|
if re.search("^关键字|词(.*)", msg):
|
||||||
search_type = 1
|
search_type = 1
|
||||||
@@ -94,7 +88,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State, arg: Message = C
|
|||||||
search_type = 2
|
search_type = 2
|
||||||
_builder = await get__builder(event, _problem, answer, idx)
|
_builder = await get__builder(event, _problem, answer, idx)
|
||||||
if await _builder.save(search_type):
|
if await _builder.save(search_type):
|
||||||
logger.info(f"已保存词条 问:{_builder.problem} 答:{msg}")
|
logger.info(f"已保存词条 问:{_builder.problem} 答:{answer}")
|
||||||
await add_word.send("已保存词条:" + _builder.problem)
|
await add_word.send("已保存词条:" + _builder.problem)
|
||||||
else:
|
else:
|
||||||
await delete_word.send("保存失败,可能是回答重复")
|
await delete_word.send("保存失败,可能是回答重复")
|
||||||
@@ -102,7 +96,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State, arg: Message = C
|
|||||||
|
|
||||||
@delete_word.handle()
|
@delete_word.handle()
|
||||||
async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||||
msg = str(arg).strip()
|
msg = str(arg)
|
||||||
if not msg:
|
if not msg:
|
||||||
await delete_word.finish("此命令之后需要跟随指定词条,通过“显示词条“查看")
|
await delete_word.finish("此命令之后需要跟随指定词条,通过“显示词条“查看")
|
||||||
index = None
|
index = None
|
||||||
@@ -124,7 +118,10 @@ async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
|||||||
if answer := await WordBank.delete_problem_answer(
|
if answer := await WordBank.delete_problem_answer(
|
||||||
event.user_id, event.group_id, _problem, index
|
event.user_id, event.group_id, _problem, index
|
||||||
):
|
):
|
||||||
await delete_word.send("删除词条成功:" + problem + f"\n回答:\n{answer}")
|
|
||||||
|
await delete_word.send(Message(
|
||||||
|
"删除词条成功:\n问" + await replace_cq(event.group_id, problem, False) + f"\n回答:\n" + await replace_cq(
|
||||||
|
event.group_id, answer, False) + "\n"))
|
||||||
logger.info(
|
logger.info(
|
||||||
f"(USER {event.user_id}, GROUP "
|
f"(USER {event.user_id}, GROUP "
|
||||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||||
@@ -137,7 +134,7 @@ async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
|||||||
|
|
||||||
|
|
||||||
@update_word.handle()
|
@update_word.handle()
|
||||||
async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||||
msg = str(arg)
|
msg = str(arg)
|
||||||
if not msg:
|
if not msg:
|
||||||
await update_word.finish("此命令之后需要跟随指定词条,通过“显示词条“查看")
|
await update_word.finish("此命令之后需要跟随指定词条,通过“显示词条“查看")
|
||||||
@@ -157,12 +154,7 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
|||||||
else:
|
else:
|
||||||
await update_word.finish("此命令之后需要跟随修改内容")
|
await update_word.finish("此命令之后需要跟随修改内容")
|
||||||
idx = 0
|
idx = 0
|
||||||
for n in bot.config.nickname:
|
_problem = problem
|
||||||
if n and problem.startswith(n):
|
|
||||||
_problem = f"[_to_me|{n}]" + problem[len(n):]
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
_problem = problem
|
|
||||||
_builder = await get__builder(event, _problem, new_answer, idx)
|
_builder = await get__builder(event, _problem, new_answer, idx)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -185,8 +177,8 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
|||||||
if not msg:
|
if not msg:
|
||||||
_problem_list = await WordBank.get_group_all_problem(event.group_id)
|
_problem_list = await WordBank.get_group_all_problem(event.group_id)
|
||||||
if not _problem_list:
|
if not _problem_list:
|
||||||
await show_word.finish("该群未收录任何词条..")
|
await show_word.finish("该群未收录任replace_cq何词条..")
|
||||||
_problem_list = [f"\t{i}. {x}" for i, x in enumerate(_problem_list)]
|
_problem_list = [f"\t{i}. {await replace_cq(event.group_id, x)}" for i, x in enumerate(_problem_list)]
|
||||||
long_problem_list = len(_problem_list)
|
long_problem_list = len(_problem_list)
|
||||||
max_line = Config.get_config("word_bank", "WORD_BANK_MIX")
|
max_line = Config.get_config("word_bank", "WORD_BANK_MIX")
|
||||||
if long_problem_list > max_line:
|
if long_problem_list > max_line:
|
||||||
@@ -245,10 +237,11 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
# 解析图片和@
|
# 解析图片和@
|
||||||
_answer_img_nu_list = [await get_one_answer(event, format, answer, 0) for answer, format in _answer_list]
|
_answer_img_nu_list = [await get_one_answer(event, format, answer, False) for answer, format in
|
||||||
|
_answer_list]
|
||||||
word_nu = len(_answer_img_nu_list)
|
word_nu = len(_answer_img_nu_list)
|
||||||
img_nu = 0
|
img_nu = 0
|
||||||
answer = "词条" + msg + "回答:"
|
answer = "词条" + msg + "\n回答:"
|
||||||
for i, x, in enumerate(_answer_img_nu_list):
|
for i, x, in enumerate(_answer_img_nu_list):
|
||||||
r = re.findall(rf"\[CQ:image,file=", str(x))
|
r = re.findall(rf"\[CQ:image,file=", str(x))
|
||||||
if r:
|
if r:
|
||||||
@@ -265,7 +258,7 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
|||||||
# await show_word.send(f"词条 {msg} 回答:\n" + "\n".join(_answer_list))
|
# await show_word.send(f"词条 {msg} 回答:\n" + "\n".join(_answer_list))
|
||||||
|
|
||||||
|
|
||||||
async def get__builder(event, _problem, answer, idx):
|
async def get__builder(event, _problem: str, answer: str, idx: int):
|
||||||
(data_dir / f"{event.group_id}").mkdir(exist_ok=True, parents=True)
|
(data_dir / f"{event.group_id}").mkdir(exist_ok=True, parents=True)
|
||||||
(data_dir / f"{event.group_id}" / "problem").mkdir(exist_ok=True, parents=True)
|
(data_dir / f"{event.group_id}" / "problem").mkdir(exist_ok=True, parents=True)
|
||||||
_builder = WordBankBuilder(event.user_id, event.group_id, _problem)
|
_builder = WordBankBuilder(event.user_id, event.group_id, _problem)
|
||||||
@@ -293,16 +286,16 @@ async def get__builder(event, _problem, answer, idx):
|
|||||||
if f"__placeholder_{rand}_{idx}.jpg" not in os.listdir(data_dir / f"{event.group_id}"):
|
if f"__placeholder_{rand}_{idx}.jpg" not in os.listdir(data_dir / f"{event.group_id}"):
|
||||||
break
|
break
|
||||||
rand = random.randint(1, 10000) + random.randint(1, 114514)
|
rand = random.randint(1, 10000) + random.randint(1, 114514)
|
||||||
strinfo = re.compile(f"\[CQ:image,file={r.group(1)},url={_x_list[0]}\?{_x_list[1]},subType=\d*?]")
|
strinfo = re.compile(f"\[CQ:image,file={r.group(1)},.*url={_x_list[0]}\?{_x_list[1]}.*?]")
|
||||||
answer = strinfo.sub(f"[__placeholder_{idx}]", answer)
|
answer = strinfo.sub(f"[__placeholder_{idx}]", answer)
|
||||||
await AsyncHttpx.download_file(
|
await AsyncHttpx.download_file(
|
||||||
img, data_dir / f"{event.group_id}" / f"__placeholder_{rand}_{idx}.jpg"
|
img, data_dir / f"{event.group_id}" / f"__placeholder_{rand}_{idx}.jpg"
|
||||||
)
|
)
|
||||||
_builder.set_placeholder(idx, f"__placeholder_{rand}_{idx}.jpg")
|
_builder.set_placeholder(idx, f"__placeholder_{rand}_{idx}.jpg")
|
||||||
idx += 1
|
idx += 1
|
||||||
r_problem = re.search(rf"\[CQ:image,file=(.*?),url={_x}.*?]", _p)
|
r_problem = re.search(rf"\[CQ:image,file=(.*?)(,subType=\d)?,url={_x}.*?]", _p)
|
||||||
if r_problem:
|
if r_problem:
|
||||||
strinfo = re.compile(f",url={_x_list[0]}\?{_x_list[1]},subType=\d*?]")
|
strinfo = re.compile(f"(,subType=\d)?,url={_x_list[0]}\?{_x_list[1]}.*?]")
|
||||||
_problem = strinfo.sub(f"]", _problem)
|
_problem = strinfo.sub(f"]", _problem)
|
||||||
_p = strinfo.sub(f"]", _p)
|
_p = strinfo.sub(f"]", _p)
|
||||||
problem += _p[: _p.find(f"[CQ:image,file={r_problem.group(1)}]")] + image(img)
|
problem += _p[: _p.find(f"[CQ:image,file={r_problem.group(1)}]")] + image(img)
|
||||||
|
|||||||
Generated
+546
-23
File diff suppressed because it is too large
Load Diff
+4
-7
@@ -1,10 +1,10 @@
|
|||||||
|
import asyncio
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from nonebot.log import logger
|
from nonebot.log import logger
|
||||||
from playwright.async_api import Browser, async_playwright
|
from playwright.async_api import Browser, async_playwright
|
||||||
import nonebot
|
import nonebot
|
||||||
from nonebot import Driver
|
from nonebot import Driver
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
import platform
|
|
||||||
|
|
||||||
|
|
||||||
driver: Driver = nonebot.get_driver()
|
driver: Driver = nonebot.get_driver()
|
||||||
@@ -15,16 +15,14 @@ _browser: Optional[Browser] = None
|
|||||||
|
|
||||||
async def init(**kwargs) -> Optional[Browser]:
|
async def init(**kwargs) -> Optional[Browser]:
|
||||||
global _browser
|
global _browser
|
||||||
|
browser = await async_playwright().start()
|
||||||
try:
|
try:
|
||||||
browser = await async_playwright().start()
|
|
||||||
_browser = await browser.chromium.launch(**kwargs)
|
_browser = await browser.chromium.launch(**kwargs)
|
||||||
return _browser
|
return _browser
|
||||||
except NotImplementedError:
|
|
||||||
logger.warning("win环境下 初始化playwright失败,相关功能将被限制....")
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"启动chromium发生错误 {type(e)}:{e}")
|
logger.warning(f"启动chromium发生错误 {type(e)}:{e}")
|
||||||
if _browser:
|
asyncio.get_event_loop().run_in_executor(None, install)
|
||||||
await _browser.close()
|
_browser = await browser.chromium.launch(**kwargs)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -32,7 +30,6 @@ async def get_browser(**kwargs) -> Browser:
|
|||||||
return _browser or await init(**kwargs)
|
return _browser or await init(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
# @driver.on_startup
|
|
||||||
def install():
|
def install():
|
||||||
"""自动安装、更新 Chromium"""
|
"""自动安装、更新 Chromium"""
|
||||||
logger.info("正在检查 Chromium 更新")
|
logger.info("正在检查 Chromium 更新")
|
||||||
|
|||||||
+6
-3
@@ -30,6 +30,7 @@ class AsyncHttpx:
|
|||||||
params: Optional[Dict[str, Any]] = None,
|
params: Optional[Dict[str, Any]] = None,
|
||||||
headers: Optional[Dict[str, str]] = None,
|
headers: Optional[Dict[str, str]] = None,
|
||||||
cookies: Optional[Dict[str, str]] = None,
|
cookies: Optional[Dict[str, str]] = None,
|
||||||
|
verify: bool = True,
|
||||||
use_proxy: bool = True,
|
use_proxy: bool = True,
|
||||||
proxy: Dict[str, str] = None,
|
proxy: Dict[str, str] = None,
|
||||||
timeout: Optional[int] = 30,
|
timeout: Optional[int] = 30,
|
||||||
@@ -50,7 +51,7 @@ class AsyncHttpx:
|
|||||||
if not headers:
|
if not headers:
|
||||||
headers = get_user_agent()
|
headers = get_user_agent()
|
||||||
proxy = proxy if proxy else cls.proxy if use_proxy else None
|
proxy = proxy if proxy else cls.proxy if use_proxy else None
|
||||||
async with httpx.AsyncClient(proxies=proxy) as client:
|
async with httpx.AsyncClient(proxies=proxy, verify=verify) as client:
|
||||||
return await client.get(
|
return await client.get(
|
||||||
url,
|
url,
|
||||||
params=params,
|
params=params,
|
||||||
@@ -68,6 +69,7 @@ class AsyncHttpx:
|
|||||||
data: Optional[Dict[str, str]] = None,
|
data: Optional[Dict[str, str]] = None,
|
||||||
content: Any = None,
|
content: Any = None,
|
||||||
files: Any = None,
|
files: Any = None,
|
||||||
|
verify: bool = True,
|
||||||
use_proxy: bool = True,
|
use_proxy: bool = True,
|
||||||
proxy: Dict[str, str] = None,
|
proxy: Dict[str, str] = None,
|
||||||
json: Optional[Dict[str, Union[Any]]] = None,
|
json: Optional[Dict[str, Union[Any]]] = None,
|
||||||
@@ -96,7 +98,7 @@ class AsyncHttpx:
|
|||||||
if not headers:
|
if not headers:
|
||||||
headers = get_user_agent()
|
headers = get_user_agent()
|
||||||
proxy = proxy if proxy else cls.proxy if use_proxy else None
|
proxy = proxy if proxy else cls.proxy if use_proxy else None
|
||||||
async with httpx.AsyncClient(proxies=proxy) as client:
|
async with httpx.AsyncClient(proxies=proxy, verify=verify) as client:
|
||||||
return await client.post(
|
return await client.post(
|
||||||
url,
|
url,
|
||||||
content=content,
|
content=content,
|
||||||
@@ -117,6 +119,7 @@ class AsyncHttpx:
|
|||||||
path: Union[str, Path],
|
path: Union[str, Path],
|
||||||
*,
|
*,
|
||||||
params: Optional[Dict[str, str]] = None,
|
params: Optional[Dict[str, str]] = None,
|
||||||
|
verify: bool = True,
|
||||||
use_proxy: bool = True,
|
use_proxy: bool = True,
|
||||||
proxy: Dict[str, str] = None,
|
proxy: Dict[str, str] = None,
|
||||||
headers: Optional[Dict[str, str]] = None,
|
headers: Optional[Dict[str, str]] = None,
|
||||||
@@ -169,7 +172,7 @@ class AsyncHttpx:
|
|||||||
headers = get_user_agent()
|
headers = get_user_agent()
|
||||||
proxy = proxy if proxy else cls.proxy if use_proxy else None
|
proxy = proxy if proxy else cls.proxy if use_proxy else None
|
||||||
try:
|
try:
|
||||||
async with httpx.AsyncClient(proxies=proxy) as client:
|
async with httpx.AsyncClient(proxies=proxy, verify=verify) as client:
|
||||||
async with client.stream(
|
async with client.stream(
|
||||||
"GET",
|
"GET",
|
||||||
url,
|
url,
|
||||||
|
|||||||
+18
-10
@@ -14,6 +14,8 @@ from imagehash import ImageHash
|
|||||||
from matplotlib import pyplot as plt
|
from matplotlib import pyplot as plt
|
||||||
from PIL import Image, ImageDraw, ImageFile, ImageFilter, ImageFont
|
from PIL import Image, ImageDraw, ImageFile, ImageFilter, ImageFont
|
||||||
|
|
||||||
|
from services import logger
|
||||||
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||||
Image.MAX_IMAGE_PIXELS = None
|
Image.MAX_IMAGE_PIXELS = None
|
||||||
|
|
||||||
@@ -178,7 +180,7 @@ class BuildImage:
|
|||||||
self.paste_image_height = int(paste_image_height)
|
self.paste_image_height = int(paste_image_height)
|
||||||
self.current_w = 0
|
self.current_w = 0
|
||||||
self.current_h = 0
|
self.current_h = 0
|
||||||
self.font = ImageFont.truetype(str(FONT_PATH / font), font_size)
|
self.font = ImageFont.truetype(str(FONT_PATH / font), int(font_size))
|
||||||
if not plain_text and not color:
|
if not plain_text and not color:
|
||||||
color = (255, 255, 255)
|
color = (255, 255, 255)
|
||||||
self.background = background
|
self.background = background
|
||||||
@@ -209,13 +211,16 @@ class BuildImage:
|
|||||||
(self.w, self.h), Image.ANTIALIAS
|
(self.w, self.h), Image.ANTIALIAS
|
||||||
)
|
)
|
||||||
if is_alpha:
|
if is_alpha:
|
||||||
array = self.markImg.load()
|
try:
|
||||||
for i in range(w):
|
array = self.markImg.load()
|
||||||
for j in range(h):
|
for i in range(w):
|
||||||
pos = array[i, j]
|
for j in range(h):
|
||||||
is_edit = sum([1 for x in pos[0:3] if x > 240]) == 3
|
pos = array[i, j]
|
||||||
if is_edit:
|
is_edit = sum([1 for x in pos[0:3] if x > 240]) == 3
|
||||||
array[i, j] = (255, 255, 255, 0)
|
if is_edit:
|
||||||
|
array[i, j] = (255, 255, 255, 0)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"背景透明化发生错误..{type(e)}:{e}")
|
||||||
self.draw = ImageDraw.Draw(self.markImg)
|
self.draw = ImageDraw.Draw(self.markImg)
|
||||||
self.size = self.w, self.h
|
self.size = self.w, self.h
|
||||||
if plain_text:
|
if plain_text:
|
||||||
@@ -681,7 +686,10 @@ class BuildImage:
|
|||||||
right, bottom = [(value - offset) * antialias for value in ellipse_box[2:]]
|
right, bottom = [(value - offset) * antialias for value in ellipse_box[2:]]
|
||||||
draw.ellipse([left, top, right, bottom], fill=fill)
|
draw.ellipse([left, top, right, bottom], fill=fill)
|
||||||
mask = mask.resize(self.markImg.size, Image.LANCZOS)
|
mask = mask.resize(self.markImg.size, Image.LANCZOS)
|
||||||
self.markImg.putalpha(mask)
|
try:
|
||||||
|
self.markImg.putalpha(mask)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
async def acircle_corner(self, radii: int = 30):
|
async def acircle_corner(self, radii: int = 30):
|
||||||
"""
|
"""
|
||||||
@@ -1499,7 +1507,7 @@ async def text2image(
|
|||||||
w, _ = _tmp.getsize(x.strip() or "正")
|
w, _ = _tmp.getsize(x.strip() or "正")
|
||||||
height += h + line_height
|
height += h + line_height
|
||||||
width = width if width > w else w
|
width = width if width > w else w
|
||||||
image_list.append(BuildImage(w, h, font=font, font_size=font_size, plain_text=x.strip()))
|
image_list.append(BuildImage(w, h, font=font, font_size=font_size, plain_text=x.strip(), color=color))
|
||||||
width += pw
|
width += pw
|
||||||
height += ph
|
height += ph
|
||||||
A = BuildImage(
|
A = BuildImage(
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
from utils.manager.data_class import StaticData
|
from utils.manager.data_class import StaticData
|
||||||
from nonebot.adapters.onebot.v11 import Bot
|
from nonebot.adapters.onebot.v11 import Bot, ActionFailed
|
||||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
from typing import Optional, Literal
|
from typing import Optional, Literal
|
||||||
from utils.image_utils import BuildImage
|
from utils.image_utils import BuildImage
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ from configs.config import SYSTEM_PROXY, Config
|
|||||||
from typing import List, Union, Optional, Type, Any
|
from typing import List, Union, Optional, Type, Any
|
||||||
from nonebot.adapters.onebot.v11 import Bot, Message
|
from nonebot.adapters.onebot.v11 import Bot, Message
|
||||||
from nonebot.matcher import matchers, Matcher
|
from nonebot.matcher import matchers, Matcher
|
||||||
|
from services.log import logger
|
||||||
|
from pathlib import Path
|
||||||
import httpx
|
import httpx
|
||||||
import nonebot
|
import nonebot
|
||||||
import pytz
|
import pytz
|
||||||
@@ -398,3 +400,19 @@ def change_pixiv_image_links(
|
|||||||
.replace("_webp", "")
|
.replace("_webp", "")
|
||||||
)
|
)
|
||||||
return url
|
return url
|
||||||
|
|
||||||
|
|
||||||
|
def change_img_md5(path_file: Union[str, Path]) -> bool:
|
||||||
|
"""
|
||||||
|
说明:
|
||||||
|
改变图片MD5
|
||||||
|
参数:
|
||||||
|
:param path_file: 图片路径
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with open(path_file, "a") as f:
|
||||||
|
f.write(str(int(time.time() * 1000)))
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"改变图片MD5发生错误 {type(e)}:{e} Path:{path_file}")
|
||||||
|
return False
|
||||||
|
|||||||
Reference in New Issue
Block a user