mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-10-01 17:49:58 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c17ac1f9d | ||
|
|
f038763041 | ||
|
|
eaf6d54757 | ||
|
|
d7368c83bc | ||
|
|
4011620da1 | ||
|
|
6e0b91531e | ||
|
|
b8ca1d68aa | ||
|
|
2b9cda40a0 |
@@ -236,13 +236,32 @@ __Docker 最新版本由 [Sakuracio](https://github.com/Sakuracio) 提供__
|
|||||||
|
|
||||||
## 更新
|
## 更新
|
||||||
|
|
||||||
### 2022/2/19 \[v0.1.2] (nonebot beta2!)
|
### 2022/2/20 \[v0.1.3.1]
|
||||||
|
|
||||||
|
* 修复pix下载临时文件目录错误
|
||||||
|
* 修复AI,天气,发送图片ignore导致无法使用
|
||||||
|
* 修复纯文本被动技能提醒有时无法删除控制文本
|
||||||
|
|
||||||
|
### 2022/2/19 \[v0.1.3] (nonebot beta2!)
|
||||||
|
|
||||||
|
* 由于nonebot升级版本,提供更新建议(__该次升级将会导致nonebot.beta1以下的插件无法使用__
|
||||||
|
* 保证services,utils,configs,plugins,basic_plugins,文件夹均为最新
|
||||||
|
* 根目录有pyproject.toml与poetry.lock
|
||||||
|
* 执行命令:
|
||||||
|
* pip3 install poetry
|
||||||
|
* poetry install
|
||||||
|
* poetry shell
|
||||||
|
* playwright install chromium
|
||||||
|
* python3 bot.py
|
||||||
|
|
||||||
|
|
||||||
* 适配nonebot.beta2
|
* 适配nonebot.beta2
|
||||||
* 删除图片搜索 nonebot_plugin_picsearcher
|
* 删除图片搜索 nonebot_plugin_picsearcher
|
||||||
* 新增图片搜索 search_image
|
* 新增图片搜索 search_image
|
||||||
* 替换cos api
|
* 替换cos api
|
||||||
* 原神签到树脂提醒新增绑定群里,在某群绑定uid就会在某群发送提醒信息(有好友则私聊,需要重新绑定uid
|
* 原神签到树脂提醒新增绑定群里,在某群绑定uid就会在某群发送提醒信息(有好友则私聊,需要重新绑定uid
|
||||||
|
* 修改update_info.json
|
||||||
|
* 修复原神资源查询下载数据失败时导致报错
|
||||||
* 优化BuildImage.circle()锯齿问题 [@pull/109](https://github.com/HibiKier/zhenxun_bot/pull/109)
|
* 优化BuildImage.circle()锯齿问题 [@pull/109](https://github.com/HibiKier/zhenxun_bot/pull/109)
|
||||||
* epic restful 替换 [@pull/119](https://github.com/HibiKier/zhenxun_bot/pull/119)
|
* epic restful 替换 [@pull/119](https://github.com/HibiKier/zhenxun_bot/pull/119)
|
||||||
* fix: 修复远古时期残留的epic推送问题 [@pull/122](https://github.com/HibiKier/zhenxun_bot/pull/122)
|
* fix: 修复远古时期残留的epic推送问题 [@pull/122](https://github.com/HibiKier/zhenxun_bot/pull/122)
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
__version__: v0.1.2
|
__version__: v0.1.3.1
|
||||||
@@ -11,7 +11,14 @@ async def handle_api_call(bot: Bot, api: str, data: Dict[str, Any]):
|
|||||||
r = None
|
r = None
|
||||||
if (
|
if (
|
||||||
(api == "send_msg" and data["message"] == "group_id" or api == "send_group_msg")
|
(api == "send_msg" and data["message"] == "group_id" or api == "send_group_msg")
|
||||||
and (r := re.search("^\[\[_task\|(.*)]]", get_message_text(data["message"])))
|
and (
|
||||||
|
r := re.search(
|
||||||
|
"^\[\[_task\|(.*)]]",
|
||||||
|
data["message"]
|
||||||
|
if isinstance(data["message"], str)
|
||||||
|
else get_message_text(data["message"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
and r.group(1) in group_manager.get_task_data().keys()
|
and r.group(1) in group_manager.get_task_data().keys()
|
||||||
):
|
):
|
||||||
task = r.group(1)
|
task = r.group(1)
|
||||||
@@ -19,6 +26,11 @@ async def handle_api_call(bot: Bot, api: str, data: Dict[str, Any]):
|
|||||||
if not await group_manager.check_group_task_status(group_id, task):
|
if not await group_manager.check_group_task_status(group_id, task):
|
||||||
raise MockApiException(f"被动技能 {task} 处于关闭状态...")
|
raise MockApiException(f"被动技能 {task} 处于关闭状态...")
|
||||||
else:
|
else:
|
||||||
msg = str(data["message"][0])
|
if isinstance(data["message"], str):
|
||||||
msg = msg.replace(f"[[_task|{task}]]", "")
|
msg = data["message"]
|
||||||
data["message"][0] = MessageSegment.text(msg)
|
msg = msg.replace(f"[[_task|{task}]]", "")
|
||||||
|
data["message"] = msg
|
||||||
|
else:
|
||||||
|
msg = str(data["message"][0])
|
||||||
|
msg = msg.replace(f"[[_task|{task}]]", "")
|
||||||
|
data["message"][0] = MessageSegment.text(msg)
|
||||||
|
|||||||
@@ -6,11 +6,10 @@ from nonebot.adapters.onebot.v11 import (
|
|||||||
MessageEvent,
|
MessageEvent,
|
||||||
)
|
)
|
||||||
from nonebot.rule import to_me
|
from nonebot.rule import to_me
|
||||||
from nonebot.params import CommandArg
|
|
||||||
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 services.log import logger
|
from services.log import logger
|
||||||
from utils.utils import get_message_img
|
from utils.utils import get_message_img, get_message_text
|
||||||
from .data_source import get_chat_result, hello, no_result
|
from .data_source import get_chat_result, hello, no_result
|
||||||
from configs.config import NICKNAME, Config
|
from configs.config import NICKNAME, Config
|
||||||
|
|
||||||
@@ -42,8 +41,8 @@ ai = on_message(rule=to_me(), priority=8)
|
|||||||
|
|
||||||
|
|
||||||
@ai.handle()
|
@ai.handle()
|
||||||
async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
async def _(bot: Bot, event: MessageEvent):
|
||||||
msg = arg.extract_plain_text().strip()
|
msg = get_message_text(event.json())
|
||||||
img = get_message_img(event.json())
|
img = get_message_img(event.json())
|
||||||
if "CQ:xml" in str(event.get_message()):
|
if "CQ:xml" in str(event.get_message()):
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from httpx import AsyncClient
|
from httpx import AsyncClient
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from nonebot.log import logger
|
from nonebot.log import logger
|
||||||
from nonebot.adapters.cqhttp import Bot
|
from nonebot.adapters.onebot.v11 import Bot
|
||||||
from configs.config import NICKNAME
|
from configs.config import NICKNAME
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ async def query_resource(resource_name: str) -> str:
|
|||||||
planning_route = True
|
planning_route = True
|
||||||
if not resource_name or resource_name not in resource_name_list:
|
if not resource_name or resource_name not in resource_name_list:
|
||||||
# return f"未查找到 {resource_name} 资源,可通过 “原神资源列表” 获取全部资源名称.."
|
# return f"未查找到 {resource_name} 资源,可通过 “原神资源列表” 获取全部资源名称.."
|
||||||
return ''
|
return ""
|
||||||
map_ = Map(
|
map_ = Map(
|
||||||
resource_name, CENTER_POINT, planning_route=planning_route, ratio=MAP_RATIO
|
resource_name, CENTER_POINT, planning_route=planning_route, ratio=MAP_RATIO
|
||||||
)
|
)
|
||||||
@@ -84,7 +84,7 @@ def check_resource_exists(resource: str) -> bool:
|
|||||||
检查资源是否存在
|
检查资源是否存在
|
||||||
:param resource: 资源名称
|
:param resource: 资源名称
|
||||||
"""
|
"""
|
||||||
resource = resource.replace('路径', '').replace('路线', '')
|
resource = resource.replace("路径", "").replace("路线", "")
|
||||||
return resource in resource_name_list
|
return resource in resource_name_list
|
||||||
|
|
||||||
|
|
||||||
@@ -97,16 +97,18 @@ async def init(flag: bool = False):
|
|||||||
await download_resource_data(semaphore)
|
await download_resource_data(semaphore)
|
||||||
await download_resource_type()
|
await download_resource_type()
|
||||||
if not CENTER_POINT:
|
if not CENTER_POINT:
|
||||||
CENTER_POINT = json.load(open(resource_label_file, "r", encoding="utf8"))[
|
if resource_label_file.exists():
|
||||||
"CENTER_POINT"
|
CENTER_POINT = json.load(
|
||||||
]
|
open(resource_label_file, "r", encoding="utf8")
|
||||||
with open(resource_type_file, "r", encoding="utf8") as f:
|
)["CENTER_POINT"]
|
||||||
data = json.load(f)
|
if resource_label_file.exists():
|
||||||
for id_ in data:
|
with open(resource_type_file, "r", encoding="utf8") as f:
|
||||||
for x in data[id_]["children"]:
|
data = json.load(f)
|
||||||
resource_name_list.append(x["name"])
|
for id_ in data:
|
||||||
|
for x in data[id_]["children"]:
|
||||||
|
resource_name_list.append(x["name"])
|
||||||
except TimeoutError:
|
except TimeoutError:
|
||||||
logger.warning('原神资源查询信息初始化超时....')
|
logger.warning("原神资源查询信息初始化超时....")
|
||||||
|
|
||||||
|
|
||||||
# 图标及位置资源
|
# 图标及位置资源
|
||||||
@@ -114,7 +116,7 @@ async def download_resource_data(semaphore: Semaphore):
|
|||||||
icon_path.mkdir(parents=True, exist_ok=True)
|
icon_path.mkdir(parents=True, exist_ok=True)
|
||||||
resource_label_file.parent.mkdir(parents=True, exist_ok=True)
|
resource_label_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
try:
|
try:
|
||||||
response = await AsyncHttpx.get(POINT_LIST_URL, timeout=5)
|
response = await AsyncHttpx.get(POINT_LIST_URL, timeout=10)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
data = response.json()
|
data = response.json()
|
||||||
if data["message"] == "OK":
|
if data["message"] == "OK":
|
||||||
@@ -157,16 +159,14 @@ async def download_resource_data(semaphore: Semaphore):
|
|||||||
|
|
||||||
|
|
||||||
# 下载原神地图并拼图
|
# 下载原神地图并拼图
|
||||||
async def download_map_init(
|
async def download_map_init(semaphore: Semaphore, flag: bool = False):
|
||||||
semaphore: Semaphore, flag: bool = False
|
|
||||||
):
|
|
||||||
global CENTER_POINT, MAP_RATIO
|
global CENTER_POINT, MAP_RATIO
|
||||||
map_path.mkdir(exist_ok=True, parents=True)
|
map_path.mkdir(exist_ok=True, parents=True)
|
||||||
_map = map_path / "map.png"
|
_map = map_path / "map.png"
|
||||||
if _map.exists() and os.path.getsize(_map) > 1024 * 1024 * 30:
|
if _map.exists() and os.path.getsize(_map) > 1024 * 1024 * 30:
|
||||||
_map.unlink()
|
_map.unlink()
|
||||||
try:
|
try:
|
||||||
response = await AsyncHttpx.get(MAP_URL, timeout=5)
|
response = await AsyncHttpx.get(MAP_URL, timeout=10)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
data = response.json()
|
data = response.json()
|
||||||
if data["message"] == "OK":
|
if data["message"] == "OK":
|
||||||
@@ -176,20 +176,24 @@ async def download_map_init(
|
|||||||
data = data["slices"]
|
data = data["slices"]
|
||||||
idx = 0
|
idx = 0
|
||||||
for _map_data in data[0]:
|
for _map_data in data[0]:
|
||||||
map_url = _map_data['url']
|
map_url = _map_data["url"]
|
||||||
await download_image(
|
await download_image(
|
||||||
map_url,
|
map_url,
|
||||||
f"{map_path}/{idx}.png",
|
f"{map_path}/{idx}.png",
|
||||||
semaphore,
|
semaphore,
|
||||||
force_flag=flag,
|
force_flag=flag,
|
||||||
)
|
)
|
||||||
BuildImage(0, 0, background=f"{map_path}/{idx}.png", ratio=MAP_RATIO).save()
|
BuildImage(
|
||||||
|
0, 0, background=f"{map_path}/{idx}.png", ratio=MAP_RATIO
|
||||||
|
).save()
|
||||||
idx += 1
|
idx += 1
|
||||||
_w, h = BuildImage(0, 0, background=f"{map_path}/0.png").size
|
_w, h = BuildImage(0, 0, background=f"{map_path}/0.png").size
|
||||||
w = _w * len(os.listdir(map_path))
|
w = _w * len(os.listdir(map_path))
|
||||||
map_file = BuildImage(w, h, _w, h, ratio=MAP_RATIO)
|
map_file = BuildImage(w, h, _w, h, ratio=MAP_RATIO)
|
||||||
for i in range(idx):
|
for i in range(idx):
|
||||||
map_file.paste(BuildImage(0, 0, background=f"{map_path}/{i}.png"))
|
map_file.paste(
|
||||||
|
BuildImage(0, 0, background=f"{map_path}/{i}.png")
|
||||||
|
)
|
||||||
map_file.save(f"{map_path}/map.png")
|
map_file.save(f"{map_path}/map.png")
|
||||||
else:
|
else:
|
||||||
logger.warning(f'获取原神地图失败 msg: {data["message"]}')
|
logger.warning(f'获取原神地图失败 msg: {data["message"]}')
|
||||||
@@ -205,7 +209,7 @@ async def download_map_init(
|
|||||||
async def download_resource_type():
|
async def download_resource_type():
|
||||||
resource_type_file.parent.mkdir(parents=True, exist_ok=True)
|
resource_type_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
try:
|
try:
|
||||||
response = await AsyncHttpx.get(LABEL_URL, timeout=5)
|
response = await AsyncHttpx.get(LABEL_URL, timeout=10)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
data = response.json()
|
data = response.json()
|
||||||
if data["message"] == "OK":
|
if data["message"] == "OK":
|
||||||
@@ -251,7 +255,7 @@ async def download_image(
|
|||||||
async with semaphore:
|
async with semaphore:
|
||||||
try:
|
try:
|
||||||
if not os.path.exists(path) or not is_valid or force_flag:
|
if not os.path.exists(path) or not is_valid or force_flag:
|
||||||
if await AsyncHttpx.download_file(img_url, path, timeout=5):
|
if await AsyncHttpx.download_file(img_url, path, timeout=10):
|
||||||
logger.info(f"下载原神资源图标:{img_url}")
|
logger.info(f"下载原神资源图标:{img_url}")
|
||||||
if gen_flag:
|
if gen_flag:
|
||||||
gen_icon(path)
|
gen_icon(path)
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
from nonebot import on_message, on_regex
|
from nonebot import on_message, on_regex
|
||||||
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 is_number
|
from utils.utils import is_number, get_message_text
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent, Message
|
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
|
||||||
from utils.utils import FreqLimiter, cn2py
|
from utils.utils import FreqLimiter, cn2py
|
||||||
from configs.config import Config
|
from configs.config import Config
|
||||||
from utils.manager import withdraw_message_manager
|
from utils.manager import withdraw_message_manager
|
||||||
from nonebot.params import CommandArg
|
|
||||||
from .rule import rule
|
from .rule import rule
|
||||||
import random
|
import random
|
||||||
import os
|
import os
|
||||||
@@ -58,8 +57,8 @@ _path = IMAGE_PATH / "image_management"
|
|||||||
|
|
||||||
|
|
||||||
@send_img.handle()
|
@send_img.handle()
|
||||||
async def _(event: MessageEvent, arg: Message = CommandArg()):
|
async def _(event: MessageEvent):
|
||||||
msg = arg.extract_plain_text().strip().split()
|
msg = get_message_text(event.json()).split()
|
||||||
gallery = msg[0]
|
gallery = msg[0]
|
||||||
if gallery not in Config.get_config("image_management", "IMAGE_DIR_LIST"):
|
if gallery not in Config.get_config("image_management", "IMAGE_DIR_LIST"):
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ async def get_image(img_url: str, user_id: int) -> Optional[str]:
|
|||||||
TEMP_PATH / f"pix_{user_id}_{img_url[-10:-4]}.jpg", "wb"
|
TEMP_PATH / f"pix_{user_id}_{img_url[-10:-4]}.jpg", "wb"
|
||||||
) as f:
|
) as f:
|
||||||
await f.write(response.content)
|
await f.write(response.content)
|
||||||
return f"pix_{user_id}_{img_url[-10:-4]}.jpg"
|
return TEMP_PATH / f"pix_{user_id}_{img_url[-10:-4]}.jpg"
|
||||||
except TimeoutError:
|
except TimeoutError:
|
||||||
logger.warning(f"PIX:{img_url} 图片下载超时...")
|
logger.warning(f"PIX:{img_url} 图片下载超时...")
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -149,11 +149,11 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
|||||||
f"title:{title}\n"
|
f"title:{title}\n"
|
||||||
f"author:{author}\n"
|
f"author:{author}\n"
|
||||||
f"PID:{pid}\nUID:{uid}\n"
|
f"PID:{pid}\nUID:{uid}\n"
|
||||||
f"{image(_img, 'temp')}"
|
f"{image(_img)}"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
msg_id = await pix.send(image(_img, 'temp'))
|
msg_id = await pix.send(image(_img))
|
||||||
logger.info(
|
logger.info(
|
||||||
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||||
f" 查看PIX图库PID: {pid}"
|
f" 查看PIX图库PID: {pid}"
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
from nonebot import on_regex
|
from nonebot import on_regex
|
||||||
from .data_source import get_weather_of_city, get_city_list
|
from .data_source import get_weather_of_city, get_city_list
|
||||||
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent, Message
|
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
|
||||||
from jieba import posseg
|
from jieba import posseg
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
from nonebot.params import CommandArg
|
from nonebot.params import RegexGroup
|
||||||
import re
|
from typing import Tuple, Any
|
||||||
|
|
||||||
|
|
||||||
__zx_plugin_name__ = "天气查询"
|
__zx_plugin_name__ = "天气查询"
|
||||||
@@ -27,19 +27,12 @@ __plugin_settings__ = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
weather = on_regex(r".{0,10}市?的?天气.{0,10}", priority=5, block=True)
|
weather = on_regex(r".{0,10}?(.*)的?天气.*?.{0,10}", priority=5, block=True)
|
||||||
|
|
||||||
|
|
||||||
@weather.handle()
|
@weather.handle()
|
||||||
async def _(event: MessageEvent, arg: Message = CommandArg()):
|
async def _(event: MessageEvent, reg_group: Tuple[Any, ...] = RegexGroup()):
|
||||||
msg = arg.extract_plain_text().strip()
|
msg = reg_group[0]
|
||||||
msg1 = re.search(r".*?(.*)市?的?天气.*?", msg)
|
|
||||||
msg2 = re.search(r".*?天气(.*).*?", msg)
|
|
||||||
msg1 = msg1.group(1)
|
|
||||||
msg2 = msg2.group(1)
|
|
||||||
msg = msg1 if msg1 else msg2
|
|
||||||
if msg[-1] == "的":
|
|
||||||
msg = msg[:-1]
|
|
||||||
if msg[-1] != "市":
|
if msg[-1] != "市":
|
||||||
msg += "市"
|
msg += "市"
|
||||||
city = ""
|
city = ""
|
||||||
|
|||||||
+4
-2
@@ -7,8 +7,10 @@
|
|||||||
"basic_plugins",
|
"basic_plugins",
|
||||||
"configs/path_config.py",
|
"configs/path_config.py",
|
||||||
"configs/utils",
|
"configs/utils",
|
||||||
"bot.py"
|
"bot.py",
|
||||||
|
"poetry.lock",
|
||||||
|
"pyproject.toml"
|
||||||
],
|
],
|
||||||
"add_file": [],
|
"add_file": [],
|
||||||
"delete_file": []
|
"delete_file": []
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user