2024-12-16 22:56:17 +08:00
|
|
|
import os
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
import re
|
|
|
|
|
import shutil
|
|
|
|
|
import uuid
|
|
|
|
|
|
|
|
|
|
import nonebot
|
|
|
|
|
from nonebot_plugin_alconna import UniMessage, UniMsg
|
|
|
|
|
from nonebot_plugin_uninfo import Uninfo
|
|
|
|
|
import ujson as json
|
|
|
|
|
|
|
|
|
|
from zhenxun.configs.path_config import DATA_PATH
|
|
|
|
|
from zhenxun.services.log import logger
|
|
|
|
|
from zhenxun.utils._build_image import BuildImage
|
|
|
|
|
from zhenxun.utils._image_template import ImageTemplate
|
|
|
|
|
from zhenxun.utils.http_utils import AsyncHttpx
|
2025-06-16 09:11:41 +08:00
|
|
|
from zhenxun.utils.manager.priority_manager import PriorityLifecycle
|
2024-12-16 22:56:17 +08:00
|
|
|
from zhenxun.utils.platform import PlatformUtils
|
|
|
|
|
|
|
|
|
|
BASE_PATH = DATA_PATH / "welcome_message"
|
|
|
|
|
BASE_PATH.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
|
|
|
|
driver = nonebot.get_driver()
|
|
|
|
|
|
|
|
|
|
|
2025-03-03 22:19:34 +08:00
|
|
|
def __migrate():
|
|
|
|
|
"""首次数据迁移"""
|
|
|
|
|
old_file = DATA_PATH / "custom_welcome_msg" / "custom_welcome_msg.json"
|
|
|
|
|
if not old_file.exists():
|
|
|
|
|
return
|
2024-12-16 22:56:17 +08:00
|
|
|
try:
|
|
|
|
|
old_data: dict[str, str] = json.load(old_file.open(encoding="utf8"))
|
|
|
|
|
for group_id, message in old_data.items():
|
|
|
|
|
file = BASE_PATH / "qq" / f"{group_id}" / "text.json"
|
|
|
|
|
file.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
json.dump(
|
|
|
|
|
{
|
|
|
|
|
uuid.uuid4(): {
|
|
|
|
|
"at": "[at]" in message,
|
|
|
|
|
"status": True,
|
|
|
|
|
"message": message.replace("[at]", ""),
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
file.open("w", encoding="utf8"),
|
|
|
|
|
ensure_ascii=False,
|
|
|
|
|
indent=4,
|
|
|
|
|
)
|
|
|
|
|
logger.debug("群欢迎消息数据迁移", group_id=group_id)
|
|
|
|
|
shutil.rmtree(old_file.parent.absolute())
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error("群欢迎消息数据迁移失败...", e=e)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def migrate(path: Path):
|
|
|
|
|
"""数据迁移
|
|
|
|
|
|
|
|
|
|
参数:
|
|
|
|
|
path: 路径
|
|
|
|
|
"""
|
2025-03-03 22:19:34 +08:00
|
|
|
__migrate()
|
2024-12-16 22:56:17 +08:00
|
|
|
text_file = path / "text.json"
|
2025-02-03 21:23:14 +08:00
|
|
|
if not text_file.exists():
|
|
|
|
|
return
|
2024-12-16 22:56:17 +08:00
|
|
|
with text_file.open(encoding="utf8") as f:
|
|
|
|
|
json_data = json.load(f)
|
|
|
|
|
new_data = {}
|
|
|
|
|
if "at" in json_data:
|
|
|
|
|
split_msg = re.split(r"\[image:\d\]", str(json_data["message"]))
|
|
|
|
|
data = []
|
|
|
|
|
for i in range(len(split_msg)):
|
|
|
|
|
msg = split_msg[i]
|
|
|
|
|
data.append(
|
|
|
|
|
{
|
|
|
|
|
"type": "text",
|
|
|
|
|
"text": msg,
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
image_file = path / f"{i}.png"
|
|
|
|
|
if image_file.exists():
|
|
|
|
|
data.append(
|
|
|
|
|
{
|
|
|
|
|
"type": "image",
|
|
|
|
|
"path": str(image_file),
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
new_data[uuid.uuid4()] = {
|
|
|
|
|
"at": json_data.get("at", False),
|
|
|
|
|
"status": json_data.get("status", True),
|
|
|
|
|
"message": data,
|
|
|
|
|
}
|
|
|
|
|
with text_file.open("w", encoding="utf8") as f:
|
|
|
|
|
json.dump(new_data, f, ensure_ascii=False, indent=4)
|
|
|
|
|
|
|
|
|
|
|
2025-06-16 09:11:41 +08:00
|
|
|
@PriorityLifecycle.on_startup(priority=5)
|
2024-12-16 22:56:17 +08:00
|
|
|
def _():
|
|
|
|
|
"""数据迁移
|
|
|
|
|
|
|
|
|
|
参数:
|
|
|
|
|
path: 存储路径
|
|
|
|
|
json_data: 存储数据
|
|
|
|
|
"""
|
|
|
|
|
flag_file = BASE_PATH / "flag.txt"
|
|
|
|
|
if flag_file.exists():
|
|
|
|
|
return
|
|
|
|
|
logger.info("开始迁移群欢迎消息数据...")
|
|
|
|
|
base_path = BASE_PATH
|
|
|
|
|
path_list = []
|
|
|
|
|
for platform in os.listdir(BASE_PATH):
|
|
|
|
|
base_path = base_path / platform
|
|
|
|
|
for group_id in os.listdir(base_path):
|
|
|
|
|
group_path = base_path / group_id
|
|
|
|
|
is_channel = False
|
|
|
|
|
for file in os.listdir(group_path):
|
|
|
|
|
inner_file = group_path / file
|
|
|
|
|
if inner_file.is_dir():
|
|
|
|
|
path_list.append(inner_file)
|
|
|
|
|
is_channel = True
|
|
|
|
|
if not is_channel:
|
|
|
|
|
path_list.append(group_path)
|
|
|
|
|
if path_list:
|
|
|
|
|
for path in path_list:
|
|
|
|
|
migrate(path)
|
|
|
|
|
if not flag_file.exists():
|
|
|
|
|
flag_file.touch()
|
|
|
|
|
logger.success("迁移群欢迎消息数据完成!", "")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Manager:
|
|
|
|
|
@classmethod
|
|
|
|
|
def __get_data(cls, session: Uninfo) -> dict | None:
|
|
|
|
|
"""获取存储数据
|
|
|
|
|
|
|
|
|
|
参数:
|
|
|
|
|
session: Uninfo
|
|
|
|
|
|
|
|
|
|
返回:
|
|
|
|
|
dict | None: 欢迎消息数据
|
|
|
|
|
"""
|
|
|
|
|
if not session.group:
|
|
|
|
|
return None
|
|
|
|
|
path = cls.get_path(session)
|
|
|
|
|
if not path:
|
|
|
|
|
return None
|
|
|
|
|
file = path / "text.json"
|
|
|
|
|
if not file.exists():
|
|
|
|
|
return None
|
|
|
|
|
with file.open(encoding="utf8") as f:
|
|
|
|
|
return json.load(f)
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def get_path(cls, session: Uninfo) -> Path | None:
|
|
|
|
|
"""根据Session获取存储路径
|
|
|
|
|
|
|
|
|
|
参数:
|
|
|
|
|
session: Uninfo:
|
|
|
|
|
|
|
|
|
|
返回:
|
|
|
|
|
Path: 存储路径
|
|
|
|
|
"""
|
|
|
|
|
if not session.group:
|
|
|
|
|
return None
|
|
|
|
|
platform = PlatformUtils.get_platform(session)
|
|
|
|
|
path = BASE_PATH / f"{platform}" / f"{session.group.id}"
|
|
|
|
|
if session.group.parent:
|
|
|
|
|
path = (
|
|
|
|
|
BASE_PATH
|
|
|
|
|
/ f"{platform}"
|
|
|
|
|
/ f"{session.group.parent.id}"
|
|
|
|
|
/ f"{session.group.id}"
|
|
|
|
|
)
|
|
|
|
|
path.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
return path
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
async def save(cls, path: Path, message: UniMsg):
|
|
|
|
|
"""保存群欢迎消息
|
|
|
|
|
|
|
|
|
|
参数:
|
|
|
|
|
path: 存储路径
|
|
|
|
|
message: 消息内容
|
|
|
|
|
"""
|
|
|
|
|
file = path / "text.json"
|
|
|
|
|
json_data = {}
|
|
|
|
|
if file.exists():
|
|
|
|
|
with file.open(encoding="utf8") as f:
|
|
|
|
|
json_data = json.load(f)
|
|
|
|
|
data = []
|
|
|
|
|
is_at = False
|
|
|
|
|
for msg in message.dump(True):
|
|
|
|
|
if msg["type"] == "image":
|
|
|
|
|
image_file = path / f"{uuid.uuid4()}.png"
|
|
|
|
|
await AsyncHttpx.download_file(msg["url"], image_file)
|
|
|
|
|
msg["path"] = str(image_file)
|
|
|
|
|
if not is_at and msg["type"] == "text" and "-at" in msg["text"]:
|
|
|
|
|
msg["text"] = msg["text"].replace("-at", "", 1).strip()
|
|
|
|
|
is_at = True
|
|
|
|
|
data.append(msg)
|
|
|
|
|
json_data[str(uuid.uuid4())] = {"at": is_at, "status": True, "message": data}
|
|
|
|
|
with file.open("w", encoding="utf8") as f:
|
|
|
|
|
json.dump(json_data, f, ensure_ascii=False, indent=4)
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
async def get_group_message(
|
|
|
|
|
cls, session: Uninfo, idx: int | None
|
|
|
|
|
) -> BuildImage | UniMessage | None:
|
|
|
|
|
"""获取群欢迎消息
|
|
|
|
|
|
|
|
|
|
参数:
|
|
|
|
|
session: Uninfo
|
|
|
|
|
idx: 指定id
|
|
|
|
|
|
|
|
|
|
返回:
|
|
|
|
|
list: 消息内容
|
|
|
|
|
"""
|
2025-01-07 14:36:22 +08:00
|
|
|
if not session.group:
|
|
|
|
|
return None
|
2024-12-16 22:56:17 +08:00
|
|
|
json_data = cls.__get_data(session)
|
|
|
|
|
if not json_data:
|
|
|
|
|
return None
|
|
|
|
|
if idx is not None:
|
|
|
|
|
key_list = list(json_data.keys())
|
|
|
|
|
if idx < 0 or idx > len(key_list):
|
|
|
|
|
return None
|
|
|
|
|
return UniMessage().load(json_data[key_list[idx]]["message"])
|
|
|
|
|
else:
|
|
|
|
|
msg_list = []
|
|
|
|
|
for i, uid in enumerate(json_data):
|
|
|
|
|
msg_data = json_data[uid]
|
|
|
|
|
msg_list.append(
|
|
|
|
|
[
|
|
|
|
|
i,
|
|
|
|
|
"开启" if msg_data["status"] else "关闭",
|
|
|
|
|
"是" if msg_data["at"] else "否",
|
|
|
|
|
str(UniMessage().load(msg_data["message"])),
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
if not msg_list:
|
|
|
|
|
return None
|
|
|
|
|
column_name = ["ID", "状态", "是否@", "消息"]
|
|
|
|
|
return await ImageTemplate.table_page(
|
|
|
|
|
"群欢迎消息", session.group.id, column_name, msg_list
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
async def delete_group_message(cls, session: Uninfo, idx: int) -> str | None:
|
|
|
|
|
"""获取群欢迎消息
|
|
|
|
|
|
|
|
|
|
参数:
|
|
|
|
|
session: EventSession:
|
|
|
|
|
id: 消息ID
|
|
|
|
|
|
|
|
|
|
返回:
|
|
|
|
|
list: 消息内容
|
|
|
|
|
"""
|
2025-03-03 22:19:34 +08:00
|
|
|
path = cls.get_path(session)
|
2024-12-16 22:56:17 +08:00
|
|
|
json_data = cls.__get_data(session)
|
2025-03-03 22:19:34 +08:00
|
|
|
if not json_data or not path:
|
2024-12-16 22:56:17 +08:00
|
|
|
return None
|
2025-03-03 22:19:34 +08:00
|
|
|
file = path / "text.json"
|
2024-12-16 22:56:17 +08:00
|
|
|
key_list = list(json_data.keys())
|
|
|
|
|
if idx < 0 or idx >= len(key_list):
|
|
|
|
|
return None
|
|
|
|
|
old_msg = str(UniMessage().load(json_data[key_list[idx]]["message"]))
|
|
|
|
|
for msg in json_data[key_list[idx]]["message"]:
|
|
|
|
|
if msg["type"] == "image" and msg["path"]:
|
|
|
|
|
image_path = Path(msg["path"])
|
|
|
|
|
if image_path.exists():
|
|
|
|
|
image_path.unlink()
|
|
|
|
|
del json_data[key_list[idx]]
|
|
|
|
|
with file.open("w", encoding="utf8") as f:
|
|
|
|
|
json.dump(json_data, f, ensure_ascii=False, indent=4)
|
|
|
|
|
return f"删除群组欢迎消息成功!消息内容: {old_msg}"
|