mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-10-01 17:49:58 +08:00
Merge branch 'main' into main
This commit is contained in:
+14
-15
@@ -1,20 +1,20 @@
|
||||
from utils.message_builder import image
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from nonebot import on_command
|
||||
from nonebot.rule import to_me
|
||||
import os
|
||||
import random
|
||||
|
||||
from nonebot import on_command, on_keyword
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent
|
||||
from nonebot.adapters.onebot.v11.permission import GROUP
|
||||
from utils.utils import FreqLimiter
|
||||
from configs.config import NICKNAME
|
||||
import random
|
||||
from nonebot import on_keyword
|
||||
import os
|
||||
from nonebot.rule import to_me
|
||||
|
||||
from configs.config import NICKNAME
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from utils.message_builder import image
|
||||
from utils.utils import FreqLimiter
|
||||
|
||||
__zx_plugin_name__ = "基本设置 [Hidden]"
|
||||
__plugin_usage__ = "用法: 无"
|
||||
__plugin_version__ = 0.1
|
||||
__plugin_author__ = 'HibiKier'
|
||||
__plugin_author__ = "HibiKier"
|
||||
|
||||
|
||||
_flmt = FreqLimiter(300)
|
||||
@@ -29,7 +29,7 @@ async def _(event: GroupMessageEvent):
|
||||
return
|
||||
_flmt.start_cd(event.group_id)
|
||||
await config_play_game.finish(
|
||||
image(random.choice(os.listdir(IMAGE_PATH / "dayouxi")), "dayouxi")
|
||||
image(IMAGE_PATH / random.choice(os.listdir(IMAGE_PATH / "dayouxi")))
|
||||
)
|
||||
|
||||
|
||||
@@ -40,14 +40,14 @@ self_introduction = on_command(
|
||||
|
||||
@self_introduction.handle()
|
||||
async def _():
|
||||
if NICKNAME.find('真寻') != -1:
|
||||
if NICKNAME.find("真寻") != -1:
|
||||
result = (
|
||||
"我叫绪山真寻\n"
|
||||
"你们可以叫我真寻,小真寻,哪怕你们叫我小寻子我也能接受!\n"
|
||||
"年龄的话我还是个**岁初中生(至少现在是)\n"
|
||||
"身高保密!!!(也就比美波里(姐姐..(妹妹))矮一点)\n"
|
||||
"我生日是在3月6号, 能记住的话我会很高兴的\n现在是自宅警备系的现役JC\n"
|
||||
"最好的朋友是椛!\n" + image("zhenxun")
|
||||
"最好的朋友是椛!\n" + image("zhenxun.jpg")
|
||||
)
|
||||
await self_introduction.finish(result)
|
||||
|
||||
@@ -57,5 +57,4 @@ my_wife = on_keyword({"老婆"}, rule=to_me(), priority=5, block=True)
|
||||
|
||||
@my_wife.handle()
|
||||
async def _():
|
||||
await my_wife.finish(image("laopo.jpg", "other"))
|
||||
|
||||
await my_wife.finish(image(IMAGE_PATH / "other" / "laopo.jpg"))
|
||||
|
||||
+6
-12
@@ -1,18 +1,14 @@
|
||||
|
||||
from nonebot import on_message
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
Bot,
|
||||
GroupMessageEvent,
|
||||
Message,
|
||||
MessageEvent,
|
||||
)
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message, MessageEvent
|
||||
from nonebot.rule import to_me
|
||||
|
||||
from configs.config import NICKNAME, Config
|
||||
from models.friend_user import FriendUser
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from services.log import logger
|
||||
from utils.utils import get_message_img, get_message_text
|
||||
|
||||
from .data_source import get_chat_result, hello, no_result
|
||||
from configs.config import NICKNAME, Config
|
||||
|
||||
__zx_plugin_name__ = "AI"
|
||||
__plugin_usage__ = f"""
|
||||
@@ -61,11 +57,9 @@ async def _(bot: Bot, event: MessageEvent):
|
||||
await ai.finish(hello())
|
||||
img = img[0] if img else ""
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
nickname = await GroupInfoUser.get_group_member_nickname(
|
||||
event.user_id, event.group_id
|
||||
)
|
||||
nickname = await GroupInfoUser.get_user_nickname(event.user_id, event.group_id)
|
||||
else:
|
||||
nickname = await FriendUser.get_friend_nickname(event.user_id)
|
||||
nickname = await FriendUser.get_user_nickname(event.user_id)
|
||||
if not nickname:
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
nickname = event.sender.card or event.sender.nickname
|
||||
|
||||
+21
-18
@@ -1,11 +1,13 @@
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from configs.path_config import IMAGE_PATH, DATA_PATH
|
||||
|
||||
from configs.config import NICKNAME, Config
|
||||
from configs.path_config import DATA_PATH, IMAGE_PATH
|
||||
from services.log import logger
|
||||
from utils.message_builder import image, face
|
||||
from configs.config import Config, NICKNAME
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.message_builder import face, image
|
||||
|
||||
from .utils import ai_message_manager
|
||||
|
||||
try:
|
||||
@@ -124,7 +126,9 @@ async def xie_ai(text: str) -> str:
|
||||
:param text: 问题
|
||||
:return: 青云可回复
|
||||
"""
|
||||
res = await AsyncHttpx.get(f"http://api.qingyunke.com/api.php?key=free&appid=0&msg={text}")
|
||||
res = await AsyncHttpx.get(
|
||||
f"http://api.qingyunke.com/api.php?key=free&appid=0&msg={text}"
|
||||
)
|
||||
content = ""
|
||||
try:
|
||||
data = json.loads(res.text)
|
||||
@@ -176,9 +180,9 @@ def hello() -> str:
|
||||
)
|
||||
img = random.choice(os.listdir(IMAGE_PATH / "zai"))
|
||||
if img[-4:] == ".gif":
|
||||
result += image(img, "zai")
|
||||
result += image(IMAGE_PATH / "zai" / img)
|
||||
else:
|
||||
result += image(img, "zai")
|
||||
result += image(IMAGE_PATH / "zai" / img)
|
||||
return result
|
||||
|
||||
|
||||
@@ -187,17 +191,16 @@ def no_result() -> str:
|
||||
"""
|
||||
没有回答时的回复
|
||||
"""
|
||||
return (
|
||||
random.choice(
|
||||
[
|
||||
"你在说啥子?",
|
||||
f"纯洁的{NICKNAME}没听懂",
|
||||
"下次再告诉你(下次一定)",
|
||||
"你觉得我听懂了吗?嗯?",
|
||||
"我!不!知!道!",
|
||||
]
|
||||
)
|
||||
+ image(random.choice(os.listdir(IMAGE_PATH / "noresult")), "noresult")
|
||||
return random.choice(
|
||||
[
|
||||
"你在说啥子?",
|
||||
f"纯洁的{NICKNAME}没听懂",
|
||||
"下次再告诉你(下次一定)",
|
||||
"你觉得我听懂了吗?嗯?",
|
||||
"我!不!知!道!",
|
||||
]
|
||||
) + image(
|
||||
IMAGE_PATH / "noresult" / random.choice(os.listdir(IMAGE_PATH / "noresult"))
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
from nonebot import on_command, on_regex
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GroupMessageEvent, Message
|
||||
from typing import Any, Optional, Tuple
|
||||
|
||||
import nonebot
|
||||
from nonebot import Driver, on_command, on_regex
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message, MessageEvent
|
||||
from nonebot.params import ArgStr, CommandArg, RegexGroup
|
||||
from nonebot.typing import T_State
|
||||
|
||||
from configs.config import Config
|
||||
from models.level_user import LevelUser
|
||||
from services.log import logger
|
||||
from utils.image_utils import text2image
|
||||
from utils.manager import group_manager
|
||||
from utils.message_builder import image
|
||||
from utils.utils import get_bot, is_number, scheduler
|
||||
|
||||
from .data_source import (
|
||||
BilibiliSub,
|
||||
SubManager,
|
||||
add_live_sub,
|
||||
delete_sub,
|
||||
add_up_sub,
|
||||
add_season_sub,
|
||||
add_up_sub,
|
||||
delete_sub,
|
||||
get_media_id,
|
||||
get_sub_status,
|
||||
SubManager,
|
||||
BilibiliSub,
|
||||
)
|
||||
from models.level_user import LevelUser
|
||||
from utils.manager import group_manager
|
||||
from configs.config import Config
|
||||
from utils.utils import is_number, scheduler, get_bot
|
||||
from typing import Optional, Tuple, Any
|
||||
from services.log import logger
|
||||
from nonebot import Driver
|
||||
from nonebot.params import CommandArg, ArgStr, RegexGroup
|
||||
import nonebot
|
||||
|
||||
__zx_plugin_name__ = "B站订阅"
|
||||
__plugin_usage__ = """
|
||||
@@ -168,20 +169,20 @@ async def _(
|
||||
sub_user: str = ArgStr("sub_user"),
|
||||
):
|
||||
if sub_type in ["主播", "直播"]:
|
||||
result = await BilibiliSub.delete_bilibili_sub(int(id_),sub_user,"live")
|
||||
result = await BilibiliSub.delete_bilibili_sub(int(id_), sub_user, "live")
|
||||
elif sub_type.lower() in ["up", "用户"]:
|
||||
result = await BilibiliSub.delete_bilibili_sub(int(id_),sub_user,"up")
|
||||
else: result = await BilibiliSub.delete_bilibili_sub(int(id_),sub_user)
|
||||
result = await BilibiliSub.delete_bilibili_sub(int(id_), sub_user, "up")
|
||||
else:
|
||||
result = await BilibiliSub.delete_bilibili_sub(int(id_), sub_user)
|
||||
if result:
|
||||
await del_sub.send(f"删除订阅id:{id_} 成功...")
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
f" 删除订阅 {id_}"
|
||||
)
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
f" 删除订阅 {id_}"
|
||||
)
|
||||
else:
|
||||
await del_sub.send(f"删除订阅id:{id_} 失败...")
|
||||
|
||||
|
||||
|
||||
@show_sub_info.handle()
|
||||
@@ -190,7 +191,7 @@ async def _(event: MessageEvent):
|
||||
id_ = f"{event.group_id}"
|
||||
else:
|
||||
id_ = f"{event.user_id}"
|
||||
data = await BilibiliSub.get_sub_data(id_)
|
||||
data = await BilibiliSub.filter(sub_users__contains=id_).all()
|
||||
live_rst = ""
|
||||
up_rst = ""
|
||||
season_rst = ""
|
||||
@@ -217,11 +218,9 @@ async def _(event: MessageEvent):
|
||||
)
|
||||
await show_sub_info.send(
|
||||
image(
|
||||
b64=(
|
||||
await text2image(
|
||||
live_rst + up_rst + season_rst, padding=10, color="#f9f6f2"
|
||||
)
|
||||
).pic2bs4()
|
||||
await text2image(
|
||||
live_rst + up_rst + season_rst, padding=10, color="#f9f6f2"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -277,7 +276,9 @@ async def send_sub_msg(rst: str, sub: BilibiliSub, bot: Bot):
|
||||
):
|
||||
rst = "[CQ:at,qq=all]\n" + rst
|
||||
if group_manager.get_plugin_status("bilibili_sub", group_id):
|
||||
await bot.send_group_msg(group_id=group_id, message=Message(rst))
|
||||
await bot.send_group_msg(
|
||||
group_id=group_id, message=Message(rst)
|
||||
)
|
||||
else:
|
||||
await bot.send_private_msg(user_id=int(x), message=Message(rst))
|
||||
except Exception as e:
|
||||
|
||||
@@ -1,34 +1,33 @@
|
||||
from bilireq.exceptions import ResponseCodeError
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
|
||||
from utils.manager import resources_manager
|
||||
import random
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from datetime import datetime
|
||||
from typing import Optional, Tuple
|
||||
|
||||
from utils.utils import get_bot
|
||||
from .model import BilibiliSub
|
||||
from bilireq.live import get_room_info_by_id
|
||||
from .utils import get_meta, get_user_card
|
||||
from utils.message_builder import image
|
||||
from bilireq.user import get_videos
|
||||
# from .utils import get_videos
|
||||
from bilireq import dynamic
|
||||
from typing import Optional, Tuple
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from datetime import datetime
|
||||
from utils.browser import get_browser
|
||||
from services.db_context import db
|
||||
from bilireq.exceptions import ResponseCodeError
|
||||
from bilireq.live import get_room_info_by_id
|
||||
from bilireq.user import get_videos
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
|
||||
from configs.path_config import IMAGE_PATH, TEMP_PATH
|
||||
from services.log import logger
|
||||
from utils.http_utils import AsyncHttpx
|
||||
import random
|
||||
from utils.browser import get_browser
|
||||
from utils.http_utils import AsyncHttpx, AsyncPlaywright
|
||||
from utils.manager import resources_manager
|
||||
from utils.message_builder import image
|
||||
from utils.utils import get_bot
|
||||
|
||||
from .model import BilibiliSub
|
||||
from .utils import get_meta, get_user_card
|
||||
|
||||
SEARCH_URL = "https://api.bilibili.com/x/web-interface/search/all/v2"
|
||||
|
||||
DYNAMIC_PATH = IMAGE_PATH / "bilibili_sub" / "dynamic"
|
||||
DYNAMIC_PATH.mkdir(exist_ok=True, parents=True)
|
||||
|
||||
|
||||
bilibili_search_url = "https://api.bilibili.com/x/web-interface/search/all/v2"
|
||||
|
||||
dynamic_path = IMAGE_PATH / "bilibili_sub" / "dynamic"
|
||||
dynamic_path.mkdir(exist_ok=True, parents=True)
|
||||
|
||||
|
||||
resources_manager.add_temp_dir(dynamic_path)
|
||||
resources_manager.add_temp_dir(DYNAMIC_PATH)
|
||||
|
||||
|
||||
async def add_live_sub(live_id: int, sub_user: str) -> str:
|
||||
@@ -49,7 +48,7 @@ async def add_live_sub(live_id: int, sub_user: str) -> str:
|
||||
short_id = live_info["short_id"]
|
||||
title = live_info["title"]
|
||||
live_status = live_info["live_status"]
|
||||
if await BilibiliSub.add_bilibili_sub(
|
||||
if await BilibiliSub.sub_handle(
|
||||
room_id,
|
||||
"live",
|
||||
sub_user,
|
||||
@@ -58,14 +57,14 @@ async def add_live_sub(live_id: int, sub_user: str) -> str:
|
||||
live_status=live_status,
|
||||
):
|
||||
await _get_up_status(room_id)
|
||||
uname = (await BilibiliSub.get_sub(room_id)).uname
|
||||
uname = (await BilibiliSub.get_or_none(sub_id=room_id)).uname
|
||||
return (
|
||||
"已成功订阅主播:\n"
|
||||
f"\ttitle:{title}\n"
|
||||
f"\tname: {uname}\n"
|
||||
f"\tlive_id:{room_id}\n"
|
||||
f"\tuid:{uid}"
|
||||
)
|
||||
)
|
||||
else:
|
||||
return "添加订阅失败..."
|
||||
except Exception as e:
|
||||
@@ -80,35 +79,34 @@ async def add_up_sub(uid: int, sub_user: str) -> str:
|
||||
:param sub_user: 订阅用户
|
||||
"""
|
||||
try:
|
||||
async with db.transaction():
|
||||
try:
|
||||
"""bilibili_api.user库中User类的get_user_info改为bilireq.user库的get_user_info方法"""
|
||||
user_info = await get_user_card(uid)
|
||||
except ResponseCodeError:
|
||||
return f"未找到UpId:{uid} 的信息,请检查Id是否正确"
|
||||
uname = user_info["name"]
|
||||
"""bilibili_api.user库中User类的get_dynamics改为bilireq.dynamic库的get_user_dynamics方法"""
|
||||
dynamic_info = await dynamic.get_user_dynamics(uid)
|
||||
dynamic_upload_time = 0
|
||||
if dynamic_info.get("cards"):
|
||||
dynamic_upload_time = dynamic_info["cards"][0]["desc"]["timestamp"]
|
||||
"""bilibili_api.user库中User类的get_videos改为bilireq.user库的get_videos方法"""
|
||||
video_info = await get_videos(uid)
|
||||
latest_video_created = 0
|
||||
if video_info["list"].get("vlist"):
|
||||
latest_video_created = video_info["list"]["vlist"][0]["created"]
|
||||
if await BilibiliSub.add_bilibili_sub(
|
||||
uid,
|
||||
"up",
|
||||
sub_user,
|
||||
uid=uid,
|
||||
uname=uname,
|
||||
dynamic_upload_time=dynamic_upload_time,
|
||||
latest_video_created=latest_video_created,
|
||||
):
|
||||
return "已成功订阅UP:\n" f"\tname: {uname}\n" f"\tuid:{uid}"
|
||||
else:
|
||||
return "添加订阅失败..."
|
||||
try:
|
||||
"""bilibili_api.user库中User类的get_user_info改为bilireq.user库的get_user_info方法"""
|
||||
user_info = await get_user_card(uid)
|
||||
except ResponseCodeError:
|
||||
return f"未找到UpId:{uid} 的信息,请检查Id是否正确"
|
||||
uname = user_info["name"]
|
||||
"""bilibili_api.user库中User类的get_dynamics改为bilireq.dynamic库的get_user_dynamics方法"""
|
||||
dynamic_info = await dynamic.get_user_dynamics(uid)
|
||||
dynamic_upload_time = 0
|
||||
if dynamic_info.get("cards"):
|
||||
dynamic_upload_time = dynamic_info["cards"][0]["desc"]["timestamp"]
|
||||
"""bilibili_api.user库中User类的get_videos改为bilireq.user库的get_videos方法"""
|
||||
video_info = await get_videos(uid)
|
||||
latest_video_created = 0
|
||||
if video_info["list"].get("vlist"):
|
||||
latest_video_created = video_info["list"]["vlist"][0]["created"]
|
||||
if await BilibiliSub.sub_handle(
|
||||
uid,
|
||||
"up",
|
||||
sub_user,
|
||||
uid=uid,
|
||||
uname=uname,
|
||||
dynamic_upload_time=dynamic_upload_time,
|
||||
latest_video_created=latest_video_created,
|
||||
):
|
||||
return "已成功订阅UP:\n" f"\tname: {uname}\n" f"\tuid:{uid}"
|
||||
else:
|
||||
return "添加订阅失败..."
|
||||
except Exception as e:
|
||||
logger.error(f"订阅Up uid:{uid} 发生了错误 {type(e)}:{e}")
|
||||
return "添加订阅失败..."
|
||||
@@ -121,30 +119,29 @@ async def add_season_sub(media_id: int, sub_user: str) -> str:
|
||||
:param sub_user: 订阅用户
|
||||
"""
|
||||
try:
|
||||
async with db.transaction():
|
||||
try:
|
||||
"""bilibili_api.bangumi库中get_meta改为bilireq.bangumi库的get_meta方法"""
|
||||
season_info = await get_meta(media_id)
|
||||
except ResponseCodeError:
|
||||
return f"未找到media_id:{media_id} 的信息,请检查Id是否正确"
|
||||
season_id = season_info["media"]["season_id"]
|
||||
season_current_episode = season_info["media"]["new_ep"]["index"]
|
||||
season_name = season_info["media"]["title"]
|
||||
if await BilibiliSub.add_bilibili_sub(
|
||||
media_id,
|
||||
"season",
|
||||
sub_user,
|
||||
season_name=season_name,
|
||||
season_id=season_id,
|
||||
season_current_episode=season_current_episode,
|
||||
):
|
||||
return (
|
||||
"已成功订阅番剧:\n"
|
||||
f"\ttitle: {season_name}\n"
|
||||
f"\tcurrent_episode: {season_current_episode}"
|
||||
)
|
||||
else:
|
||||
return "添加订阅失败..."
|
||||
try:
|
||||
"""bilibili_api.bangumi库中get_meta改为bilireq.bangumi库的get_meta方法"""
|
||||
season_info = await get_meta(media_id)
|
||||
except ResponseCodeError:
|
||||
return f"未找到media_id:{media_id} 的信息,请检查Id是否正确"
|
||||
season_id = season_info["media"]["season_id"]
|
||||
season_current_episode = season_info["media"]["new_ep"]["index"]
|
||||
season_name = season_info["media"]["title"]
|
||||
if await BilibiliSub.sub_handle(
|
||||
media_id,
|
||||
"season",
|
||||
sub_user,
|
||||
season_name=season_name,
|
||||
season_id=season_id,
|
||||
season_current_episode=season_current_episode,
|
||||
):
|
||||
return (
|
||||
"已成功订阅番剧:\n"
|
||||
f"\ttitle: {season_name}\n"
|
||||
f"\tcurrent_episode: {season_current_episode}"
|
||||
)
|
||||
else:
|
||||
return "添加订阅失败..."
|
||||
except Exception as e:
|
||||
logger.error(f"订阅番剧 media_id:{media_id} 发生了错误 {type(e)}:{e}")
|
||||
return "添加订阅失败..."
|
||||
@@ -171,9 +168,7 @@ async def get_media_id(keyword: str) -> dict:
|
||||
for _ in range(3):
|
||||
try:
|
||||
_season_data = {}
|
||||
response = await AsyncHttpx.get(
|
||||
bilibili_search_url, params=params, timeout=5
|
||||
)
|
||||
response = await AsyncHttpx.get(SEARCH_URL, params=params, timeout=5)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("data"):
|
||||
@@ -227,9 +222,9 @@ async def _get_live_status(id_: int) -> Optional[str]:
|
||||
room_id = live_info["room_id"]
|
||||
live_status = live_info["live_status"]
|
||||
cover = live_info["user_cover"]
|
||||
sub = await BilibiliSub.get_sub(id_)
|
||||
sub = await BilibiliSub.get_or_none(sub_id=id_)
|
||||
if sub.live_status != live_status:
|
||||
await BilibiliSub.update_sub_info(id_, live_status=live_status)
|
||||
await BilibiliSub.sub_handle(id_, live_status=live_status)
|
||||
if sub.live_status in [0, 2] and live_status == 1:
|
||||
return (
|
||||
f""
|
||||
@@ -247,7 +242,7 @@ async def _get_up_status(id_: int) -> Optional[str]:
|
||||
:param id_: 订阅 id
|
||||
:return:
|
||||
"""
|
||||
_user = await BilibiliSub.get_sub(id_)
|
||||
_user = await BilibiliSub.get_or_none(sub_id=id_)
|
||||
"""bilibili_api.user库中User类的get_user_info改为bilireq.user库的get_user_info方法"""
|
||||
user_info = await get_user_card(_user.uid)
|
||||
uname = user_info["name"]
|
||||
@@ -257,14 +252,14 @@ async def _get_up_status(id_: int) -> Optional[str]:
|
||||
video = None
|
||||
dividing_line = "\n-------------\n"
|
||||
if _user.uname != uname:
|
||||
await BilibiliSub.update_sub_info(id_, uname=uname)
|
||||
await BilibiliSub.sub_handle(id_, uname=uname)
|
||||
dynamic_img, dynamic_upload_time, link = await get_user_dynamic(_user.uid, _user)
|
||||
if video_info["list"].get("vlist"):
|
||||
video = video_info["list"]["vlist"][0]
|
||||
latest_video_created = video["created"]
|
||||
rst = ""
|
||||
if dynamic_img:
|
||||
await BilibiliSub.update_sub_info(id_, dynamic_upload_time=dynamic_upload_time)
|
||||
await BilibiliSub.sub_handle(id_, dynamic_upload_time=dynamic_upload_time)
|
||||
rst += f"{uname} 发布了动态!\n" f"{dynamic_img}\n{link}"
|
||||
if (
|
||||
latest_video_created
|
||||
@@ -273,9 +268,7 @@ async def _get_up_status(id_: int) -> Optional[str]:
|
||||
and _user.latest_video_created < latest_video_created
|
||||
):
|
||||
rst = rst + dividing_line if rst else rst
|
||||
await BilibiliSub.update_sub_info(
|
||||
id_, latest_video_created=latest_video_created
|
||||
)
|
||||
await BilibiliSub.sub_handle(id_, latest_video_created=latest_video_created)
|
||||
rst += (
|
||||
f'{image(video["pic"])}\n'
|
||||
f"{uname} 投稿了新视频啦\n"
|
||||
@@ -295,10 +288,10 @@ async def _get_season_status(id_) -> Optional[str]:
|
||||
"""bilibili_api.bangumi库中get_meta改为bilireq.bangumi库的get_meta方法"""
|
||||
season_info = await get_meta(id_)
|
||||
title = season_info["media"]["title"]
|
||||
_idx = (await BilibiliSub.get_sub(id_)).season_current_episode
|
||||
_idx = (await BilibiliSub.get_or_none(sub_id=id_)).season_current_episode
|
||||
new_ep = season_info["media"]["new_ep"]["index"]
|
||||
if new_ep != _idx:
|
||||
await BilibiliSub.update_sub_info(
|
||||
await BilibiliSub.sub_handle(
|
||||
id_, season_current_episode=new_ep, season_update_time=datetime.now()
|
||||
)
|
||||
return (
|
||||
@@ -320,55 +313,22 @@ async def get_user_dynamic(
|
||||
"""
|
||||
"""bilibili_api.user库中User类的get_dynamics改为bilireq.dynamic库的get_user_dynamics方法"""
|
||||
dynamic_info = await dynamic.get_user_dynamics(uid)
|
||||
browser = await get_browser()
|
||||
if dynamic_info.get("cards") and browser:
|
||||
if dynamic_info.get("cards"):
|
||||
dynamic_upload_time = dynamic_info["cards"][0]["desc"]["timestamp"]
|
||||
dynamic_id = dynamic_info["cards"][0]["desc"]["dynamic_id"]
|
||||
if local_user.dynamic_upload_time < dynamic_upload_time:
|
||||
context = await browser.new_context()
|
||||
page = await context.new_page()
|
||||
try:
|
||||
await page.goto(
|
||||
f"https://t.bilibili.com/{dynamic_id}",
|
||||
wait_until="networkidle",
|
||||
timeout=10000,
|
||||
)
|
||||
# await page.set_viewport_size({"width": 2560, "height": 1080, "timeout": 10000*20}) # timeout: 200s
|
||||
# 删除置顶
|
||||
# await page.evaluate(
|
||||
# """
|
||||
# xs = document.getElementsByClassName('bili-dyn-item__tag');
|
||||
# for (x of xs) {
|
||||
# x.parentNode.parentNode.remove();
|
||||
# }
|
||||
# """
|
||||
# )
|
||||
# async with page.expect_popup() as popup_info:
|
||||
# await page.locator(".bili-rich-text__content").click()
|
||||
# details_page = await popup_info.value
|
||||
await page.set_viewport_size(
|
||||
{"width": 2560, "height": 1080, "timeout": 10000 * 20}
|
||||
)
|
||||
await page.wait_for_selector(".bili-dyn-item__main")
|
||||
card = page.locator(".bili-dyn-item__main")
|
||||
await card.wait_for()
|
||||
await card.screenshot(
|
||||
path=dynamic_path / f"{local_user.sub_id}_{dynamic_upload_time}.jpg",
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"B站订阅:获取用户动态 发送错误 {type(e)}:{e}")
|
||||
finally:
|
||||
await context.close()
|
||||
await page.close()
|
||||
return (
|
||||
image(
|
||||
f"{local_user.sub_id}_{dynamic_upload_time}.jpg",
|
||||
"bilibili_sub/dynamic",
|
||||
),
|
||||
dynamic_upload_time,
|
||||
f"https://t.bilibili.com/{dynamic_id}"
|
||||
image = await AsyncPlaywright.screenshot(
|
||||
f"https://t.bilibili.com/{dynamic_id}",
|
||||
DYNAMIC_PATH / f"sub_{local_user.sub_id}.png",
|
||||
".bili-dyn-item__main",
|
||||
wait_until="networkidle",
|
||||
)
|
||||
return None, 0, ''
|
||||
return (
|
||||
image,
|
||||
dynamic_upload_time,
|
||||
f"https://t.bilibili.com/{dynamic_id}",
|
||||
)
|
||||
return None, 0, ""
|
||||
|
||||
|
||||
class SubManager:
|
||||
|
||||
+112
-186
@@ -1,43 +1,58 @@
|
||||
from services.log import logger
|
||||
from services.db_context import db
|
||||
from datetime import datetime
|
||||
from typing import Optional, List
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
from tortoise import fields
|
||||
|
||||
from services.db_context import Model
|
||||
from services.log import logger
|
||||
|
||||
|
||||
class BilibiliSub(db.Model):
|
||||
__tablename__ = "bilibili_sub"
|
||||
class BilibiliSub(Model):
|
||||
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
sub_id = db.Column(db.Integer(), nullable=False)
|
||||
sub_type = db.Column(db.String(), nullable=False)
|
||||
# 订阅用户
|
||||
sub_users = db.Column(db.String(), nullable=False)
|
||||
# 直播
|
||||
live_short_id = db.Column(db.Integer())
|
||||
live_status = db.Column(db.Integer)
|
||||
# 主播/UP
|
||||
uid = db.Column(db.BigInteger())
|
||||
uname = db.Column(db.String())
|
||||
latest_video_created = db.Column(db.BigInteger()) # 视频上传时间
|
||||
dynamic_upload_time = db.Column(db.BigInteger(), default=0) # 动态发布时间
|
||||
# 番剧
|
||||
season_name = db.Column(db.String())
|
||||
season_id = db.Column(db.Integer())
|
||||
season_current_episode = db.Column(db.String())
|
||||
season_update_time = db.Column(db.DateTime())
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
sub_id = fields.IntField()
|
||||
"""订阅id"""
|
||||
sub_type = fields.CharField(255)
|
||||
"""订阅类型"""
|
||||
sub_users = fields.TextField()
|
||||
"""订阅用户"""
|
||||
live_short_id = fields.IntField(null=True)
|
||||
"""直播短id"""
|
||||
live_status = fields.IntField(null=True)
|
||||
"""直播状态 0: 停播 1: 直播"""
|
||||
uid = fields.BigIntField(null=True)
|
||||
"""主播/UP UID"""
|
||||
uname = fields.CharField(255, null=True)
|
||||
"""主播/UP 名称"""
|
||||
latest_video_created = fields.BigIntField(null=True)
|
||||
"""最后视频上传时间"""
|
||||
dynamic_upload_time = fields.BigIntField(null=True, default=0)
|
||||
"""动态发布时间"""
|
||||
season_name = fields.CharField(255, null=True)
|
||||
"""番剧名称"""
|
||||
season_id = fields.IntField(null=True)
|
||||
"""番剧id"""
|
||||
season_current_episode = fields.CharField(255, null=True)
|
||||
"""番剧最新集数"""
|
||||
season_update_time = fields.DateField(null=True)
|
||||
"""番剧更新日期"""
|
||||
|
||||
_idx1 = db.Index("bilibili_sub_idx1", "sub_id", "sub_type", unique=True)
|
||||
class Meta:
|
||||
table = "bilibili_sub"
|
||||
table_description = "B站订阅数据表"
|
||||
unique_together = ("sub_id", "sub_type")
|
||||
|
||||
@classmethod
|
||||
async def add_bilibili_sub(
|
||||
async def sub_handle(
|
||||
cls,
|
||||
sub_id: int,
|
||||
sub_type: str,
|
||||
sub_user: str,
|
||||
sub_type: Optional[str] = None,
|
||||
sub_user: str = "",
|
||||
*,
|
||||
live_short_id: Optional[int] = None,
|
||||
live_status: Optional[int] = None,
|
||||
dynamic_upload_time: Optional[int] = None,
|
||||
dynamic_upload_time: int = 0,
|
||||
uid: Optional[int] = None,
|
||||
uname: Optional[str] = None,
|
||||
latest_video_created: Optional[int] = None,
|
||||
@@ -64,50 +79,60 @@ class BilibiliSub(db.Model):
|
||||
:param season_current_episode: 番剧最新集数
|
||||
:param season_update_time: 番剧更新时间
|
||||
"""
|
||||
try:
|
||||
query = (
|
||||
await cls.query.where( (cls.sub_id == sub_id) & (cls.sub_type == sub_type) )
|
||||
.with_for_update()
|
||||
.gino.first()
|
||||
)
|
||||
# try:
|
||||
data = {
|
||||
"sub_type": sub_type,
|
||||
"sub_user": sub_user,
|
||||
"live_short_id": live_short_id,
|
||||
"live_status": live_status,
|
||||
"dynamic_upload_time": dynamic_upload_time,
|
||||
"uid": uid,
|
||||
"uname": uname,
|
||||
"latest_video_created": latest_video_created,
|
||||
"season_name": season_name,
|
||||
"season_id": season_id,
|
||||
"season_current_episode": season_current_episode,
|
||||
"season_update_time": season_update_time,
|
||||
}
|
||||
if sub_user:
|
||||
sub_user = sub_user if sub_user[-1] == "," else f"{sub_user},"
|
||||
if query:
|
||||
if sub_user not in query.sub_users:
|
||||
sub_users = query.sub_users + sub_user
|
||||
await query.update(sub_users=sub_users).apply()
|
||||
else:
|
||||
sub = await cls.create(
|
||||
sub_id=sub_id, sub_type=sub_type, sub_users=sub_user
|
||||
)
|
||||
await sub.update(
|
||||
live_short_id=live_short_id
|
||||
if live_short_id
|
||||
else sub.live_short_id,
|
||||
live_status=live_status if live_status else sub.live_status,
|
||||
dynamic_upload_time=dynamic_upload_time
|
||||
if dynamic_upload_time
|
||||
else sub.dynamic_upload_time,
|
||||
uid=uid if uid else sub.uid,
|
||||
uname=uname if uname else sub.uname,
|
||||
latest_video_created=latest_video_created
|
||||
if latest_video_created
|
||||
else sub.latest_video_created,
|
||||
season_update_time=season_update_time
|
||||
if season_update_time
|
||||
else sub.season_update_time,
|
||||
season_current_episode=season_current_episode
|
||||
if season_current_episode
|
||||
else sub.season_current_episode,
|
||||
season_id=season_id if season_id else sub.season_id,
|
||||
season_name=season_name if season_name else sub.season_name,
|
||||
).apply()
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.info(f"bilibili_sub 添加订阅错误 {type(e)}: {e}")
|
||||
return False
|
||||
sub = None
|
||||
if sub_type:
|
||||
sub = await cls.get_or_none(sub_id=sub_id, sub_type=sub_type)
|
||||
else:
|
||||
sub = await cls.get_or_none(sub_id=sub_id)
|
||||
if sub:
|
||||
sub_users = sub.sub_users + sub_user
|
||||
data["sub_type"] = sub_type or sub.sub_type
|
||||
data["sub_user"] = sub_users
|
||||
data["live_short_id"] = live_short_id or sub.live_short_id
|
||||
data["live_status"] = (
|
||||
live_status if live_status is not None else sub.live_status
|
||||
)
|
||||
data["dynamic_upload_time"] = dynamic_upload_time or sub.dynamic_upload_time
|
||||
data["uid"] = uid or sub.uid
|
||||
data["uname"] = uname or sub.uname
|
||||
data["latest_video_created"] = (
|
||||
latest_video_created or sub.latest_video_created
|
||||
)
|
||||
data["season_name"] = season_name or sub.season_name
|
||||
data["season_id"] = season_id or sub.season_id
|
||||
data["season_current_episode"] = (
|
||||
season_current_episode or sub.season_current_episode
|
||||
)
|
||||
data["season_update_time"] = season_update_time or sub.season_update_time
|
||||
else:
|
||||
await cls.create(sub_id=sub_id, sub_type=sub_type, sub_users=sub_user)
|
||||
await cls.update_or_create(sub_id=sub_id, defaults=data)
|
||||
return True
|
||||
# except Exception as e:
|
||||
# logger.info(f"bilibili_sub 添加订阅错误 {type(e)}: {e}")
|
||||
# return False
|
||||
|
||||
@classmethod
|
||||
async def delete_bilibili_sub(cls, sub_id: int, sub_user: str,sub_type: Optional[str] = None) -> bool:
|
||||
async def delete_bilibili_sub(
|
||||
cls, sub_id: int, sub_user: str, sub_type: Optional[str] = None
|
||||
) -> bool:
|
||||
"""
|
||||
说明:
|
||||
删除订阅
|
||||
@@ -116,129 +141,30 @@ class BilibiliSub(db.Model):
|
||||
:param sub_user: 删除此条目的用户
|
||||
"""
|
||||
try:
|
||||
async with db.transaction():
|
||||
if sub_type:
|
||||
query = (
|
||||
await cls.query.where(
|
||||
(cls.sub_id == sub_id) & (cls.sub_users.contains(sub_user) & (cls.sub_type == sub_type))
|
||||
)
|
||||
.with_for_update()
|
||||
.gino.first()
|
||||
)
|
||||
else:
|
||||
query = (
|
||||
await cls.query.where(
|
||||
(cls.sub_id == sub_id) & (cls.sub_users.contains(sub_user))
|
||||
)
|
||||
.with_for_update()
|
||||
.gino.first()
|
||||
)
|
||||
if not query:
|
||||
return False
|
||||
await query.update(
|
||||
sub_users=query.sub_users.replace(f"{sub_user},", "")
|
||||
).apply()
|
||||
if not query.sub_users.strip():
|
||||
await query.delete()
|
||||
return True
|
||||
if sub_type:
|
||||
sub = await cls.filter(
|
||||
sub_id=sub_id, sub_type=sub_type, sub_users__contains=sub_user
|
||||
).first()
|
||||
else:
|
||||
sub = await cls.filter(
|
||||
sub_id=sub_id, sub_users__contains=sub_user
|
||||
).first()
|
||||
if not sub:
|
||||
return False
|
||||
sub.sub_users = sub.sub_users.replace(f"{sub_user},", "")
|
||||
if sub.sub_users.strip():
|
||||
await sub.save(update_fields=["sub_users"])
|
||||
else:
|
||||
await sub.delete()
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.info(f"bilibili_sub 删除订阅错误 {type(e)}: {e}")
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def get_sub(cls, sub_id: int) -> Optional["BilibiliSub"]:
|
||||
"""
|
||||
说明:
|
||||
获取订阅对象
|
||||
参数:
|
||||
:param sub_id: 订阅 id
|
||||
"""
|
||||
return await cls.query.where(cls.sub_id == sub_id).gino.first()
|
||||
|
||||
@classmethod
|
||||
async def get_sub_data(cls, id_: str) -> List["BilibiliSub"]:
|
||||
"""
|
||||
获取 id_ 订阅的所有内容
|
||||
:param id_: id
|
||||
"""
|
||||
query = cls.query.where(cls.sub_users.contains(id_))
|
||||
return await query.gino.all()
|
||||
|
||||
@classmethod
|
||||
async def update_sub_info(
|
||||
cls,
|
||||
sub_id: int,
|
||||
*,
|
||||
live_short_id: Optional[int] = None,
|
||||
live_status: Optional[int] = None,
|
||||
dynamic_upload_time: Optional[int] = None,
|
||||
uid: Optional[int] = None,
|
||||
uname: Optional[str] = None,
|
||||
latest_video_created: Optional[int] = None,
|
||||
season_name: Optional[str] = None,
|
||||
season_id: Optional[int] = None,
|
||||
season_current_episode: Optional[str] = None,
|
||||
season_update_time: Optional[datetime] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
说明:
|
||||
更新订阅信息
|
||||
参数:
|
||||
:param sub_id: 订阅名称,房间号,番剧号等
|
||||
:param live_short_id: 直接短 id
|
||||
:param live_status: 主播开播状态
|
||||
:param dynamic_upload_time: 主播/UP最新动态时间
|
||||
:param uid: 主播/UP uid
|
||||
:param uname: 用户名称
|
||||
:param latest_video_created: 最新视频上传时间
|
||||
:param season_name: 番剧名称
|
||||
:param season_id: 番剧 season_id
|
||||
:param season_current_episode: 番剧最新集数
|
||||
:param season_update_time: 番剧更新时间
|
||||
"""
|
||||
try:
|
||||
async with db.transaction():
|
||||
sub = (
|
||||
await cls.query.where(cls.sub_id == sub_id)
|
||||
.with_for_update()
|
||||
.gino.first()
|
||||
)
|
||||
if sub:
|
||||
await sub.update(
|
||||
live_short_id=live_short_id
|
||||
if live_short_id is not None
|
||||
else sub.live_short_id,
|
||||
live_status=live_status
|
||||
if live_status is not None
|
||||
else sub.live_status,
|
||||
dynamic_upload_time=dynamic_upload_time
|
||||
if dynamic_upload_time is not None
|
||||
else sub.dynamic_upload_time,
|
||||
uid=uid if uid is not None else sub.uid,
|
||||
uname=uname if uname is not None else sub.uname,
|
||||
latest_video_created=latest_video_created
|
||||
if latest_video_created is not None
|
||||
else sub.latest_video_created,
|
||||
season_update_time=season_update_time
|
||||
if season_update_time is not None
|
||||
else sub.season_update_time,
|
||||
season_current_episode=season_current_episode
|
||||
if season_current_episode is not None
|
||||
else sub.season_current_episode,
|
||||
season_id=season_id if season_id is not None else sub.season_id,
|
||||
season_name=season_name
|
||||
if season_name is not None
|
||||
else sub.season_name,
|
||||
).apply()
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.info(f"bilibili_sub 更新订阅错误 {type(e)}: {e}")
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def get_all_sub_data(
|
||||
cls,
|
||||
) -> "List[BilibiliSub], List[BilibiliSub], List[BilibiliSub]":
|
||||
) -> Tuple[List["BilibiliSub"], List["BilibiliSub"], List["BilibiliSub"]]:
|
||||
"""
|
||||
说明:
|
||||
分类获取所有数据
|
||||
@@ -246,7 +172,7 @@ class BilibiliSub(db.Model):
|
||||
live_data = []
|
||||
up_data = []
|
||||
season_data = []
|
||||
query = await cls.query.gino.all()
|
||||
query = await cls.all()
|
||||
for x in query:
|
||||
if x.sub_type == "live":
|
||||
live_data.append(x)
|
||||
|
||||
@@ -1,28 +1,30 @@
|
||||
from datetime import datetime
|
||||
from typing import Any, Tuple
|
||||
|
||||
from nonebot import on_command, on_message, on_regex
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
Bot,
|
||||
Event,
|
||||
MessageEvent,
|
||||
GroupMessageEvent,
|
||||
Message,
|
||||
Bot,
|
||||
MessageEvent,
|
||||
)
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.message import run_preprocessor
|
||||
from nonebot.params import CommandArg, RegexGroup
|
||||
from nonebot.permission import SUPERUSER
|
||||
|
||||
from configs.config import NICKNAME, Config
|
||||
from models.ban_user import BanUser
|
||||
from services.log import logger
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.manager import group_manager
|
||||
from utils.utils import get_message_text, is_number
|
||||
from nonebot.params import RegexGroup, CommandArg
|
||||
from .utils import black_word_manager
|
||||
from nonebot import on_command, on_message, on_regex
|
||||
from configs.config import Config, NICKNAME
|
||||
from nonebot.permission import SUPERUSER
|
||||
from .data_source import show_black_text_image, set_user_punish
|
||||
from services.log import logger
|
||||
from models.ban_user import BanUser
|
||||
from datetime import datetime
|
||||
from utils.message_builder import image
|
||||
from .model import BlackWord
|
||||
from typing import Tuple, Any
|
||||
from utils.utils import get_message_text, is_number
|
||||
|
||||
from .data_source import set_user_punish, show_black_text_image
|
||||
from .model import BlackWord
|
||||
from .utils import black_word_manager
|
||||
|
||||
__zx_plugin_name__ = "敏感词检测"
|
||||
__plugin_usage__ = """
|
||||
@@ -38,7 +40,7 @@ usage:
|
||||
设置惩罚id需要通过 '记录名单u:xxxxxxxx' 获取
|
||||
指令:
|
||||
记录名单
|
||||
设置惩罚 [user_id] [id] [punish_level]
|
||||
设置惩罚 [user_id] [下标] [惩罚等级]
|
||||
示例:记录名单
|
||||
示例:记录名单u:12345678
|
||||
示例:设置惩罚 12345678 1 4
|
||||
@@ -150,24 +152,32 @@ async def _(
|
||||
matcher: Matcher,
|
||||
event: Event,
|
||||
):
|
||||
msg = get_message_text(event.json())
|
||||
if (
|
||||
isinstance(event, MessageEvent)
|
||||
and event.is_tome()
|
||||
and matcher.plugin_name == "black_word"
|
||||
and not await BanUser.is_ban(event.user_id)
|
||||
and str(event.user_id) not in bot.config.superusers
|
||||
and not get_message_text(event.json()).startswith("原神绑定")
|
||||
and not msg.startswith("原神绑定")
|
||||
):
|
||||
# 屏蔽群权限-1的群
|
||||
if isinstance(event, GroupMessageEvent) and group_manager.get_group_level(event.group_id) < 0:
|
||||
return
|
||||
user_id = event.user_id
|
||||
group_id = event.group_id if isinstance(event, GroupMessageEvent) else None
|
||||
msg = get_message_text(event.json())
|
||||
if await black_word_manager.check(user_id, group_id, msg) and Config.get_config(
|
||||
"black_word", "CONTAIN_BLACK_STOP_PROPAGATION"
|
||||
# if str(event.user_id) not in bot.config.superusers:
|
||||
# return logger.debug(f"超级用户跳过黑名单词汇检查 Message: {msg}", target=event.user_id)
|
||||
if (
|
||||
event.is_tome()
|
||||
and matcher.plugin_name == "black_word"
|
||||
and not await BanUser.is_ban(event.user_id)
|
||||
):
|
||||
matcher.stop_propagation()
|
||||
# 屏蔽群权限-1的群
|
||||
if (
|
||||
isinstance(event, GroupMessageEvent)
|
||||
and group_manager.get_group_level(event.group_id) < 0
|
||||
):
|
||||
return
|
||||
user_id = event.user_id
|
||||
group_id = event.group_id if isinstance(event, GroupMessageEvent) else None
|
||||
msg = get_message_text(event.json())
|
||||
if await black_word_manager.check(
|
||||
user_id, group_id, msg
|
||||
) and Config.get_config("black_word", "CONTAIN_BLACK_STOP_PROPAGATION"):
|
||||
matcher.stop_propagation()
|
||||
|
||||
|
||||
@show_black.handle()
|
||||
|
||||
+56
-62
@@ -1,47 +1,34 @@
|
||||
from services.db_context import db
|
||||
from typing import Optional, List
|
||||
from datetime import datetime, timedelta
|
||||
from typing import List, Optional
|
||||
|
||||
from tortoise import fields
|
||||
|
||||
from services.db_context import Model
|
||||
|
||||
|
||||
class BlackWord(db.Model):
|
||||
__tablename__ = "black_word"
|
||||
class BlackWord(Model):
|
||||
# __tablename__ = "black_word"
|
||||
|
||||
id = db.Column(db.Integer(), primary_key=True, autoincrement=True)
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False, primary_key=True)
|
||||
group_id = db.Column(db.BigInteger())
|
||||
plant_text = db.Column(db.String())
|
||||
black_word = db.Column(db.String())
|
||||
punish = db.Column(db.String(), default="")
|
||||
punish_level = db.Column(db.Integer())
|
||||
create_time = db.Column(db.DateTime(timezone=True), nullable=False)
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
"""用户id"""
|
||||
group_id = fields.BigIntField(null=True)
|
||||
"""群聊id"""
|
||||
plant_text = fields.TextField()
|
||||
"""检测文本"""
|
||||
black_word = fields.TextField()
|
||||
"""黑名单词语"""
|
||||
punish = fields.TextField(default="")
|
||||
"""惩罚内容"""
|
||||
punish_level = fields.IntField()
|
||||
"""惩罚等级"""
|
||||
create_time = fields.DatetimeField(auto_now_add=True)
|
||||
"""创建时间"""
|
||||
|
||||
@classmethod
|
||||
async def add_user_black_word(
|
||||
cls,
|
||||
user_qq: int,
|
||||
group_id: Optional[int],
|
||||
black_word: str,
|
||||
plant_text: str,
|
||||
punish_level: int,
|
||||
):
|
||||
"""
|
||||
说明:
|
||||
添加用户发送的敏感词
|
||||
参数:
|
||||
:param user_qq: 用户id
|
||||
:param group_id: 群号
|
||||
:param black_word: 黑名单词汇
|
||||
:param plant_text: 消息文本
|
||||
:param punish_level: 惩罚等级
|
||||
"""
|
||||
await cls.create(
|
||||
user_qq=user_qq,
|
||||
group_id=group_id,
|
||||
plant_text=plant_text,
|
||||
black_word=black_word,
|
||||
punish_level=punish_level,
|
||||
create_time=datetime.now(),
|
||||
)
|
||||
class Meta:
|
||||
table = "black_word"
|
||||
table_description = "惩罚机制数据表"
|
||||
|
||||
@classmethod
|
||||
async def set_user_punish(
|
||||
@@ -63,17 +50,21 @@ class BlackWord(db.Model):
|
||||
user = None
|
||||
if (not black_word and not id_) or not punish:
|
||||
return False
|
||||
query = cls.query.where(cls.user_qq == user_qq).with_for_update()
|
||||
if black_word:
|
||||
user = await query.where(cls.black_word == black_word).order_by(cls.id.desc()).gino.first()
|
||||
user = (
|
||||
await cls.filter(user_qq=user_qq, black_word=black_word)
|
||||
.order_by("id")
|
||||
.first()
|
||||
)
|
||||
elif id_:
|
||||
user_list = await query.gino.all()
|
||||
user_list = await cls.filter(user_qq=user_qq).order_by("id").all()
|
||||
if len(user_list) == 0 or (id_ < 0 or id_ > len(user_list)):
|
||||
return False
|
||||
user = user_list[id_]
|
||||
if not user:
|
||||
return False
|
||||
await user.update(punish=cls.punish + punish + " ").apply()
|
||||
user.punish = f"{user.punish}{punish} "
|
||||
await user.save(update_fields=["punish"])
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
@@ -88,15 +79,14 @@ class BlackWord(db.Model):
|
||||
:param days: 周期天数
|
||||
:param punish_level: 惩罚等级
|
||||
"""
|
||||
setattr(BlackWord, "count", db.func.count(cls.id).label("count"))
|
||||
query = cls.select("count").where(
|
||||
(cls.user_qq == user_qq)
|
||||
& (cls.punish_level != -1)
|
||||
& (cls.create_time > datetime.now() - timedelta(days=days))
|
||||
query = cls.filter(
|
||||
user_qq=user_qq,
|
||||
create_time__gte=datetime.now() - timedelta(days=days),
|
||||
punish_level__not_in=[-1],
|
||||
)
|
||||
if punish_level is not None:
|
||||
query = query.where(cls.punish_level == punish_level)
|
||||
return (await query.gino.first())[0]
|
||||
query = query.filter(punish_level=punish_level)
|
||||
return await query.count()
|
||||
|
||||
@classmethod
|
||||
async def get_user_punish_level(cls, user_qq: int, days: int = 7) -> Optional[int]:
|
||||
@@ -108,12 +98,14 @@ class BlackWord(db.Model):
|
||||
:param days: 周期天数
|
||||
"""
|
||||
if (
|
||||
query := await cls.query.where(cls.user_qq == user_qq)
|
||||
.where(cls.create_time > datetime.now() - timedelta(days=days))
|
||||
.order_by(cls.id.desc())
|
||||
.gino.first()
|
||||
user := await cls.filter(
|
||||
user_qq=user_qq,
|
||||
create_time__gte=datetime.now() - timedelta(days=days),
|
||||
)
|
||||
.order_by("id")
|
||||
.first()
|
||||
):
|
||||
return query.punish_level
|
||||
return user.punish_level
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
@@ -133,16 +125,18 @@ class BlackWord(db.Model):
|
||||
:param date: 日期
|
||||
:param date_type: 日期查询类型
|
||||
"""
|
||||
query = cls.query
|
||||
query = cls
|
||||
if user_qq:
|
||||
query = query.where(cls.user_qq == user_qq)
|
||||
query = query.filter(user_qq=user_qq)
|
||||
if group_id:
|
||||
query = query.where(cls.group_id == group_id)
|
||||
query = query.filter(group_id=group_id)
|
||||
if date:
|
||||
if date_type == "=":
|
||||
query = query.where(cls.create_time == date)
|
||||
query = query.filter(
|
||||
create_time__range=[date, date + timedelta(days=1)]
|
||||
)
|
||||
elif date_type == ">":
|
||||
query = query.where(cls.create_time > date)
|
||||
query = query.filter(create_time__gte=date)
|
||||
elif date_type == "<":
|
||||
query = query.where(cls.create_time < date)
|
||||
return await query.gino.all()
|
||||
query = query.filter(create_time__lte=date)
|
||||
return await query.order_by("id").all()
|
||||
|
||||
+37
-23
@@ -1,15 +1,18 @@
|
||||
from utils.utils import cn2py, get_bot
|
||||
from configs.path_config import DATA_PATH
|
||||
from typing import Optional, Union, Tuple
|
||||
from .model import BlackWord
|
||||
from configs.config import Config
|
||||
from pathlib import Path
|
||||
from services.log import logger
|
||||
from models.ban_user import BanUser
|
||||
from nonebot.adapters.onebot.v11 import ActionFailed
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from utils.http_utils import AsyncHttpx
|
||||
import random
|
||||
from pathlib import Path
|
||||
from typing import Optional, Tuple, Union
|
||||
|
||||
from nonebot.adapters.onebot.v11 import ActionFailed
|
||||
|
||||
from configs.config import Config
|
||||
from configs.path_config import DATA_PATH
|
||||
from models.ban_user import BanUser
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from services.log import logger
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.utils import cn2py, get_bot
|
||||
|
||||
from .model import BlackWord
|
||||
|
||||
try:
|
||||
import ujson as json
|
||||
@@ -49,7 +52,7 @@ class BlackWordManager:
|
||||
"hanbi",
|
||||
"hanpi",
|
||||
"laji",
|
||||
"fw"
|
||||
"fw",
|
||||
],
|
||||
"5": [],
|
||||
}
|
||||
@@ -94,9 +97,9 @@ class BlackWordManager:
|
||||
user_id, group_id, data[0], message, int(data[1])
|
||||
)
|
||||
return True
|
||||
if Config.get_config(
|
||||
"black_word", "ALAPI_CHECK_FLAG"
|
||||
) and not await check_text(message):
|
||||
if Config.get_config("black_word", "ALAPI_CHECK_FLAG") and not await check_text(
|
||||
message
|
||||
):
|
||||
await send_msg(
|
||||
0, None, f"USER {user_id} GROUP {group_id} ALAPI 疑似检测:{message}"
|
||||
)
|
||||
@@ -146,8 +149,12 @@ async def _add_user_black_word(
|
||||
"black_word", "AUTO_ADD_PUNISH_LEVEL"
|
||||
) and user_count > Config.get_config("black_word", "ADD_PUNISH_LEVEL_TO_COUNT"):
|
||||
punish_level -= 1
|
||||
await BlackWord.add_user_black_word(
|
||||
user_id, group_id, black_word, message, punish_level
|
||||
await BlackWord.create(
|
||||
user_qq=user_id,
|
||||
group_id=group_id,
|
||||
plant_text=message,
|
||||
black_word=black_word,
|
||||
punish_level=punish_level,
|
||||
)
|
||||
logger.info(
|
||||
f"已将 USER {user_id} GROUP {group_id} 添加至黑名单词汇记录 Black_word:{black_word} Plant_text:{message}"
|
||||
@@ -172,7 +179,9 @@ async def _punish_handle(
|
||||
# 用户周期内触发punish_level级惩罚的次数
|
||||
user_count = await BlackWord.get_user_count(user_id, cycle_days, punish_level)
|
||||
# 获取最近一次的惩罚等级,将在此基础上增加
|
||||
punish_level = await BlackWord.get_user_punish_level(user_id, cycle_days) or punish_level
|
||||
punish_level = (
|
||||
await BlackWord.get_user_punish_level(user_id, cycle_days) or punish_level
|
||||
)
|
||||
# 容忍次数:List[int]
|
||||
tolerate_count = Config.get_config("black_word", "TOLERATE_COUNT")
|
||||
if not tolerate_count or len(tolerate_count) < 5:
|
||||
@@ -226,15 +235,17 @@ async def _get_punish(
|
||||
ban_4_duration = Config.get_config("black_word", "BAN_4_DURATION")
|
||||
# 口头警告内容
|
||||
warning_result = Config.get_config("black_word", "WARNING_RESULT")
|
||||
try:
|
||||
uname = (await GroupInfoUser.get_member_info(user_id, group_id)).user_name
|
||||
except AttributeError:
|
||||
if user := await GroupInfoUser.get_or_none(user_qq=user_id, group_id=group_id):
|
||||
uname = user.user_name
|
||||
else:
|
||||
uname = user_id
|
||||
# 永久ban
|
||||
if id_ == 1:
|
||||
if str(user_id) not in bot.config.superusers:
|
||||
await BanUser.ban(user_id, 10, 99999999)
|
||||
await send_msg(user_id, group_id, f"BlackWordChecker 永久ban USER {uname}({user_id})")
|
||||
await send_msg(
|
||||
user_id, group_id, f"BlackWordChecker 永久ban USER {uname}({user_id})"
|
||||
)
|
||||
logger.info(f"BlackWord 永久封禁 USER {user_id}...")
|
||||
# 删除好友(有的话
|
||||
elif id_ == 2:
|
||||
@@ -319,4 +330,7 @@ async def check_text(text: str) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
black_word_manager = BlackWordManager(DATA_PATH / "black_word" / "black_word.json", DATA_PATH / "black_word" / "black_py.json")
|
||||
black_word_manager = BlackWordManager(
|
||||
DATA_PATH / "black_word" / "black_word.json",
|
||||
DATA_PATH / "black_word" / "black_py.json",
|
||||
)
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from configs.config import Config
|
||||
from bs4 import BeautifulSoup
|
||||
import platform
|
||||
|
||||
# if platform.system() == "Windows":
|
||||
# import asyncio
|
||||
#
|
||||
# asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
||||
|
||||
from configs.config import Config
|
||||
from utils.http_utils import AsyncHttpx
|
||||
|
||||
url = "http://www.eclzz.love"
|
||||
|
||||
@@ -28,10 +22,7 @@ async def get_bt_info(keyword: str, page: int):
|
||||
for item in item_lst[:bt_max_num]:
|
||||
divs = item.find_all("div")
|
||||
title = (
|
||||
str(divs[0].find("a").text)
|
||||
.replace("<em>", "")
|
||||
.replace("</em>", "")
|
||||
.strip()
|
||||
str(divs[0].find("a").text).replace("<em>", "").replace("</em>", "").strip()
|
||||
)
|
||||
spans = divs[2].find_all("span")
|
||||
type_ = spans[0].text
|
||||
|
||||
@@ -65,4 +65,4 @@ async def _():
|
||||
mes = "[[_task|genshin_alc]]" + alc_img
|
||||
for gid in gl:
|
||||
if group_manager.check_group_task_status(gid, "genshin_alc"):
|
||||
await bot.send_group_msg(group_id=int(gid), message="" + mes)
|
||||
await bot.send_group_msg(group_id=int(gid), message=mes)
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
from nonebot import on_command, Driver
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, Message, GroupMessageEvent
|
||||
from utils.message_builder import image
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.browser import get_browser
|
||||
from configs.path_config import IMAGE_PATH
|
||||
import nonebot
|
||||
from services.log import logger
|
||||
from nonebot.permission import SUPERUSER
|
||||
from typing import List
|
||||
from datetime import datetime, timedelta
|
||||
import os
|
||||
import asyncio
|
||||
import os
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
from typing import List
|
||||
|
||||
import nonebot
|
||||
from nonebot import Driver, on_command
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message, MessageEvent
|
||||
from nonebot.permission import SUPERUSER
|
||||
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from services.log import logger
|
||||
from utils.browser import get_browser
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.message_builder import image
|
||||
|
||||
__zx_plugin_name__ = "今日素材"
|
||||
__plugin_usage__ = """
|
||||
@@ -114,5 +115,3 @@ def get_background_height(weapons_img: List[str]) -> int:
|
||||
last_weapon.save(weapons_img[-1])
|
||||
|
||||
return height
|
||||
|
||||
|
||||
|
||||
@@ -1,219 +1,49 @@
|
||||
from services.db_context import db
|
||||
from typing import Optional, Union, List
|
||||
from datetime import datetime, timedelta
|
||||
import random
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Optional
|
||||
|
||||
import pytz
|
||||
from tortoise import fields
|
||||
from tortoise.contrib.postgres.functions import Random
|
||||
|
||||
from services.db_context import Model
|
||||
|
||||
|
||||
class Genshin(db.Model):
|
||||
__tablename__ = "genshin"
|
||||
class Genshin(Model):
|
||||
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||
uid = db.Column(db.BigInteger())
|
||||
mys_id = db.Column(db.BigInteger())
|
||||
cookie = db.Column(db.String(), default="")
|
||||
today_query_uid = db.Column(db.String(), default="") # 该cookie今日查询的uid
|
||||
auto_sign = db.Column(db.Boolean(), default=False)
|
||||
auto_sign_time = db.Column(db.DateTime(timezone=True))
|
||||
resin_remind = db.Column(db.Boolean(), default=False) # 树脂提醒
|
||||
resin_recovery_time = db.Column(db.DateTime(timezone=True)) # 满树脂提醒日期
|
||||
bind_group = db.Column(db.BigInteger())
|
||||
login_ticket = db.Column(db.String(), default="")
|
||||
stuid = db.Column(db.String(), default="")
|
||||
stoken = db.Column(db.String(), default="")
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
"""用户id"""
|
||||
uid = fields.BigIntField()
|
||||
"""uid"""
|
||||
mys_id: int = fields.BigIntField(null=True)
|
||||
"""米游社id"""
|
||||
cookie: str = fields.TextField(default="")
|
||||
"""米游社cookie"""
|
||||
auto_sign = fields.BooleanField(default=False)
|
||||
"""是否自动签到"""
|
||||
today_query_uid = fields.TextField(default="")
|
||||
"""cookie今日查询uid"""
|
||||
auto_sign_time = fields.DatetimeField(null=True)
|
||||
"""签到日期时间"""
|
||||
resin_remind = fields.BooleanField(default=False)
|
||||
"""树脂提醒"""
|
||||
resin_recovery_time = fields.DatetimeField(null=True)
|
||||
"""满树脂提醒日期"""
|
||||
bind_group: int = fields.BigIntField(null=True)
|
||||
"""发送提示 绑定群聊"""
|
||||
login_ticket = fields.TextField(default="")
|
||||
"""login_ticket"""
|
||||
stuid: str = fields.TextField(default="")
|
||||
"""stuid"""
|
||||
stoken: str = fields.TextField(default="")
|
||||
"""stoken"""
|
||||
|
||||
_idx1 = db.Index("genshin_uid_idx1", "user_qq", "uid", unique=True)
|
||||
|
||||
@classmethod
|
||||
async def add_uid(cls, user_qq: int, uid: int):
|
||||
"""
|
||||
说明:
|
||||
添加一个uid
|
||||
参数:
|
||||
:param user_qq: 用户qq
|
||||
:param uid: 原神uid
|
||||
"""
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.uid == uid))
|
||||
user = await query.gino.first()
|
||||
if not user:
|
||||
await cls.create(
|
||||
user_qq=user_qq,
|
||||
uid=uid,
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def set_mys_id(cls, uid: int, mys_id: int) -> bool:
|
||||
"""
|
||||
说明:
|
||||
设置米游社id
|
||||
参数:
|
||||
:param uid: 原神uid
|
||||
:param mys_id: 米游社id
|
||||
"""
|
||||
query = cls.query.where(cls.uid == uid).with_for_update()
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
await user.update(mys_id=mys_id).apply()
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def set_bind_group(cls, uid: int, bind_group) -> bool:
|
||||
"""
|
||||
说明:
|
||||
绑定group_id,除私聊外的提醒将在此群发送
|
||||
参数:
|
||||
:param uid: uid
|
||||
:param bind_group: 群号
|
||||
"""
|
||||
query = cls.query.where(cls.uid == uid).with_for_update()
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
await user.update(bind_group=bind_group).apply()
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def get_bind_group(cls, uid: int) -> Optional[int]:
|
||||
"""
|
||||
说明:
|
||||
获取用户绑定的群聊
|
||||
参数:
|
||||
:param uid: uid
|
||||
"""
|
||||
user = await cls.query.where(cls.uid == uid).gino.first()
|
||||
if user:
|
||||
return user.bind_group
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
async def set_cookie(cls, uid: int, cookie: str) -> bool:
|
||||
"""
|
||||
说明:
|
||||
设置cookie
|
||||
参数:
|
||||
:param uid: 原神uid
|
||||
:param cookie: 米游社id
|
||||
"""
|
||||
query = cls.query.where(cls.uid == uid).with_for_update()
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
await user.update(cookie=cookie).apply()
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def set_resin_remind(cls, uid: int, flag: bool) -> bool:
|
||||
"""
|
||||
说明:
|
||||
设置体力提醒
|
||||
参数:
|
||||
:param uid: 原神uid
|
||||
:param flag: 开关状态
|
||||
"""
|
||||
query = cls.query.where(cls.uid == uid).with_for_update()
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
await user.update(resin_remind=flag).apply()
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def set_user_resin_recovery_time(cls, uid: int, date: datetime):
|
||||
"""
|
||||
说明:
|
||||
设置体力完成时间
|
||||
参数:
|
||||
:param uid: uid
|
||||
:param date: 提醒日期
|
||||
"""
|
||||
u = await cls.query.where(cls.uid == uid).gino.first()
|
||||
if u:
|
||||
await u.update(resin_recovery_time=date).apply()
|
||||
|
||||
@classmethod
|
||||
async def get_user_resin_recovery_time(cls, uid: int) -> Optional[datetime]:
|
||||
"""
|
||||
说明:
|
||||
获取体力完成时间
|
||||
参数:
|
||||
:param uid: uid
|
||||
"""
|
||||
u = await cls.query.where(cls.uid == uid).gino.first()
|
||||
if u:
|
||||
return u.resin_recovery_time.astimezone(pytz.timezone("Asia/Shanghai"))
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
async def get_all_resin_remind_user(cls) -> List["Genshin"]:
|
||||
"""
|
||||
说明:
|
||||
获取所有开启体力提醒的用户
|
||||
"""
|
||||
return await cls.query.where(cls.resin_remind == True).gino.all()
|
||||
|
||||
@classmethod
|
||||
async def clear_resin_remind_time(cls, uid: int) -> bool:
|
||||
"""
|
||||
说明:
|
||||
清空提醒日期
|
||||
参数:
|
||||
:param uid: uid
|
||||
"""
|
||||
user = await cls.query.where(cls.uid == uid).gino.first()
|
||||
if user:
|
||||
await user.update(resin_recovery_time=None).apply()
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def set_auto_sign(cls, uid: int, flag: bool) -> bool:
|
||||
"""
|
||||
说明:
|
||||
设置米游社/原神自动签到
|
||||
参数:
|
||||
:param uid: 原神uid
|
||||
:param flag: 开关状态
|
||||
"""
|
||||
query = cls.query.where(cls.uid == uid).with_for_update()
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
await user.update(auto_sign=flag).apply()
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def get_all_auto_sign_user(cls) -> List["Genshin"]:
|
||||
"""
|
||||
说明:
|
||||
获取所有开启自动签到的用户
|
||||
"""
|
||||
return await cls.query.where(cls.auto_sign == True).gino.all()
|
||||
|
||||
@classmethod
|
||||
async def get_all_sign_user(cls) -> List["Genshin"]:
|
||||
"""
|
||||
说明:
|
||||
获取 原神 所有今日签到用户
|
||||
"""
|
||||
return await cls.query.where(cls.auto_sign_time != None).gino.all()
|
||||
|
||||
@classmethod
|
||||
async def clear_sign_time(cls, uid: int) -> bool:
|
||||
"""
|
||||
说明:
|
||||
清空签到日期
|
||||
参数:
|
||||
:param uid: uid
|
||||
"""
|
||||
user = await cls.query.where(cls.uid == uid).gino.first()
|
||||
if user:
|
||||
await user.update(auto_sign_time=None).apply()
|
||||
return True
|
||||
return False
|
||||
class Meta:
|
||||
table = "genshin"
|
||||
table_description = "原神数据表"
|
||||
unique_together = ("user_qq", "uid")
|
||||
|
||||
@classmethod
|
||||
async def random_sign_time(cls, uid: int) -> Optional[datetime]:
|
||||
@@ -223,262 +53,43 @@ class Genshin(db.Model):
|
||||
说明:
|
||||
:param uid: uid
|
||||
"""
|
||||
query = cls.query.where(cls.uid == uid).with_for_update()
|
||||
user = await query.gino.first()
|
||||
user = await cls.get_or_none(uid=uid)
|
||||
if user and user.cookie:
|
||||
if user.auto_sign_time and user.auto_sign_time.astimezone(
|
||||
pytz.timezone("Asia/Shanghai")
|
||||
pytz.timezone("Asia/Shanghai")
|
||||
) - timedelta(seconds=2) >= datetime.now(pytz.timezone("Asia/Shanghai")):
|
||||
return user.auto_sign_time.astimezone(pytz.timezone("Asia/Shanghai"))
|
||||
hours = int(str(datetime.now()).split()[1].split(":")[0])
|
||||
minutes = int(str(datetime.now()).split()[1].split(":")[1])
|
||||
date = (
|
||||
datetime.now()
|
||||
+ timedelta(days=1)
|
||||
- timedelta(hours=hours)
|
||||
- timedelta(minutes=minutes - 1)
|
||||
datetime.now()
|
||||
+ timedelta(days=1)
|
||||
- timedelta(hours=hours)
|
||||
- timedelta(minutes=minutes - 1)
|
||||
)
|
||||
random_hours = random.randint(0, 22)
|
||||
random_minutes = random.randint(1, 59)
|
||||
date += timedelta(hours=random_hours) + timedelta(minutes=random_minutes)
|
||||
await user.update(auto_sign_time=date).apply()
|
||||
user.auto_sign_time = date
|
||||
await user.save(update_fields=["auto_sign_time"])
|
||||
return date
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
async def get_query_cookie(cls, uid: int) -> Optional[str]:
|
||||
async def random_cookie(cls, uid: int) -> Optional[str]:
|
||||
"""
|
||||
说明:
|
||||
获取查询角色信息cookie
|
||||
随机获取查询角色信息cookie
|
||||
参数:
|
||||
:param uid: 原神uid
|
||||
"""
|
||||
# 查找用户今日是否已经查找过,防止重复
|
||||
query = cls.query.where(cls.today_query_uid.contains(str(uid)))
|
||||
x = await query.gino.first()
|
||||
if x:
|
||||
await cls._add_query_uid(uid, uid)
|
||||
return x.cookie
|
||||
for u in await cls.query.where(cls.cookie != "").order_by(db.func.random()).gino.all():
|
||||
if not u.today_query_uid or len(u.today_query_uid[:-1].split()) < 30:
|
||||
await cls._add_query_uid(uid, u.uid)
|
||||
return u.cookie
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
async def get_user_cookie(cls, uid: int, flag: bool = False) -> Optional[str]:
|
||||
"""
|
||||
说明:
|
||||
获取用户cookie
|
||||
参数:
|
||||
:param uid:原神uid
|
||||
:param flag:必须使用自己的cookie
|
||||
"""
|
||||
cookie = await cls._get_user_data(None, uid, "cookie")
|
||||
if not cookie and not flag:
|
||||
cookie = await cls.get_query_cookie(uid)
|
||||
return cookie
|
||||
|
||||
@classmethod
|
||||
async def get_user_by_qq(cls, user_qq: int) -> Optional["Genshin"]:
|
||||
"""
|
||||
说明:
|
||||
通过qq获取用户对象
|
||||
参数:
|
||||
:param user_qq: qq
|
||||
"""
|
||||
return await cls.query.where(cls.user_qq == user_qq).gino.first()
|
||||
|
||||
@classmethod
|
||||
async def get_user_by_uid(cls, uid: int) -> Optional["Genshin"]:
|
||||
"""
|
||||
说明:
|
||||
通过uid获取用户对象
|
||||
参数:
|
||||
:param uid: qq
|
||||
"""
|
||||
return await cls.query.where(cls.uid == uid).gino.first()
|
||||
|
||||
@classmethod
|
||||
async def get_user_uid(cls, user_qq: int) -> Optional[int]:
|
||||
"""
|
||||
说明:
|
||||
获取用户uid
|
||||
参数:
|
||||
:param user_qq:用户qq
|
||||
"""
|
||||
return await cls._get_user_data(user_qq, None, "uid")
|
||||
|
||||
@classmethod
|
||||
async def get_user_mys_id(cls, uid: int) -> Optional[int]:
|
||||
"""
|
||||
说嘛:
|
||||
获取用户米游社id
|
||||
参数:
|
||||
:param uid:原神id
|
||||
"""
|
||||
return await cls._get_user_data(None, uid, "mys_id")
|
||||
|
||||
@classmethod
|
||||
async def delete_user_cookie(cls, uid: int):
|
||||
"""
|
||||
说明:
|
||||
删除用户cookie
|
||||
参数:
|
||||
:param uid: 原神uid
|
||||
"""
|
||||
query = cls.query.where(cls.uid == uid).with_for_update()
|
||||
user = await query.gino.first()
|
||||
user = await cls.get_or_none(today_query_uid__contains=str(uid))
|
||||
if user:
|
||||
await user.update(cookie="").apply()
|
||||
|
||||
@classmethod
|
||||
async def delete_user(cls, user_qq: int):
|
||||
"""
|
||||
说明:
|
||||
删除用户数据
|
||||
参数:
|
||||
:param user_qq: 用户qq
|
||||
"""
|
||||
query = cls.query.where(cls.user_qq == user_qq).with_for_update()
|
||||
user = await query.gino.first()
|
||||
if not user:
|
||||
return False
|
||||
await user.delete()
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
async def _add_query_uid(cls, uid: int, cookie_uid: int):
|
||||
"""
|
||||
说明:
|
||||
添加每日查询重复uid的cookie
|
||||
参数:
|
||||
:param uid: 原神uid
|
||||
:param cookie_uid: cookie的uid
|
||||
"""
|
||||
query = cls.query.where(cls.uid == cookie_uid).with_for_update()
|
||||
user = await query.gino.first()
|
||||
await user.update(today_query_uid=user.today_query_uid + f"{uid} ").apply()
|
||||
|
||||
@classmethod
|
||||
async def _get_user_data(
|
||||
cls, user_qq: Optional[int], uid: Optional[int], type_: str
|
||||
) -> Optional[Union[int, str]]:
|
||||
"""
|
||||
说明:
|
||||
获取用户数据
|
||||
参数:
|
||||
:param user_qq: 用户qq
|
||||
:param uid: uid
|
||||
:param type_: 数据类型
|
||||
"""
|
||||
if type_ == "uid":
|
||||
user = await cls.query.where(cls.user_qq == user_qq).gino.first()
|
||||
return user.uid if user else None
|
||||
user = await cls.query.where(cls.uid == uid).gino.first()
|
||||
if not user:
|
||||
return None
|
||||
if type_ == "mys_id":
|
||||
return user.mys_id
|
||||
elif type_ == "cookie":
|
||||
return user.cookie
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
async def reset_today_query_uid(cls):
|
||||
for u in await cls.query.with_for_update().gino.all():
|
||||
if u.today_query_uid:
|
||||
await u.update(today_query_uid="").apply()
|
||||
|
||||
@classmethod
|
||||
async def set_stuid(cls, uid: int, stuid: str) -> bool:
|
||||
"""
|
||||
说明:
|
||||
设置stuid
|
||||
参数:
|
||||
:param uid: 原神uid
|
||||
:param stuid: stuid
|
||||
"""
|
||||
query = cls.query.where(cls.uid == uid).with_for_update()
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
await user.update(stuid=stuid).apply()
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def set_stoken(cls, uid: int, stoken: str) -> bool:
|
||||
"""
|
||||
说明:
|
||||
设置stoken
|
||||
参数:
|
||||
:param uid: 原神uid
|
||||
:param stoken: stoken
|
||||
"""
|
||||
query = cls.query.where(cls.uid == uid).with_for_update()
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
await user.update(stoken=stoken).apply()
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def set_login_ticket(cls, uid: int, login_ticket: str) -> bool:
|
||||
"""
|
||||
说明:
|
||||
设置login_ticket
|
||||
参数:
|
||||
:param uid: 原神uid
|
||||
:param login_ticket: login_ticket
|
||||
"""
|
||||
query = cls.query.where(cls.uid == uid).with_for_update()
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
await user.update(login_ticket=login_ticket).apply()
|
||||
return True
|
||||
return False
|
||||
|
||||
# 获取login_ticket
|
||||
@classmethod
|
||||
async def get_login_ticket(cls, uid: int) -> Optional[str]:
|
||||
"""
|
||||
说明:
|
||||
获取login_ticket
|
||||
参数:
|
||||
:param uid: 原神uid
|
||||
"""
|
||||
query = cls.query.where(cls.uid == uid)
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
return user.login_ticket
|
||||
return None
|
||||
|
||||
# 获取stuid
|
||||
@classmethod
|
||||
async def get_stuid(cls, uid: int) -> Optional[str]:
|
||||
"""
|
||||
说明:
|
||||
获取stuid
|
||||
参数:
|
||||
:param uid: 原神uid
|
||||
"""
|
||||
query = cls.query.where(cls.uid == uid)
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
return user.stuid
|
||||
return None
|
||||
|
||||
# 获取stoken
|
||||
@classmethod
|
||||
async def get_stoken(cls, uid: int) -> Optional[str]:
|
||||
"""
|
||||
说明:
|
||||
获取stoken
|
||||
参数:
|
||||
:param uid: 原神uid
|
||||
"""
|
||||
query = cls.query.where(cls.uid == uid)
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
return user.stoken
|
||||
for user in await cls.filter(cookie__not="").annotate(rand=Random()).all():
|
||||
if not user.today_query_uid or len(user.today_query_uid[:-1].split()) < 30:
|
||||
user.today_query_uid = user.today_query_uid + f"{uid} "
|
||||
await user.save(update_fields=["today_query_uid"])
|
||||
return user.cookie
|
||||
return None
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from configs.config import Config
|
||||
import json
|
||||
import time
|
||||
import random
|
||||
import hashlib
|
||||
import json
|
||||
import random
|
||||
import string
|
||||
import time
|
||||
|
||||
from configs.config import Config
|
||||
|
||||
|
||||
def _md5(text):
|
||||
@@ -15,7 +16,7 @@ def _md5(text):
|
||||
def get_old_ds() -> str:
|
||||
n = Config.get_config("genshin", "n")
|
||||
i = str(int(time.time()))
|
||||
r = ''.join(random.sample(string.ascii_lowercase + string.digits, 6))
|
||||
r = "".join(random.sample(string.ascii_lowercase + string.digits, 6))
|
||||
c = _md5("salt=" + n + "&t=" + i + "&r=" + r)
|
||||
return i + "," + r + "," + c
|
||||
|
||||
@@ -33,7 +34,7 @@ def get_ds(q: str = "", b: dict = None) -> str:
|
||||
|
||||
|
||||
def random_hex(length: int) -> str:
|
||||
result = hex(random.randint(0, 16 ** length)).replace("0x", "").upper()
|
||||
result = hex(random.randint(0, 16**length)).replace("0x", "").upper()
|
||||
if len(result) < length:
|
||||
result = "0" * (length - len(result)) + result
|
||||
return result
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent, Message
|
||||
from utils.utils import is_number
|
||||
from .._models import Genshin
|
||||
from services.log import logger
|
||||
from nonebot.params import CommandArg, Command
|
||||
from typing import Tuple
|
||||
from utils.http_utils import AsyncHttpx
|
||||
import json
|
||||
from typing import Tuple
|
||||
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message, MessageEvent
|
||||
from nonebot.params import Command, CommandArg
|
||||
|
||||
from services.log import logger
|
||||
from utils.depends import OneCommand
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.utils import is_number
|
||||
|
||||
from .._models import Genshin
|
||||
|
||||
__zx_plugin_name__ = "原神绑定"
|
||||
__plugin_usage__ = """
|
||||
@@ -43,82 +46,94 @@ unbind = on_command("原神解绑", priority=5, block=True)
|
||||
|
||||
web_Api = "https://api-takumi.mihoyo.com"
|
||||
bbs_Cookie_url = "https://webapi.account.mihoyo.com/Api/cookie_accountinfo_by_loginticket?login_ticket={}"
|
||||
bbs_Cookie_url2 = web_Api + "/auth/api/getMultiTokenByLoginTicket?login_ticket={}&token_types=3&uid={}"
|
||||
bbs_Cookie_url2 = (
|
||||
web_Api
|
||||
+ "/auth/api/getMultiTokenByLoginTicket?login_ticket={}&token_types=3&uid={}"
|
||||
)
|
||||
|
||||
|
||||
@bind.handle()
|
||||
async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
|
||||
cmd = cmd[0]
|
||||
async def _(event: MessageEvent, cmd: str = OneCommand(), arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
user = await Genshin.get_or_none(user_qq=event.user_id)
|
||||
if cmd in ["原神绑定uid", "原神绑定米游社id"]:
|
||||
if not is_number(msg):
|
||||
await bind.finish("uid/id必须为纯数字!", at_senders=True)
|
||||
msg = int(msg)
|
||||
if cmd == "原神绑定uid":
|
||||
uid = await Genshin.get_user_uid(event.user_id)
|
||||
if uid:
|
||||
await bind.finish(f"您已绑定过uid:{uid},如果希望更换uid,请先发送原神解绑")
|
||||
flag = await Genshin.add_uid(event.user_id, msg)
|
||||
if not flag:
|
||||
if user:
|
||||
await bind.finish(f"您已绑定过uid:{user.uid},如果希望更换uid,请先发送原神解绑")
|
||||
if await Genshin.get_or_none(user_qq=event.user_id, uid=msg):
|
||||
await bind.finish("添加失败,该uid可能已存在...")
|
||||
user = await Genshin.create(user_qq=event.user_id, uid=msg)
|
||||
_x = f"已成功添加原神uid:{msg}"
|
||||
elif cmd == "原神绑定米游社id":
|
||||
uid = await Genshin.get_user_uid(event.user_id)
|
||||
if not uid:
|
||||
if not user:
|
||||
await bind.finish("请先绑定原神uid..")
|
||||
await Genshin.set_mys_id(uid, msg)
|
||||
_x = f"已成功为uid:{uid} 设置米游社id:{msg}"
|
||||
user.mys_id = int(msg)
|
||||
_x = f"已成功为uid:{user.uid} 设置米游社id:{msg}"
|
||||
else:
|
||||
if not msg:
|
||||
await bind.finish("""私聊发送!!
|
||||
await bind.finish(
|
||||
"""私聊发送!!
|
||||
1.以无痕模式打开浏览器(Edge请新建InPrivate窗口)
|
||||
2.打开http://bbs.mihoyo.com/ys/并登陆
|
||||
2.打开http://bbs.mihoyo.com/ys/ 并登陆
|
||||
3.登陆后打开http://user.mihoyo.com/进行登陆
|
||||
4.按下F12,打开控制台,输入以下命令:
|
||||
var cookie=document.cookie;var ask=confirm('Cookie:'+cookie+'\\n\\nDo you want to copy the cookie to the clipboard?');if(ask==true){copy(cookie);msg=cookie}else{msg='Cancel'}
|
||||
5.私聊发送:原神绑定cookie 刚刚复制的cookie""")
|
||||
5.私聊发送:原神绑定cookie 刚刚复制的cookie"""
|
||||
)
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
await bind.finish("请立即撤回你的消息并私聊发送!")
|
||||
uid = await Genshin.get_user_uid(event.user_id)
|
||||
if not uid:
|
||||
if not user:
|
||||
await bind.finish("请先绑定原神uid..")
|
||||
if msg.startswith('"') or msg.startswith("'"):
|
||||
msg = msg[1:]
|
||||
if msg.endswith('"') or msg.endswith("'"):
|
||||
msg = msg[:-1]
|
||||
await Genshin.set_cookie(uid, msg)
|
||||
cookie = msg
|
||||
# 用: 代替=, ,代替;
|
||||
cookie = '{"' + cookie.replace('=', '": "').replace("; ", '","') + '"}'
|
||||
print(cookie)
|
||||
cookie = '{"' + cookie.replace("=", '": "').replace("; ", '","') + '"}'
|
||||
# print(cookie)
|
||||
cookie_json = json.loads(cookie)
|
||||
print(cookie_json)
|
||||
if 'login_ticket' not in cookie_json:
|
||||
# print(cookie_json)
|
||||
if "login_ticket" not in cookie_json:
|
||||
await bind.finish("请发送正确完整的cookie!")
|
||||
login_ticket = cookie_json['login_ticket']
|
||||
user.cookie = str(msg)
|
||||
login_ticket = cookie_json["login_ticket"]
|
||||
# try:
|
||||
res = await AsyncHttpx.get(url=bbs_Cookie_url.format(login_ticket))
|
||||
res.encoding = "utf-8"
|
||||
data = json.loads(res.text)
|
||||
print(data)
|
||||
# print(data)
|
||||
if "成功" in data["data"]["msg"]:
|
||||
stuid = str(data["data"]["cookie_info"]["account_id"])
|
||||
res = await AsyncHttpx.get(url=bbs_Cookie_url2.format(
|
||||
login_ticket, stuid))
|
||||
res = await AsyncHttpx.get(url=bbs_Cookie_url2.format(login_ticket, stuid))
|
||||
res.encoding = "utf-8"
|
||||
data = json.loads(res.text)
|
||||
stoken = data["data"]["list"][0]["token"]
|
||||
# await Genshin.set_cookie(uid, cookie)
|
||||
await Genshin.set_stoken(uid, stoken)
|
||||
await Genshin.set_stuid(uid, stuid)
|
||||
await Genshin.set_login_ticket(uid, login_ticket)
|
||||
user.stoken = stoken
|
||||
user.stuid = stuid
|
||||
user.login_ticket = login_ticket
|
||||
# except Exception as e:
|
||||
# await bind.finish("获取登陆信息失败,请检查cookie是否正确或更新cookie")
|
||||
elif data["data"]["msg"] == "登录信息已失效,请重新登录":
|
||||
await bind.finish("登录信息失效,请重新获取最新cookie进行绑定")
|
||||
_x = f"已成功为uid:{uid} 设置cookie"
|
||||
_x = f"已成功为uid:{user.uid} 设置cookie"
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
await Genshin.set_bind_group(uid, event.group_id)
|
||||
user.bind_group = event.group_id
|
||||
if user:
|
||||
await user.save(
|
||||
update_fields=[
|
||||
"mys_id",
|
||||
"cookie",
|
||||
"stoken",
|
||||
"stuid",
|
||||
"login_ticket",
|
||||
"bind_group",
|
||||
]
|
||||
)
|
||||
await bind.send(_x)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, "
|
||||
@@ -129,12 +144,10 @@ async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message
|
||||
|
||||
@unbind.handle()
|
||||
async def _(event: MessageEvent):
|
||||
if await Genshin.delete_user(event.user_id):
|
||||
await unbind.send("用户数据删除成功...")
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
f"原神解绑"
|
||||
)
|
||||
else:
|
||||
await unbind.send("该用户数据不存在..")
|
||||
await Genshin.filter(user_qq=event.user_id).delete()
|
||||
await unbind.send("用户数据删除成功...")
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
f"原神解绑"
|
||||
)
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
from .data_source import get_sign_reward_list, genshin_sign
|
||||
from ..mihoyobbs_sign import mihoyobbs_sign
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
|
||||
from nonebot import on_command
|
||||
from services.log import logger
|
||||
from .init_task import add_job, scheduler, _sign
|
||||
from apscheduler.jobstores.base import JobLookupError
|
||||
from .._models import Genshin
|
||||
from nonebot.params import Command
|
||||
from typing import Tuple
|
||||
|
||||
from apscheduler.jobstores.base import JobLookupError
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageEvent
|
||||
from nonebot.params import Command
|
||||
|
||||
from services.log import logger
|
||||
from utils.depends import OneCommand
|
||||
|
||||
from .._models import Genshin
|
||||
from ..mihoyobbs_sign import mihoyobbs_sign
|
||||
from .data_source import genshin_sign, get_sign_reward_list
|
||||
from .init_task import _sign, add_job, scheduler
|
||||
|
||||
__zx_plugin_name__ = "原神自动签到"
|
||||
__plugin_usage__ = """
|
||||
@@ -39,45 +42,46 @@ genshin_matcher = on_command(
|
||||
|
||||
|
||||
@genshin_matcher.handle()
|
||||
async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command()):
|
||||
cmd = cmd[0]
|
||||
uid = await Genshin.get_user_uid(event.user_id)
|
||||
async def _(event: MessageEvent, cmd: str = OneCommand()):
|
||||
user = await Genshin.get_or_none(user_qq=event.user_id)
|
||||
if not user:
|
||||
await genshin_matcher.finish("请先绑定user.uid...")
|
||||
if cmd == "查看我的cookie":
|
||||
my_cookie = await Genshin.get_user_cookie(uid, True)
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
await genshin_matcher.finish("请私聊查看您的cookie!")
|
||||
await genshin_matcher.finish("您的cookie为" + my_cookie)
|
||||
if not uid or not await Genshin.get_user_cookie(uid, True):
|
||||
await genshin_matcher.finish("请先绑定uid和cookie!")
|
||||
# if "account_id" not in await Genshin.get_user_cookie(uid, True):
|
||||
await genshin_matcher.finish("您的cookie为" + user.cookie)
|
||||
if not user.uid or not user.cookie:
|
||||
await genshin_matcher.finish("请先绑定user.uid和cookie!")
|
||||
# if "account_id" not in await Genshin.get_user_cookie(user.uid, True):
|
||||
# await genshin_matcher.finish("请更新cookie!")
|
||||
if cmd == "原神我硬签":
|
||||
try:
|
||||
await genshin_matcher.send("正在进行签到...", at_sender=True)
|
||||
msg = await genshin_sign(uid)
|
||||
msg = await genshin_sign(user.uid)
|
||||
return_data = await mihoyobbs_sign(event.user_id)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, "
|
||||
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) UID:{uid} 原神签到"
|
||||
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) UID:{user.uid} 原神签到"
|
||||
)
|
||||
logger.info(msg)
|
||||
# 硬签,移除定时任务
|
||||
try:
|
||||
for i in range(3):
|
||||
scheduler.remove_job(f"genshin_auto_sign_{uid}_{event.user_id}_{i}",)
|
||||
scheduler.remove_job(
|
||||
f"genshin_auto_sign_{user.uid}_{event.user_id}_{i}",
|
||||
)
|
||||
except JobLookupError:
|
||||
pass
|
||||
u = await Genshin.get_user_by_uid(uid)
|
||||
if u and u.auto_sign:
|
||||
await u.clear_sign_time(uid)
|
||||
next_date = await Genshin.random_sign_time(uid)
|
||||
add_job(event.user_id, uid, next_date)
|
||||
if user.auto_sign:
|
||||
user.auto_sign_time = None
|
||||
next_date = await Genshin.random_sign_time(user.uid)
|
||||
add_job(event.user_id, user.uid, next_date)
|
||||
msg += f"\n{return_data}\n因开启自动签到\n下一次签到时间为:{next_date.replace(microsecond=0)}"
|
||||
except Exception as e:
|
||||
msg = "原神签到失败..请尝试检查cookie或报告至管理员!"
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, "
|
||||
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) UID:{uid} 原神签到发生错误 "
|
||||
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) UID:{user.uid} 原神签到发生错误 "
|
||||
f"{type(e)}:{e}"
|
||||
)
|
||||
msg = msg or "请检查cookie是否更新!"
|
||||
@@ -85,13 +89,16 @@ async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command()):
|
||||
else:
|
||||
for i in range(3):
|
||||
try:
|
||||
scheduler.remove_job(f"genshin_auto_sign_{uid}_{event.user_id}_{i}")
|
||||
scheduler.remove_job(
|
||||
f"genshin_auto_sign_{user.uid}_{event.user_id}_{i}"
|
||||
)
|
||||
except JobLookupError:
|
||||
pass
|
||||
if cmd[0] == "开":
|
||||
await Genshin.set_auto_sign(uid, True)
|
||||
next_date = await Genshin.random_sign_time(uid)
|
||||
add_job(event.user_id, uid, next_date)
|
||||
next_date = await Genshin.random_sign_time(user.uid)
|
||||
user.auto_sign = True
|
||||
user.auto_sign_time = next_date
|
||||
add_job(event.user_id, user.uid, next_date)
|
||||
await genshin_matcher.send(
|
||||
f"已开启原神自动签到!\n下一次签到时间为:{next_date.replace(microsecond=0)}",
|
||||
at_sender=True,
|
||||
@@ -102,11 +109,13 @@ async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command()):
|
||||
f" 开启原神自动签到"
|
||||
)
|
||||
else:
|
||||
await Genshin.set_auto_sign(uid, False)
|
||||
await Genshin.clear_sign_time(uid)
|
||||
user.auto_sign = False
|
||||
user.auto_sign_time = None
|
||||
await genshin_matcher.send(f"已关闭原神自动签到!", at_sender=True)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
f" 关闭原神自动签到"
|
||||
)
|
||||
if user:
|
||||
await user.save(update_fields=["auto_sign_time", "auto_sign"])
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from configs.config import Config
|
||||
from services.log import logger
|
||||
from ..mihoyobbs_sign.setting import *
|
||||
from .._models import Genshin
|
||||
from typing import Optional, Dict
|
||||
import hashlib
|
||||
import random
|
||||
import string
|
||||
import uuid
|
||||
import time
|
||||
import uuid
|
||||
from typing import Dict, Optional
|
||||
|
||||
from configs.config import Config
|
||||
from services.log import logger
|
||||
from utils.http_utils import AsyncHttpx
|
||||
|
||||
from .._models import Genshin
|
||||
from ..mihoyobbs_sign.setting import *
|
||||
|
||||
|
||||
async def genshin_sign(uid: int) -> Optional[str]:
|
||||
@@ -28,10 +30,10 @@ async def genshin_sign(uid: int) -> Optional[str]:
|
||||
sign_list = await get_sign_reward_list()
|
||||
get_reward = sign_list["data"]["awards"][
|
||||
int(sign_info["total_sign_day"]) - 1
|
||||
]["name"]
|
||||
]["name"]
|
||||
reward_num = sign_list["data"]["awards"][
|
||||
int(sign_info["total_sign_day"]) - 1
|
||||
]["cnt"]
|
||||
]["cnt"]
|
||||
get_im = f"本次签到获得:{get_reward}x{reward_num}"
|
||||
logger.info("get_im:" + get_im + "\nsign_info:" + str(sign_info))
|
||||
if status == "OK" and sign_info["is_sign"]:
|
||||
@@ -64,7 +66,7 @@ def timestamp() -> int:
|
||||
|
||||
|
||||
def random_text(num: int) -> str:
|
||||
return ''.join(random.sample(string.ascii_lowercase + string.digits, num))
|
||||
return "".join(random.sample(string.ascii_lowercase + string.digits, num))
|
||||
|
||||
|
||||
def md5(text: str) -> str:
|
||||
@@ -75,8 +77,7 @@ def md5(text: str) -> str:
|
||||
|
||||
# 生成一个device id
|
||||
def get_device_id(cookie) -> str:
|
||||
return str(uuid.uuid3(uuid.NAMESPACE_URL, cookie)).replace(
|
||||
'-', '').upper()
|
||||
return str(uuid.uuid3(uuid.NAMESPACE_URL, cookie)).replace("-", "").upper()
|
||||
|
||||
|
||||
async def _sign(uid: int, server_id: str = "cn_gf01") -> Optional[Dict[str, str]]:
|
||||
@@ -88,18 +89,20 @@ async def _sign(uid: int, server_id: str = "cn_gf01") -> Optional[Dict[str, str]
|
||||
if str(uid)[0] == "5":
|
||||
server_id = "cn_qd01"
|
||||
try:
|
||||
cookie = await Genshin.get_user_cookie(uid, True)
|
||||
headers['DS'] = get_ds(web=True)
|
||||
headers['Referer'] = 'https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?bbs_auth_required=true' \
|
||||
f'&act_id={genshin_Act_id}&utm_source=bbs&utm_medium=mys&utm_campaign=icon'
|
||||
headers['Cookie'] = cookie
|
||||
headers['x-rpc-device_id'] = get_device_id(cookie)
|
||||
req = await AsyncHttpx.post(
|
||||
url=genshin_Signurl,
|
||||
headers=headers,
|
||||
json={"act_id": genshin_Act_id, "uid": uid, "region": server_id},
|
||||
)
|
||||
return req.json()
|
||||
if user := await Genshin.get_or_none(uid=uid):
|
||||
headers["DS"] = get_ds(web=True)
|
||||
headers["Referer"] = (
|
||||
"https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?bbs_auth_required=true"
|
||||
f"&act_id={genshin_Act_id}&utm_source=bbs&utm_medium=mys&utm_campaign=icon"
|
||||
)
|
||||
headers["Cookie"] = user.cookie
|
||||
headers["x-rpc-device_id"] = get_device_id(user.cookie)
|
||||
req = await AsyncHttpx.post(
|
||||
url=genshin_Signurl,
|
||||
headers=headers,
|
||||
json={"act_id": genshin_Act_id, "uid": uid, "region": server_id},
|
||||
)
|
||||
return req.json()
|
||||
except Exception as e:
|
||||
logger.error(f"米游社签到发生错误 UID:{uid} {type(e)}:{e}")
|
||||
return None
|
||||
@@ -129,17 +132,22 @@ async def _get_sign_info(uid: int, server_id: str = "cn_gf01"):
|
||||
if str(uid)[0] == "5":
|
||||
server_id = "cn_qd01"
|
||||
try:
|
||||
req = await AsyncHttpx.get(
|
||||
url=f"https://api-takumi.mihoyo.com/event/bbs_sign_reward/info?act_id=e202009291139501®ion={server_id}&uid={uid}",
|
||||
headers={
|
||||
"x-rpc-app_version": str(Config.get_config("genshin", "mhyVersion")),
|
||||
"Cookie": await Genshin.get_user_cookie(int(uid), True),
|
||||
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1",
|
||||
"x-rpc-client_type": str(Config.get_config("genshin", "client_type")),
|
||||
"Referer": "https://webstatic.mihoyo.com/",
|
||||
},
|
||||
)
|
||||
return req.json()
|
||||
if user := await Genshin.get_or_none(uid=uid):
|
||||
req = await AsyncHttpx.get(
|
||||
url=f"https://api-takumi.mihoyo.com/event/bbs_sign_reward/info?act_id=e202009291139501®ion={server_id}&uid={uid}",
|
||||
headers={
|
||||
"x-rpc-app_version": str(
|
||||
Config.get_config("genshin", "mhyVersion")
|
||||
),
|
||||
"Cookie": user.cookie,
|
||||
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1",
|
||||
"x-rpc-client_type": str(
|
||||
Config.get_config("genshin", "client_type")
|
||||
),
|
||||
"Referer": "https://webstatic.mihoyo.com/",
|
||||
},
|
||||
)
|
||||
return req.json()
|
||||
except Exception as e:
|
||||
logger.error(f"获取签到信息发生错误 UID:{uid} {type(e)}:{e}")
|
||||
return None
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
from .data_source import genshin_sign
|
||||
from ..mihoyobbs_sign import mihoyobbs_sign
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from utils.message_builder import at
|
||||
from services.log import logger
|
||||
from utils.utils import scheduler, get_bot
|
||||
from apscheduler.jobstores.base import ConflictingIdError
|
||||
from .._models import Genshin
|
||||
from datetime import datetime, timedelta
|
||||
from nonebot import Driver
|
||||
import nonebot
|
||||
import random
|
||||
import pytz
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import nonebot
|
||||
import pytz
|
||||
from apscheduler.jobstores.base import ConflictingIdError
|
||||
from nonebot import Driver
|
||||
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from services.log import logger
|
||||
from utils.message_builder import at
|
||||
from utils.utils import get_bot, scheduler
|
||||
|
||||
from .._models import Genshin
|
||||
from ..mihoyobbs_sign import mihoyobbs_sign
|
||||
from .data_source import genshin_sign
|
||||
|
||||
driver: Driver = nonebot.get_driver()
|
||||
|
||||
@@ -21,7 +23,7 @@ async def _():
|
||||
"""
|
||||
启动时分配定时任务
|
||||
"""
|
||||
g_list = await Genshin.get_all_auto_sign_user()
|
||||
g_list = await Genshin.filter(auto_sign=True).all()
|
||||
for u in g_list:
|
||||
if u.auto_sign_time:
|
||||
if date := await Genshin.random_sign_time(u.uid):
|
||||
@@ -33,7 +35,8 @@ async def _():
|
||||
args=[u.user_qq, u.uid, 0],
|
||||
)
|
||||
logger.info(
|
||||
f"genshin_sign add_job:USER:{u.user_qq} UID:{u.uid} " f"{date} 原神自动签到"
|
||||
f"genshin_sign add_job:USER:{u.user_qq} UID:{u.uid} "
|
||||
f"{date} 原神自动签到"
|
||||
)
|
||||
|
||||
|
||||
@@ -110,10 +113,12 @@ async def _sign(user_id: int, uid: int, count: int):
|
||||
await bot.send_private_msg(user_id=user_id, message=return_data)
|
||||
await bot.send_private_msg(user_id=user_id, message=msg)
|
||||
else:
|
||||
if not (group_id := await Genshin.get_bind_group(uid)):
|
||||
group_list = await GroupInfoUser.get_user_all_group(user_id)
|
||||
if group_list:
|
||||
group_id = group_list[0]
|
||||
await bot.send_group_msg(
|
||||
group_id=group_id, message=at(user_id) + msg
|
||||
)
|
||||
if user := await Genshin.get_or_none(uid=uid):
|
||||
group_id = user.bind_group
|
||||
if not group_id:
|
||||
if group_list := await GroupInfoUser.get_user_all_group(user_id):
|
||||
group_id = group_list[0]
|
||||
if group_id:
|
||||
await bot.send_group_msg(
|
||||
group_id=group_id, message=at(user_id) + msg
|
||||
)
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent
|
||||
from typing import Tuple
|
||||
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent
|
||||
from nonebot.params import Command
|
||||
|
||||
from services.log import logger
|
||||
|
||||
# from .init_task import add_job, scheduler, _sign
|
||||
# from apscheduler.jobstores.base import JobLookupError
|
||||
from .._models import Genshin
|
||||
from nonebot.params import Command
|
||||
from typing import Tuple
|
||||
from .mihoyobbs import *
|
||||
|
||||
|
||||
__zx_plugin_name__ = "米游社自动签到"
|
||||
__plugin_usage__ = """
|
||||
usage:
|
||||
@@ -28,12 +30,10 @@ __plugin_settings__ = {
|
||||
"level": 5,
|
||||
"default_status": True,
|
||||
"limit_superuser": False,
|
||||
"cmd": ["原神签到"],
|
||||
"cmd": ["米游社签到"],
|
||||
}
|
||||
|
||||
mihoyobbs_matcher = on_command(
|
||||
"米游社签到", aliases={"米游社我硬签"}, priority=5, block=True
|
||||
)
|
||||
mihoyobbs_matcher = on_command("米游社签到", aliases={"米游社我硬签"}, priority=5, block=True)
|
||||
|
||||
|
||||
@mihoyobbs_matcher.handle()
|
||||
@@ -47,24 +47,29 @@ async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command()):
|
||||
|
||||
|
||||
async def mihoyobbs_sign(user_id):
|
||||
uid = await Genshin.get_user_uid(user_id)
|
||||
if not uid or not await Genshin.get_user_cookie(uid, True):
|
||||
user = await Genshin.get_or_none(user_qq=user_id)
|
||||
if not user or not user.uid or not user.cookie:
|
||||
await mihoyobbs_matcher.finish("请先绑定uid和cookie!", at_sender=True)
|
||||
stuid = await Genshin.get_stuid(uid)
|
||||
stoken = await Genshin.get_stoken(uid)
|
||||
cookie = await Genshin.get_user_cookie(uid)
|
||||
bbs = mihoyobbs.Mihoyobbs(stuid=stuid, stoken=stoken, cookie=cookie)
|
||||
bbs = mihoyobbs.Mihoyobbs(stuid=user.stuid, stoken=user.stoken, cookie=user.cookie)
|
||||
await bbs.init()
|
||||
return_data = ""
|
||||
if bbs.Task_do["bbs_Sign"] and bbs.Task_do["bbs_Read_posts"] and bbs.Task_do["bbs_Like_posts"] and \
|
||||
bbs.Task_do["bbs_Share"]:
|
||||
return_data += f"今天的米游社签到任务已经全部完成了!\n" \
|
||||
f"一共获得{mihoyobbs.today_have_get_coins}个米游币\n目前有{mihoyobbs.Have_coins}个米游币"
|
||||
logger.info(f"今天已经全部完成了!一共获得{mihoyobbs.today_have_get_coins}个米游币,目前有{mihoyobbs.Have_coins}个米游币")
|
||||
if (
|
||||
bbs.Task_do["bbs_Sign"]
|
||||
and bbs.Task_do["bbs_Read_posts"]
|
||||
and bbs.Task_do["bbs_Like_posts"]
|
||||
and bbs.Task_do["bbs_Share"]
|
||||
):
|
||||
return_data += (
|
||||
f"今天的米游社签到任务已经全部完成了!\n"
|
||||
f"一共获得{mihoyobbs.today_have_get_coins}个米游币\n目前有{mihoyobbs.Have_coins}个米游币"
|
||||
)
|
||||
logger.info(
|
||||
f"今天已经全部完成了!一共获得{mihoyobbs.today_have_get_coins}个米游币,目前有{mihoyobbs.Have_coins}个米游币"
|
||||
)
|
||||
else:
|
||||
i = 0
|
||||
print("开始签到")
|
||||
print(mihoyobbs.today_have_get_coins)
|
||||
# print("开始签到")
|
||||
# print(mihoyobbs.today_have_get_coins)
|
||||
while mihoyobbs.today_get_coins != 0 and i < 3:
|
||||
# if i > 0:
|
||||
await bbs.refresh_list()
|
||||
@@ -74,8 +79,12 @@ async def mihoyobbs_sign(user_id):
|
||||
await bbs.share_post()
|
||||
await bbs.get_tasks_list()
|
||||
i += 1
|
||||
return_data += "\n" + f"今天已经获得{mihoyobbs.today_have_get_coins}个米游币\n" \
|
||||
f"还能获得{mihoyobbs.today_get_coins}个米游币\n目前有{mihoyobbs.Have_coins}个米游币"
|
||||
logger.info(f"今天已经获得{mihoyobbs.today_have_get_coins}个米游币,"
|
||||
f"还能获得{mihoyobbs.today_get_coins}个米游币,目前有{mihoyobbs.Have_coins}个米游币")
|
||||
return_data += (
|
||||
"\n" + f"今天已经获得{mihoyobbs.today_have_get_coins}个米游币\n"
|
||||
f"还能获得{mihoyobbs.today_get_coins}个米游币\n目前有{mihoyobbs.Have_coins}个米游币"
|
||||
)
|
||||
logger.info(
|
||||
f"今天已经获得{mihoyobbs.today_have_get_coins}个米游币,"
|
||||
f"还能获得{mihoyobbs.today_get_coins}个米游币,目前有{mihoyobbs.Have_coins}个米游币"
|
||||
)
|
||||
return return_data
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
|
||||
from services.log import logger
|
||||
from .data_source import get_user_memo, get_memo
|
||||
from .._models import Genshin
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageEvent
|
||||
|
||||
from services.log import logger
|
||||
|
||||
from .._models import Genshin
|
||||
from .data_source import get_memo, get_user_memo
|
||||
|
||||
__zx_plugin_name__ = "原神便笺查询"
|
||||
__plugin_usage__ = """
|
||||
@@ -27,30 +28,27 @@ __plugin_settings__ = {
|
||||
__plugin_block_limit__ = {}
|
||||
|
||||
|
||||
query_memo_matcher = on_command("原神便签查询", aliases={"原神便笺查询", "yss"}, priority=5, block=True)
|
||||
query_memo_matcher = on_command(
|
||||
"原神便签查询", aliases={"原神便笺查询", "yss"}, priority=5, block=True
|
||||
)
|
||||
|
||||
|
||||
@query_memo_matcher.handle()
|
||||
async def _(event: MessageEvent):
|
||||
uid = await Genshin.get_user_uid(event.user_id)
|
||||
if not uid or not await Genshin.get_user_cookie(uid, True):
|
||||
user = await Genshin.get_or_none(user_qq=event.user_id)
|
||||
if not user or not user.uid or not user.cookie:
|
||||
await query_memo_matcher.finish("请先绑定uid和cookie!")
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
uname = event.sender.card or event.sender.nickname
|
||||
else:
|
||||
uname = event.sender.nickname
|
||||
data = await get_user_memo(event.user_id, uid, uname)
|
||||
data = await get_user_memo(event.user_id, user.uid, uname)
|
||||
if data:
|
||||
await query_memo_matcher.send(data)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, "
|
||||
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) "
|
||||
f"使用原神便笺查询 uid:{uid}"
|
||||
f"使用原神便笺查询 uid:{user.uid}"
|
||||
)
|
||||
else:
|
||||
await query_memo_matcher.send("未查询到数据...")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
from typing import Optional, Union
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
from configs.config import Config
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from services.log import logger
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.utils import get_user_avatar
|
||||
from utils.message_builder import image
|
||||
from .._utils import get_ds
|
||||
from .._models import Genshin
|
||||
from io import BytesIO
|
||||
from nonebot import Driver
|
||||
import asyncio
|
||||
import nonebot
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from io import BytesIO
|
||||
from typing import Optional, Tuple, Union
|
||||
|
||||
import nonebot
|
||||
from nonebot import Driver
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
|
||||
from configs.config import Config
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from services.log import logger
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.message_builder import image
|
||||
from utils.utils import get_user_avatar
|
||||
|
||||
from .._models import Genshin
|
||||
from .._utils import get_ds
|
||||
|
||||
driver: Driver = nonebot.get_driver()
|
||||
|
||||
@@ -26,10 +28,7 @@ memo_path.mkdir(exist_ok=True, parents=True)
|
||||
@driver.on_startup
|
||||
async def _():
|
||||
for name, url in zip(
|
||||
[
|
||||
"resin.png", "task.png", "resin_discount.png", "chengehu.png",
|
||||
"zhibian.png"
|
||||
],
|
||||
["resin.png", "task.png", "resin_discount.png", "chengehu.png", "zhibian.png"],
|
||||
[
|
||||
"https://upload-bbs.mihoyo.com/upload/2021/09/29/8819732/54266243c7d15ba31690c8f5d63cc3c6_71491376413333325"
|
||||
"20.png?x-oss-process=image//resize,s_600/quality,q_80/auto-orient,0/interlace,1/format,png",
|
||||
@@ -45,8 +44,9 @@ async def _():
|
||||
logger.info(f"已下载原神便签资源 -> {file}...")
|
||||
|
||||
|
||||
async def get_user_memo(user_id: int, uid: int,
|
||||
uname: str) -> Optional[Union[str, MessageSegment]]:
|
||||
async def get_user_memo(
|
||||
user_id: int, uid: int, uname: str
|
||||
) -> Optional[Union[str, MessageSegment]]:
|
||||
uid = str(uid)
|
||||
if uid[0] in ["1", "2"]:
|
||||
server_id = "cn_gf01"
|
||||
@@ -57,21 +57,17 @@ async def get_user_memo(user_id: int, uid: int,
|
||||
return await parse_data_and_draw(user_id, uid, server_id, uname)
|
||||
|
||||
|
||||
async def get_memo(uid: str, server_id: str) -> "Union[str, dict], int":
|
||||
async def get_memo(uid: str, server_id: str) -> Tuple[Union[str, dict], int]:
|
||||
try:
|
||||
req = await AsyncHttpx.get(
|
||||
url=
|
||||
f"https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/dailyNote?server={server_id}&role_id={uid}",
|
||||
url=f"https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/dailyNote?server={server_id}&role_id={uid}",
|
||||
headers={
|
||||
"DS": get_ds(f"role_id={uid}&server={server_id}"),
|
||||
"x-rpc-app_version": Config.get_config("genshin",
|
||||
"mhyVersion"),
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1",
|
||||
"x-rpc-client_type": Config.get_config("genshin",
|
||||
"client_type"),
|
||||
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
|
||||
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1",
|
||||
"x-rpc-client_type": Config.get_config("genshin", "client_type"),
|
||||
"Referer": "https://webstatic.mihoyo.com/",
|
||||
"Cookie": await Genshin.get_user_cookie(int(uid))
|
||||
"Cookie": await Genshin.random_cookie(uid),
|
||||
},
|
||||
)
|
||||
data = req.json()
|
||||
@@ -85,18 +81,13 @@ async def get_memo(uid: str, server_id: str) -> "Union[str, dict], int":
|
||||
return "发生了一些错误,请稍后再试", 998
|
||||
|
||||
|
||||
def create_border(image_name: str, content: str, notice_text: str,
|
||||
value: str) -> BuildImage:
|
||||
border = BuildImage(500,
|
||||
75,
|
||||
color="#E0D9D1",
|
||||
font="HYWenHei-85W.ttf",
|
||||
font_size=20)
|
||||
text_bk = BuildImage(350,
|
||||
75,
|
||||
color="#F5F1EB",
|
||||
font_size=23,
|
||||
font="HYWenHei-85W.ttf")
|
||||
def create_border(
|
||||
image_name: str, content: str, notice_text: str, value: str
|
||||
) -> BuildImage:
|
||||
border = BuildImage(500, 75, color="#E0D9D1", font="HYWenHei-85W.ttf", font_size=20)
|
||||
text_bk = BuildImage(
|
||||
350, 75, color="#F5F1EB", font_size=23, font="HYWenHei-85W.ttf"
|
||||
)
|
||||
_x = 70 if image_name == "resin.png" else 50
|
||||
_px = 10 if image_name == "resin.png" else 20
|
||||
text_bk.paste(
|
||||
@@ -119,15 +110,14 @@ def create_border(image_name: str, content: str, notice_text: str,
|
||||
True,
|
||||
)
|
||||
font_width, _ = border.getsize(value)
|
||||
border.text((350 + 76 - int(font_width / 2), 0),
|
||||
value,
|
||||
center_type="by_height")
|
||||
border.text((350 + 76 - int(font_width / 2), 0), value, center_type="by_height")
|
||||
border.paste(text_bk, (2, 0), center_type="by_height")
|
||||
return border
|
||||
|
||||
|
||||
async def parse_data_and_draw(user_id: int, uid: str, server_id: str,
|
||||
uname: str) -> Union[str, MessageSegment]:
|
||||
async def parse_data_and_draw(
|
||||
user_id: int, uid: str, server_id: str, uname: str
|
||||
) -> Union[str, MessageSegment]:
|
||||
data, code = await get_memo(uid, server_id)
|
||||
if code != 200:
|
||||
return data
|
||||
@@ -138,11 +128,13 @@ async def parse_data_and_draw(user_id: int, uid: str, server_id: str,
|
||||
if not role_avatar.exists():
|
||||
await AsyncHttpx.download_file(x["avatar_side_icon"], role_avatar)
|
||||
return await asyncio.get_event_loop().run_in_executor(
|
||||
None, _parse_data_and_draw, data, user_avatar, uid, uname)
|
||||
None, _parse_data_and_draw, data, user_avatar, uid, uname
|
||||
)
|
||||
|
||||
|
||||
def _parse_data_and_draw(data: dict, user_avatar: BytesIO, uid: int,
|
||||
uname: str) -> Union[str, MessageSegment]:
|
||||
def _parse_data_and_draw(
|
||||
data: dict, user_avatar: BytesIO, uid: int, uname: str
|
||||
) -> Union[str, MessageSegment]:
|
||||
current_resin = data["current_resin"] # 当前树脂
|
||||
max_resin = data["max_resin"] # 最大树脂
|
||||
resin_recovery_time = data["resin_recovery_time"] # 树脂全部回复时间
|
||||
@@ -157,33 +149,24 @@ def _parse_data_and_draw(data: dict, user_avatar: BytesIO, uid: int,
|
||||
max_coin = data["max_home_coin"] # 最大宝钱
|
||||
coin_recovery_time = data["home_coin_recovery_time"] # 宝钱全部回复时间
|
||||
transformer_available = data["transformer"]["obtained"] # 参量质变仪可获取
|
||||
transformer_state = data["transformer"]["recovery_time"][
|
||||
"reached"] # 参量质变仪状态
|
||||
transformer_recovery_time = data["transformer"]["recovery_time"][
|
||||
"Day"] # 参量质变仪回复时间
|
||||
transformer_state = data["transformer"]["recovery_time"]["reached"] # 参量质变仪状态
|
||||
transformer_recovery_time = data["transformer"]["recovery_time"]["Day"] # 参量质变仪回复时间
|
||||
transformer_recovery_hour = data["transformer"]["recovery_time"][
|
||||
"Hour"] # 参量质变仪回复时间
|
||||
"Hour"
|
||||
] # 参量质变仪回复时间
|
||||
coin_minute, coin_second = divmod(int(coin_recovery_time), 60)
|
||||
coin_hour, coin_minute = divmod(coin_minute, 60)
|
||||
#print(data)
|
||||
# print(data)
|
||||
minute, second = divmod(int(resin_recovery_time), 60)
|
||||
hour, minute = divmod(minute, 60)
|
||||
|
||||
A = BuildImage(1030,
|
||||
570,
|
||||
color="#f1e9e1",
|
||||
font_size=15,
|
||||
font="HYWenHei-85W.ttf")
|
||||
A = BuildImage(1030, 570, color="#f1e9e1", font_size=15, font="HYWenHei-85W.ttf")
|
||||
A.text((10, 15), "原神便笺 | Create By ZhenXun", (198, 186, 177))
|
||||
ava = BuildImage(100, 100, background=user_avatar)
|
||||
ava.circle()
|
||||
A.paste(ava, (40, 40), True)
|
||||
A.paste(
|
||||
BuildImage(0,
|
||||
0,
|
||||
plain_text=uname,
|
||||
font_size=20,
|
||||
font="HYWenHei-85W.ttf"),
|
||||
BuildImage(0, 0, plain_text=uname, font_size=20, font="HYWenHei-85W.ttf"),
|
||||
(160, 62),
|
||||
True,
|
||||
)
|
||||
@@ -225,40 +208,39 @@ def _parse_data_and_draw(data: dict, user_avatar: BytesIO, uid: int,
|
||||
"chengehu.png",
|
||||
"洞天财翁-洞天宝钱",
|
||||
"洞天财翁已达到存储上限"
|
||||
if current_coin == max_coin else f"{coin_hour}小时{coin_minute}分钟后存满",
|
||||
if current_coin == max_coin
|
||||
else f"{coin_hour}小时{coin_minute}分钟后存满",
|
||||
f"{current_coin}/{max_coin}",
|
||||
)
|
||||
A.paste(border, (10, 395))
|
||||
border = create_border(
|
||||
"zhibian.png",
|
||||
"参量质变仪",
|
||||
"不存在" if not transformer_available else
|
||||
"已准备完成 " if transformer_state else f"{transformer_recovery_hour}小时后可使用" if not transformer_recovery_time else f"{transformer_recovery_time}天后可使用",
|
||||
"不存在" if not transformer_available else
|
||||
"可使用" if transformer_state else "冷却中",
|
||||
"不存在"
|
||||
if not transformer_available
|
||||
else "已准备完成 "
|
||||
if transformer_state
|
||||
else f"{transformer_recovery_hour}小时后可使用"
|
||||
if not transformer_recovery_time
|
||||
else f"{transformer_recovery_time}天后可使用",
|
||||
"不存在" if not transformer_available else "可使用" if transformer_state else "冷却中",
|
||||
)
|
||||
A.paste(border, (10, 475))
|
||||
|
||||
expeditions_border = BuildImage(470,
|
||||
510,
|
||||
color="#E0D9D1",
|
||||
font="HYWenHei-85W.ttf",
|
||||
font_size=20)
|
||||
expeditions_text = BuildImage(466,
|
||||
506,
|
||||
color="#F5F1EB",
|
||||
font_size=23,
|
||||
font="HYWenHei-85W.ttf")
|
||||
expeditions_border = BuildImage(
|
||||
470, 510, color="#E0D9D1", font="HYWenHei-85W.ttf", font_size=20
|
||||
)
|
||||
expeditions_text = BuildImage(
|
||||
466, 506, color="#F5F1EB", font_size=23, font="HYWenHei-85W.ttf"
|
||||
)
|
||||
expeditions_text.text(
|
||||
(5, 5), f"探索派遣限制{current_expedition_num}/{max_expedition_num}",
|
||||
(100, 100, 98))
|
||||
(5, 5), f"探索派遣限制{current_expedition_num}/{max_expedition_num}", (100, 100, 98)
|
||||
)
|
||||
h = 45
|
||||
for x in expeditions:
|
||||
_bk = BuildImage(400,
|
||||
82,
|
||||
color="#ECE3D8",
|
||||
font="HYWenHei-85W.ttf",
|
||||
font_size=21)
|
||||
_bk = BuildImage(
|
||||
400, 82, color="#ECE3D8", font="HYWenHei-85W.ttf", font_size=21
|
||||
)
|
||||
file_name = x["avatar_side_icon"].split("_")[-1]
|
||||
role_avatar = memo_path / "role_avatar" / file_name
|
||||
_ava_img = BuildImage(75, 75, background=role_avatar)
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
from httpx import ConnectError
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent, Message
|
||||
from services.log import logger
|
||||
from .data_source import query_role_data
|
||||
from .._models import Genshin
|
||||
from utils.utils import is_number
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message, MessageEvent
|
||||
from nonebot.params import CommandArg
|
||||
|
||||
from services.log import logger
|
||||
from utils.utils import is_number
|
||||
|
||||
from .._models import Genshin
|
||||
from .data_source import query_role_data
|
||||
|
||||
__zx_plugin_name__ = "原神玩家查询"
|
||||
__plugin_usage__ = """
|
||||
@@ -29,7 +31,9 @@ __plugin_settings__ = {
|
||||
__plugin_block_limit__ = {}
|
||||
|
||||
|
||||
query_role_info_matcher = on_command("原神玩家查询", aliases={"原神玩家查找", "ys"}, priority=5, block=True)
|
||||
query_role_info_matcher = on_command(
|
||||
"原神玩家查询", aliases={"原神玩家查找", "ys"}, priority=5, block=True
|
||||
)
|
||||
|
||||
|
||||
@query_role_info_matcher.handle()
|
||||
@@ -39,24 +43,25 @@ async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
if not is_number(msg):
|
||||
await query_role_info_matcher.finish("查询uid必须为数字!")
|
||||
msg = int(msg)
|
||||
if not msg:
|
||||
uid = await Genshin.get_user_uid(event.user_id)
|
||||
uid = None
|
||||
user = await Genshin.get_or_none(user_qq=event.user_id)
|
||||
if not msg and user:
|
||||
uid = user.uid
|
||||
else:
|
||||
uid = msg
|
||||
if not uid: # or not await Genshin.get_user_cookie(uid):
|
||||
await query_role_info_matcher.finish("请先绑定uid和cookie!")
|
||||
nickname = event.sender.card or event.sender.nickname
|
||||
mys_id = await Genshin.get_user_mys_id(uid)
|
||||
data = await query_role_data(event.user_id, uid, mys_id, nickname)
|
||||
if data:
|
||||
await query_role_info_matcher.send(data)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, "
|
||||
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 使用原神玩家查询 uid:{uid}"
|
||||
)
|
||||
else:
|
||||
await query_role_info_matcher.send("查询失败..")
|
||||
|
||||
|
||||
|
||||
|
||||
mys_id = user.mys_id if user else None
|
||||
try:
|
||||
data = await query_role_data(event.user_id, uid, mys_id, nickname)
|
||||
if data:
|
||||
await query_role_info_matcher.send(data)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, "
|
||||
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 使用原神玩家查询 uid:{uid}"
|
||||
)
|
||||
else:
|
||||
await query_role_info_matcher.send("查询失败..")
|
||||
except ConnectError:
|
||||
await query_role_info_matcher.send("网络出小差啦~")
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
from typing import Optional, List, Dict, Union
|
||||
from .draw_image import init_image, get_genshin_image
|
||||
from typing import Dict, List, Optional, Tuple, Union
|
||||
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
from .._utils import get_ds, element_mastery
|
||||
|
||||
from configs.config import Config
|
||||
from services.log import logger
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from configs.config import Config
|
||||
|
||||
from .._models import Genshin
|
||||
from .._utils import element_mastery, get_ds
|
||||
from .draw_image import get_genshin_image, init_image
|
||||
|
||||
try:
|
||||
import ujson as json
|
||||
@@ -96,66 +99,66 @@ b=body q=query
|
||||
"""
|
||||
|
||||
|
||||
async def get_info(uid_: str, server_id: str) -> "Optional[Union[dict, str]], int":
|
||||
try:
|
||||
req = await AsyncHttpx.get(
|
||||
url=f"https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/index?server={server_id}&role_id={uid_}",
|
||||
headers={
|
||||
"Accept": "application/json, text/plain, */*",
|
||||
"DS": get_ds(f"role_id={uid_}&server={server_id}"),
|
||||
"Origin": "https://webstatic.mihoyo.com",
|
||||
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
|
||||
"User-Agent": "Mozilla/5.0 (Linux; Android 9; Unspecified Device) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 miHoYoBBS/2.2.0",
|
||||
"x-rpc-client_type": Config.get_config("genshin", "client_type"),
|
||||
"Referer": "https://webstatic.mihoyo.com/app/community-game-records/index.html?v=6",
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"Accept-Language": "zh-CN,en-US;q=0.8",
|
||||
"X-Requested-With": "com.mihoyo.hyperion",
|
||||
"Cookie": await Genshin.get_user_cookie(int(uid_))
|
||||
},
|
||||
)
|
||||
data = req.json()
|
||||
if data["message"] == "OK":
|
||||
return data["data"], 200
|
||||
return data["message"], 999
|
||||
except Exception as e:
|
||||
logger.error(f"访问失败,请重试! {type(e)}: {e}")
|
||||
async def get_info(uid_: str, server_id: str) -> Tuple[Optional[Union[dict, str]], int]:
|
||||
# try:
|
||||
req = await AsyncHttpx.get(
|
||||
url=f"https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/index?server={server_id}&role_id={uid_}",
|
||||
headers={
|
||||
"Accept": "application/json, text/plain, */*",
|
||||
"DS": get_ds(f"role_id={uid_}&server={server_id}"),
|
||||
"Origin": "https://webstatic.mihoyo.com",
|
||||
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
|
||||
"User-Agent": "Mozilla/5.0 (Linux; Android 9; Unspecified Device) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 miHoYoBBS/2.2.0",
|
||||
"x-rpc-client_type": Config.get_config("genshin", "client_type"),
|
||||
"Referer": "https://webstatic.mihoyo.com/app/community-game-records/index.html?v=6",
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"Accept-Language": "zh-CN,en-US;q=0.8",
|
||||
"X-Requested-With": "com.mihoyo.hyperion",
|
||||
"Cookie": await Genshin.random_cookie(uid_),
|
||||
},
|
||||
)
|
||||
data = req.json()
|
||||
if data["message"] == "OK":
|
||||
return data["data"], 200
|
||||
return data["message"], 999
|
||||
# except Exception as e:
|
||||
# logger.error(f"访问失败,请重试! {type(e)}: {e}")
|
||||
return None, -1
|
||||
|
||||
|
||||
async def get_character(
|
||||
uid: str, character_ids: List[str], server_id="cn_gf01"
|
||||
) -> Optional[dict]:
|
||||
try:
|
||||
req = await AsyncHttpx.post(
|
||||
url="https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/character",
|
||||
headers={
|
||||
"Accept": "application/json, text/plain, */*",
|
||||
"DS": get_ds(
|
||||
"",
|
||||
{
|
||||
"character_ids": character_ids,
|
||||
"role_id": uid,
|
||||
"server": server_id,
|
||||
},
|
||||
),
|
||||
"Origin": "https://webstatic.mihoyo.com",
|
||||
"Cookie": await Genshin.get_user_cookie(int(uid)),
|
||||
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
|
||||
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1",
|
||||
"x-rpc-client_type": "5",
|
||||
"Referer": "https://webstatic.mihoyo.com/",
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"Accept-Language": "zh-CN,en-US;q=0.8",
|
||||
"X-Requested-With": "com.mihoyo.hyperion",
|
||||
},
|
||||
json={"character_ids": character_ids, "role_id": uid, "server": server_id},
|
||||
)
|
||||
data = req.json()
|
||||
if data["message"] == "OK":
|
||||
return data["data"]
|
||||
except Exception as e:
|
||||
logger.error(f"访问失败,请重试! {type(e)}: {e}")
|
||||
# try:
|
||||
req = await AsyncHttpx.post(
|
||||
url="https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/character",
|
||||
headers={
|
||||
"Accept": "application/json, text/plain, */*",
|
||||
"DS": get_ds(
|
||||
"",
|
||||
{
|
||||
"character_ids": character_ids,
|
||||
"role_id": uid,
|
||||
"server": server_id,
|
||||
},
|
||||
),
|
||||
"Origin": "https://webstatic.mihoyo.com",
|
||||
"Cookie": await Genshin.random_cookie(uid),
|
||||
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
|
||||
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1",
|
||||
"x-rpc-client_type": "5",
|
||||
"Referer": "https://webstatic.mihoyo.com/",
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"Accept-Language": "zh-CN,en-US;q=0.8",
|
||||
"X-Requested-With": "com.mihoyo.hyperion",
|
||||
},
|
||||
json={"character_ids": character_ids, "role_id": uid, "server": server_id},
|
||||
)
|
||||
data = req.json()
|
||||
if data["message"] == "OK":
|
||||
return data["data"]
|
||||
# except Exception as e:
|
||||
# logger.error(f"访问失败,请重试! {type(e)}: {e}")
|
||||
return None
|
||||
|
||||
|
||||
@@ -205,7 +208,7 @@ def parsed_data(
|
||||
"image": world["icon"],
|
||||
"name": world["name"],
|
||||
"offerings": world["offerings"],
|
||||
"icon": world["icon"]
|
||||
"icon": world["icon"],
|
||||
}
|
||||
world_data_dict[world["name"]] = _x
|
||||
home_data_list = []
|
||||
@@ -231,21 +234,21 @@ async def get_mys_data(uid: str, mys_id: Optional[str]) -> Optional[List[Dict]]:
|
||||
:param mys_id: 米游社id
|
||||
"""
|
||||
if mys_id:
|
||||
try:
|
||||
req = await AsyncHttpx.get(
|
||||
url=f"https://api-takumi-record.mihoyo.com/game_record/card/wapi/getGameRecordCard?uid={mys_id}",
|
||||
headers={
|
||||
"DS": get_ds(f"uid={mys_id}"),
|
||||
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
|
||||
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1",
|
||||
"x-rpc-client_type": "5",
|
||||
"Referer": "https://webstatic.mihoyo.com/",
|
||||
"Cookie": await Genshin.get_user_cookie(int(uid))
|
||||
},
|
||||
)
|
||||
data = req.json()
|
||||
if data["message"] == "OK":
|
||||
return data["data"]["list"]
|
||||
except Exception as e:
|
||||
logger.error(f"访问失败,请重试! {type(e)}: {e}")
|
||||
# try:
|
||||
req = await AsyncHttpx.get(
|
||||
url=f"https://api-takumi-record.mihoyo.com/game_record/card/wapi/getGameRecordCard?uid={mys_id}",
|
||||
headers={
|
||||
"DS": get_ds(f"uid={mys_id}"),
|
||||
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
|
||||
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1",
|
||||
"x-rpc-client_type": "5",
|
||||
"Referer": "https://webstatic.mihoyo.com/",
|
||||
"Cookie": await Genshin.random_cookie(uid),
|
||||
},
|
||||
)
|
||||
data = req.json()
|
||||
if data["message"] == "OK":
|
||||
return data["data"]["list"]
|
||||
# except Exception as e:
|
||||
# logger.error(f"访问失败,请重试! {type(e)}: {e}")
|
||||
return None
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from utils.utils import scheduler
|
||||
from .._models import Genshin
|
||||
from services.log import logger
|
||||
from utils.utils import scheduler
|
||||
|
||||
from .._models import Genshin
|
||||
|
||||
|
||||
@scheduler.scheduled_job(
|
||||
@@ -10,7 +11,7 @@ from services.log import logger
|
||||
)
|
||||
async def _():
|
||||
try:
|
||||
await Genshin.reset_today_query_uid()
|
||||
await Genshin.all().update(today_query_uid="")
|
||||
logger.warning(f"重置原神查询记录成功..")
|
||||
except Exception as e:
|
||||
logger.error(f"重置原神查询记录失败. {type(e)}:{e}")
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
|
||||
from apscheduler.jobstores.base import JobLookupError
|
||||
from services.log import logger
|
||||
from .init_task import scheduler, add_job
|
||||
from .._models import Genshin
|
||||
from nonebot.params import Command
|
||||
from typing import Tuple
|
||||
|
||||
from apscheduler.jobstores.base import JobLookupError
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageEvent
|
||||
from nonebot.params import Command
|
||||
|
||||
from services.log import logger
|
||||
from utils.depends import OneCommand
|
||||
|
||||
from .._models import Genshin
|
||||
from .init_task import add_job, scheduler
|
||||
|
||||
__zx_plugin_name__ = "原神树脂提醒"
|
||||
__plugin_usage__ = """
|
||||
@@ -33,31 +36,32 @@ __plugin_configs__ = {
|
||||
"AUTO_CLOSE_QUERY_FAIL_RESIN_REMIND": {
|
||||
"value": True,
|
||||
"help": "当请求连续三次失败时,关闭用户的树脂提醒",
|
||||
"default_value": True
|
||||
"default_value": True,
|
||||
},
|
||||
"CUSTOM_RESIN_OVERFLOW_REMIND": {
|
||||
"value": 20,
|
||||
"help": "自定义树脂溢出指定数量时的提醒,空值是为关闭",
|
||||
"default_value": None
|
||||
}
|
||||
"default_value": None,
|
||||
},
|
||||
}
|
||||
|
||||
resin_remind = on_command("开原神树脂提醒", aliases={"关原神树脂提醒"}, priority=5, block=True)
|
||||
|
||||
|
||||
@resin_remind.handle()
|
||||
async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command()):
|
||||
cmd = cmd[0]
|
||||
uid = await Genshin.get_user_uid(event.user_id)
|
||||
if not uid or not await Genshin.get_user_cookie(uid, True):
|
||||
async def _(event: MessageEvent, cmd: str = OneCommand()):
|
||||
user = await Genshin.get_or_none(user_qq=event.user_id)
|
||||
if not user or not user.uid or not user.cookie:
|
||||
await resin_remind.finish("请先绑定uid和cookie!")
|
||||
try:
|
||||
scheduler.remove_job(f"genshin_resin_remind_{uid}_{event.user_id}")
|
||||
scheduler.remove_job(f"genshin_resin_remind_{user.uid}_{event.user_id}")
|
||||
except JobLookupError:
|
||||
pass
|
||||
if cmd[0] == "开":
|
||||
await Genshin.set_resin_remind(uid, True)
|
||||
add_job(event.user_id, uid)
|
||||
if user.resin_remind:
|
||||
await resin_remind.finish("原神树脂提醒已经是开启状态,请勿重复开启!", at_sender=True)
|
||||
user.resin_remind = True
|
||||
add_job(event.user_id, user.uid)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
@@ -65,12 +69,15 @@ async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command()):
|
||||
)
|
||||
await resin_remind.send("开启原神树脂提醒成功!", at_sender=True)
|
||||
else:
|
||||
await Genshin.set_resin_remind(uid, False)
|
||||
await Genshin.clear_resin_remind_time(uid)
|
||||
if not user.resin_remind:
|
||||
await resin_remind.finish("原神树脂提醒已经是开启状态,请勿重复开启!", at_sender=True)
|
||||
user.resin_remind = False
|
||||
user.resin_recovery_time = None
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
f" 关闭原神体力提醒"
|
||||
)
|
||||
await resin_remind.send("已关闭原神树脂提醒..", at_sender=True)
|
||||
|
||||
if user:
|
||||
await user.save(update_fields=["resin_remind", "resin_recovery_time"])
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
from nonebot.adapters.onebot.v11 import ActionFailed
|
||||
|
||||
from utils.utils import get_bot, scheduler
|
||||
from utils.message_builder import at
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from apscheduler.jobstores.base import ConflictingIdError
|
||||
from nonebot import Driver
|
||||
from .._models import Genshin
|
||||
from datetime import datetime, timedelta
|
||||
from apscheduler.jobstores.base import JobLookupError
|
||||
from services.log import logger
|
||||
from nonebot.plugin import require
|
||||
from configs.config import Config
|
||||
import random
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import nonebot
|
||||
import pytz
|
||||
from apscheduler.jobstores.base import ConflictingIdError, JobLookupError
|
||||
from nonebot import Driver
|
||||
from nonebot.adapters.onebot.v11 import ActionFailed
|
||||
from nonebot.plugin import require
|
||||
|
||||
from configs.config import Config
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from services.log import logger
|
||||
from utils.message_builder import at
|
||||
from utils.utils import get_bot, scheduler
|
||||
|
||||
from .._models import Genshin
|
||||
|
||||
driver: Driver = nonebot.get_driver()
|
||||
|
||||
@@ -23,7 +23,6 @@ require("query_memo")
|
||||
|
||||
from ..query_memo import get_memo
|
||||
|
||||
|
||||
global_map = {}
|
||||
|
||||
|
||||
@@ -80,12 +79,13 @@ async def _():
|
||||
"""
|
||||
启动时分配定时任务
|
||||
"""
|
||||
g_list = await Genshin.get_all_resin_remind_user()
|
||||
g_list = await Genshin.filter(resin_remind=True).all()
|
||||
update_list = []
|
||||
date = datetime.now(pytz.timezone("Asia/Shanghai")) + timedelta(seconds=30)
|
||||
for u in g_list:
|
||||
if u.resin_remind:
|
||||
if u.resin_recovery_time:
|
||||
if await Genshin.get_user_resin_recovery_time(u.uid) > datetime.now(
|
||||
if u.resin_recovery_time and u.resin_recovery_time > datetime.now(
|
||||
pytz.timezone("Asia/Shanghai")
|
||||
):
|
||||
# date = await Genshin.get_user_resin_recovery_time(u.uid) # 不能要,因为可能在这期间用户使用了树脂
|
||||
@@ -101,7 +101,8 @@ async def _():
|
||||
f"genshin_resin_remind add_job:USER:{u.user_qq} UID:{u.uid}启动原神树脂提醒 "
|
||||
)
|
||||
else:
|
||||
await Genshin.clear_resin_remind_time(u.uid)
|
||||
u.resin_recovery_time = None
|
||||
update_list.append(u)
|
||||
add_job(u.user_qq, u.uid)
|
||||
logger.info(
|
||||
f"genshin_resin_remind add_job CHECK:USER:{u.user_qq} UID:{u.uid}启动原神树脂提醒 "
|
||||
@@ -111,6 +112,8 @@ async def _():
|
||||
logger.info(
|
||||
f"genshin_resin_remind add_job CHECK:USER:{u.user_qq} UID:{u.uid}启动原神树脂提醒 "
|
||||
)
|
||||
if update_list:
|
||||
await Genshin.bulk_update(update_list, ["resin_recovery_time"])
|
||||
|
||||
|
||||
def add_job(user_id: int, uid: int):
|
||||
@@ -133,6 +136,7 @@ def add_job(user_id: int, uid: int):
|
||||
|
||||
|
||||
async def _remind(user_id: int, uid: str):
|
||||
user = await Genshin.get_or_none(user_qq=user_id, uid=int(uid))
|
||||
uid = str(uid)
|
||||
if uid[0] in ["1", "2"]:
|
||||
server_id = "cn_gf01"
|
||||
@@ -158,7 +162,9 @@ async def _remind(user_id: int, uid: str):
|
||||
elif max_resin - 20 <= current_resin < max_resin:
|
||||
next_time = now + timedelta(minutes=(max_resin - current_resin) * 8)
|
||||
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:
|
||||
next_time = now + timedelta(minutes=custom_overflow_resin * 8)
|
||||
user_manager.add_overflow(uid)
|
||||
@@ -178,28 +184,35 @@ async def _remind(user_id: int, uid: str):
|
||||
message=msg,
|
||||
)
|
||||
else:
|
||||
group_id = await Genshin.get_bind_group(int(uid))
|
||||
if not group_id:
|
||||
group_list = await GroupInfoUser.get_user_all_group(user_id)
|
||||
if group_list:
|
||||
group_id = group_list[0]
|
||||
try:
|
||||
await bot.send_group_msg(
|
||||
group_id=group_id,
|
||||
message=at(user_id) + msg
|
||||
)
|
||||
except ActionFailed as e:
|
||||
logger.error(f"树脂提醒推送发生错误 {type(e)}:{e}")
|
||||
if user:
|
||||
group_id = user.bind_group
|
||||
if not group_id:
|
||||
if group_list := await GroupInfoUser.get_user_all_group(
|
||||
user_id
|
||||
):
|
||||
group_id = group_list[0]
|
||||
try:
|
||||
await bot.send_group_msg(
|
||||
group_id=group_id, message=at(user_id) + msg
|
||||
)
|
||||
except ActionFailed as e:
|
||||
logger.error(f"树脂提醒推送发生错误 {type(e)}:{e}")
|
||||
|
||||
if not next_time:
|
||||
if user_manager.check(uid) and Config.get_config("resin_remind", "AUTO_CLOSE_QUERY_FAIL_RESIN_REMIND"):
|
||||
await Genshin.set_resin_remind(int(uid), False)
|
||||
await Genshin.clear_resin_remind_time(int(uid))
|
||||
if user_manager.check(uid) and Config.get_config(
|
||||
"resin_remind", "AUTO_CLOSE_QUERY_FAIL_RESIN_REMIND"
|
||||
):
|
||||
if user:
|
||||
user.resin_remind = False
|
||||
user.resin_recovery_time = None
|
||||
await user.save(update_fields=["resin_recovery_time", "resin_remind"])
|
||||
next_time = now + timedelta(minutes=(20 + random.randint(5, 20)) * 8)
|
||||
user_manager.add_error_count(uid)
|
||||
else:
|
||||
user_manager.remove_error_count(uid)
|
||||
await Genshin.set_user_resin_recovery_time(int(uid), next_time)
|
||||
if user:
|
||||
user.resin_recovery_time = next_time
|
||||
await user.save(update_fields=["resin_recovery_time", "resin_remind"])
|
||||
scheduler.add_job(
|
||||
_remind,
|
||||
"date",
|
||||
@@ -208,6 +221,5 @@ async def _remind(user_id: int, uid: str):
|
||||
args=[user_id, uid],
|
||||
)
|
||||
logger.info(
|
||||
f"genshin_resin_remind add_job:USER:{user_id} UID:{uid} "
|
||||
f"{next_time} 原神树脂提醒"
|
||||
)
|
||||
f"genshin_resin_remind add_job:USER:{user_id} UID:{uid} " f"{next_time} 原神树脂提醒"
|
||||
)
|
||||
|
||||
@@ -29,7 +29,6 @@ from nonebot.params import CommandArg
|
||||
import random
|
||||
import time
|
||||
|
||||
|
||||
__zx_plugin_name__ = "金币红包"
|
||||
__plugin_usage__ = """
|
||||
usage:
|
||||
@@ -64,11 +63,16 @@ __plugin_settings__ = {
|
||||
}
|
||||
__plugin_resources__ = {"prts": IMAGE_PATH}
|
||||
|
||||
|
||||
async def rule(event: GroupMessageEvent) -> bool:
|
||||
return check_on_gold_red(event)
|
||||
|
||||
|
||||
gold_redbag = on_command(
|
||||
"塞红包", aliases={"金币红包"}, priority=5, block=True, permission=GROUP
|
||||
)
|
||||
|
||||
open_ = on_command("开", aliases={"抢"}, priority=5, block=True, permission=GROUP)
|
||||
open_ = on_command("开", aliases={"抢"}, priority=5, block=True, permission=GROUP, rule=rule)
|
||||
|
||||
poke_ = on_notice(priority=6, block=False)
|
||||
|
||||
@@ -85,27 +89,11 @@ festive_redbag_data = {}
|
||||
|
||||
# 阻断其他poke
|
||||
@run_preprocessor
|
||||
async def _(matcher: Matcher, event: PokeNotifyEvent):
|
||||
async def _(matcher: Matcher, event: PokeNotifyEvent, ):
|
||||
try:
|
||||
if matcher.type == "notice" and event.self_id == event.target_id:
|
||||
flag1 = True
|
||||
flag2 = True
|
||||
try:
|
||||
if festive_redbag_data[event.group_id]["user_id"]:
|
||||
if (
|
||||
event.user_id
|
||||
in festive_redbag_data[event.group_id]["open_user"]
|
||||
):
|
||||
flag1 = False
|
||||
except KeyError:
|
||||
flag1 = False
|
||||
try:
|
||||
if redbag_data[event.group_id]["user_id"]:
|
||||
if event.user_id in redbag_data[event.group_id]["open_user"]:
|
||||
flag2 = False
|
||||
except KeyError:
|
||||
flag2 = False
|
||||
if flag1 or flag2:
|
||||
flag = check_on_gold_red(event)
|
||||
if flag:
|
||||
if matcher.plugin_name == "poke":
|
||||
raise IgnoredException("目前正在抢红包...")
|
||||
else:
|
||||
@@ -121,8 +109,8 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
try:
|
||||
if time.time() - redbag_data[event.group_id]["time"] > 60:
|
||||
amount = (
|
||||
redbag_data[event.group_id]["amount"]
|
||||
- redbag_data[event.group_id]["open_amount"]
|
||||
redbag_data[event.group_id]["amount"]
|
||||
- redbag_data[event.group_id]["open_amount"]
|
||||
)
|
||||
await return_gold(redbag_data[event.group_id]["user_id"], event.group_id, amount)
|
||||
await gold_redbag.send(
|
||||
@@ -185,43 +173,21 @@ async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
msg = (
|
||||
msg.replace("!", "")
|
||||
.replace("!", "")
|
||||
.replace(",", "")
|
||||
.replace(",", "")
|
||||
.replace(".", "")
|
||||
.replace("。", "")
|
||||
.replace("!", "")
|
||||
.replace(",", "")
|
||||
.replace(",", "")
|
||||
.replace(".", "")
|
||||
.replace("。", "")
|
||||
)
|
||||
if msg:
|
||||
if "红包" not in msg:
|
||||
return
|
||||
flag1 = True
|
||||
flag2 = True
|
||||
open_flag1 = True
|
||||
open_flag2 = True
|
||||
try:
|
||||
if festive_redbag_data[event.group_id]["user_id"]:
|
||||
if event.user_id in festive_redbag_data[event.group_id]["open_user"]:
|
||||
open_flag1 = False
|
||||
except KeyError:
|
||||
open_flag1 = False
|
||||
flag1 = False
|
||||
try:
|
||||
if redbag_data[event.group_id]["user_id"]:
|
||||
if event.user_id in redbag_data[event.group_id]["open_user"]:
|
||||
open_flag2 = False
|
||||
except KeyError:
|
||||
flag2 = False
|
||||
if not flag1 and not flag2:
|
||||
await open_.finish("目前没有红包可以开...", at_sender=True)
|
||||
if open_flag1 or open_flag2:
|
||||
try:
|
||||
await open_.send(
|
||||
image(b64=await get_redbag_img(event.user_id, event.group_id)),
|
||||
at_sender=True,
|
||||
await open_.send(
|
||||
image(b64=await get_redbag_img(event.user_id, event.group_id)),
|
||||
at_sender=True,
|
||||
)
|
||||
except KeyError:
|
||||
await open_.finish("真贪心,明明已经开过这个红包了的说...", at_sender=True)
|
||||
else:
|
||||
except KeyError:
|
||||
await open_.finish("真贪心,明明已经开过这个红包了的说...", at_sender=True)
|
||||
|
||||
|
||||
@@ -229,19 +195,8 @@ async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
async def _poke_(event: PokeNotifyEvent):
|
||||
global redbag_data, festive_redbag_data
|
||||
if event.self_id == event.target_id:
|
||||
flag1 = True
|
||||
flag2 = True
|
||||
try:
|
||||
if event.user_id in festive_redbag_data[event.group_id]["open_user"]:
|
||||
flag1 = False
|
||||
except KeyError:
|
||||
flag1 = False
|
||||
try:
|
||||
if event.user_id in redbag_data[event.group_id]["open_user"]:
|
||||
flag2 = False
|
||||
except KeyError:
|
||||
flag2 = False
|
||||
if not flag1 and not flag2:
|
||||
flag = check_on_gold_red(event)
|
||||
if not flag:
|
||||
return
|
||||
await poke_.send(
|
||||
image(b64=await get_redbag_img(event.user_id, event.group_id)),
|
||||
@@ -331,7 +286,7 @@ async def _(bot: Bot, arg: Message = CommandArg()):
|
||||
await bot.send_group_msg(
|
||||
group_id=g,
|
||||
message=f"{NICKNAME}发起了金币红包\n金额:{amount}\n数量:{num}\n"
|
||||
+ image(
|
||||
+ image(
|
||||
b64=await generate_send_redbag_pic(int(bot.self_id), greetings)
|
||||
),
|
||||
)
|
||||
@@ -342,13 +297,13 @@ async def _(bot: Bot, arg: Message = CommandArg()):
|
||||
|
||||
# 红包数据初始化
|
||||
def init_redbag(
|
||||
user_id: int,
|
||||
group_id: int,
|
||||
nickname: str,
|
||||
amount: int,
|
||||
num: int,
|
||||
bot_self_id: int,
|
||||
mode: int = 0,
|
||||
user_id: int,
|
||||
group_id: int,
|
||||
nickname: str,
|
||||
amount: int,
|
||||
num: int,
|
||||
bot_self_id: int,
|
||||
mode: int = 0,
|
||||
):
|
||||
global redbag_data, festive_redbag_data
|
||||
data = redbag_data if mode == 0 else festive_redbag_data
|
||||
@@ -428,3 +383,27 @@ async def end_festive_redbag(bot: Bot, group_id: int):
|
||||
)
|
||||
await bot.send_group_msg(group_id=group_id, message=message)
|
||||
festive_redbag_data[group_id] = {}
|
||||
|
||||
|
||||
def check_on_gold_red(event) -> bool:
|
||||
flag1 = True
|
||||
flag2 = True
|
||||
try:
|
||||
if festive_redbag_data[event.group_id]["user_id"]:
|
||||
if (
|
||||
event.user_id
|
||||
in festive_redbag_data[event.group_id]["open_user"]
|
||||
):
|
||||
flag1 = False
|
||||
except KeyError:
|
||||
flag1 = False
|
||||
try:
|
||||
if redbag_data[event.group_id]["user_id"]:
|
||||
if event.user_id in redbag_data[event.group_id]["open_user"]:
|
||||
flag2 = False
|
||||
except KeyError:
|
||||
flag2 = False
|
||||
if flag1 or flag2:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
@@ -1,73 +1,58 @@
|
||||
from services.db_context import db
|
||||
from typing import List
|
||||
|
||||
from tortoise import fields
|
||||
|
||||
class RedbagUser(db.Model):
|
||||
__tablename__ = "redbag_users"
|
||||
from services.db_context import Model
|
||||
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||
group_id = db.Column(db.BigInteger(), nullable=False)
|
||||
send_redbag_count = db.Column(db.Integer(), default=0)
|
||||
get_redbag_count = db.Column(db.Integer(), default=0)
|
||||
spend_gold = db.Column(db.Integer(), default=0)
|
||||
get_gold = db.Column(db.Integer(), default=0)
|
||||
|
||||
_idx1 = db.Index("redbag_group_users_idx1", "user_qq", "group_id", unique=True)
|
||||
class RedbagUser(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
"""用户id"""
|
||||
group_id = fields.BigIntField()
|
||||
"""群聊id"""
|
||||
send_redbag_count = fields.IntField(default=0)
|
||||
"""发送红包次数"""
|
||||
get_redbag_count = fields.IntField(default=0)
|
||||
"""开启红包次数"""
|
||||
spend_gold = fields.IntField(default=0)
|
||||
"""发送红包花费金额"""
|
||||
get_gold = fields.IntField(default=0)
|
||||
"""开启红包获取金额"""
|
||||
|
||||
class Meta:
|
||||
table = "redbag_users"
|
||||
table_description = "红包统计数据表"
|
||||
unique_together = ("user_qq", "group_id")
|
||||
|
||||
@classmethod
|
||||
async def add_redbag_data(cls, user_qq: int, group_id: int, itype: str, money: int):
|
||||
async def add_redbag_data(
|
||||
cls, user_qq: int, group_id: int, i_type: str, money: int
|
||||
):
|
||||
"""
|
||||
说明:
|
||||
添加收发红包数据
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 群号
|
||||
:param itype: 收或发
|
||||
:param i_type: 收或发
|
||||
:param money: 金钱数量
|
||||
"""
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
user = await query.with_for_update().gino.first() or await cls.create(
|
||||
user_qq=user_qq,
|
||||
group_id=group_id,
|
||||
)
|
||||
if itype == "get":
|
||||
await user.update(
|
||||
get_redbag_count=user.get_redbag_count + 1,
|
||||
get_gold=user.get_gold + money,
|
||||
).apply()
|
||||
else:
|
||||
await user.update(
|
||||
send_redbag_count=user.send_redbag_count + 1,
|
||||
spend_gold=user.spend_gold + money,
|
||||
).apply()
|
||||
|
||||
@classmethod
|
||||
async def ensure(cls, user_qq: int, group_id: int) -> bool:
|
||||
"""
|
||||
说明:
|
||||
获取用户对象
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 群号
|
||||
"""
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
user = await query.gino.first() or await cls.create(
|
||||
user_qq=user_qq,
|
||||
group_id=group_id,
|
||||
)
|
||||
return user
|
||||
|
||||
@classmethod
|
||||
async def get_user_all(cls, group_id: int = None) -> List["RedbagUser"]:
|
||||
"""
|
||||
说明:
|
||||
获取所有用户对象
|
||||
参数:
|
||||
:param group_id: 群号
|
||||
"""
|
||||
if not group_id:
|
||||
query = await cls.query.gino.all()
|
||||
user, _ = await cls.get_or_create(user_qq=user_qq, group_id=group_id)
|
||||
if i_type == "get":
|
||||
user.get_redbag_count = user.get_redbag_count + 1
|
||||
user.get_gold = user.get_gold + money
|
||||
else:
|
||||
query = await cls.query.where((cls.group_id == group_id)).gino.all()
|
||||
return query
|
||||
user.send_redbag_count = user.send_redbag_count + 1
|
||||
user.spend_gold = user.spend_gold + money
|
||||
await user.save(
|
||||
update_fields=[
|
||||
"get_redbag_count",
|
||||
"get_gold",
|
||||
"send_redbag_count",
|
||||
"spend_gold",
|
||||
]
|
||||
)
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
from nonebot import on_message, on_regex
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from utils.message_builder import image
|
||||
from utils.utils import is_number, get_message_text
|
||||
from services.log import logger
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
|
||||
from utils.utils import FreqLimiter, cn2py
|
||||
from configs.config import Config
|
||||
from utils.manager import withdraw_message_manager
|
||||
from .rule import rule
|
||||
import random
|
||||
import os
|
||||
import random
|
||||
|
||||
from nonebot import on_message, on_regex
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageEvent
|
||||
|
||||
from configs.config import Config
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from services.log import logger
|
||||
from utils.manager import withdraw_message_manager
|
||||
from utils.message_builder import image
|
||||
from utils.utils import FreqLimiter, cn2py, get_message_text, is_number
|
||||
|
||||
from .rule import rule
|
||||
|
||||
try:
|
||||
import ujson as json
|
||||
@@ -66,16 +68,14 @@ async def _(event: MessageEvent):
|
||||
if len(msg) > 1:
|
||||
img_id = msg[1]
|
||||
path = _path / cn2py(gallery)
|
||||
if gallery in Config.get_config(
|
||||
"image_management", "IMAGE_DIR_LIST"
|
||||
):
|
||||
if gallery in Config.get_config("image_management", "IMAGE_DIR_LIST"):
|
||||
if not path.exists() and (path.parent.parent / cn2py(gallery)).exists():
|
||||
path = IMAGE_PATH / cn2py(gallery)
|
||||
else:
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
length = len(os.listdir(path))
|
||||
if length == 0:
|
||||
logger.warning(f'图库 {cn2py(gallery)} 为空,调用取消!')
|
||||
logger.warning(f"图库 {cn2py(gallery)} 为空,调用取消!")
|
||||
await send_img.finish("该图库中没有图片噢")
|
||||
index = img_id if img_id else str(random.randint(0, length - 1))
|
||||
if not is_number(index):
|
||||
@@ -87,8 +87,7 @@ async def _(event: MessageEvent):
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) "
|
||||
f"发送{cn2py(gallery)}:"
|
||||
+ result
|
||||
f"发送{cn2py(gallery)}:" + result
|
||||
)
|
||||
msg_id = await send_img.send(
|
||||
f"id:{index}" + result
|
||||
@@ -113,4 +112,6 @@ async def _(event: MessageEvent):
|
||||
async def _(event: MessageEvent):
|
||||
if _flmt.check(event.user_id):
|
||||
_flmt.start_cd(event.user_id)
|
||||
await pa_reg.finish(image(random.choice(os.listdir(IMAGE_PATH / "pa")), "pa"))
|
||||
await pa_reg.finish(
|
||||
image(IMAGE_PATH / "pa" / random.choice(os.listdir(IMAGE_PATH / "pa")))
|
||||
)
|
||||
|
||||
+12
-11
@@ -1,10 +1,11 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11.permission import GROUP
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from datetime import timedelta
|
||||
from models.level_user import LevelUser
|
||||
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent
|
||||
from nonebot.adapters.onebot.v11.permission import GROUP
|
||||
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from models.level_user import LevelUser
|
||||
|
||||
__zx_plugin_name__ = "个人信息权限查看"
|
||||
__plugin_usage__ = """
|
||||
@@ -31,13 +32,13 @@ async def _(event: GroupMessageEvent):
|
||||
|
||||
|
||||
async def get_member_info(user_qq: int, group_id: int) -> str:
|
||||
user = await GroupInfoUser.get_member_info(user_qq, group_id)
|
||||
if user is None:
|
||||
if user := await GroupInfoUser.get_or_none(user_qq=user_qq, group_id=group_id):
|
||||
result = ""
|
||||
result += "昵称:" + user.user_name + "\n"
|
||||
result += "加群时间:" + str(user.user_join_time.date())
|
||||
return result
|
||||
else:
|
||||
return "该群员不在列表中,请更新群成员信息"
|
||||
result = ""
|
||||
result += "昵称:" + user.user_name + "\n"
|
||||
result += "加群时间:" + str(user.user_join_time.date() + timedelta(hours=8))
|
||||
return result
|
||||
|
||||
|
||||
@my_level.handle()
|
||||
|
||||
@@ -1,35 +1,23 @@
|
||||
|
||||
from datetime import datetime
|
||||
from tortoise import fields
|
||||
|
||||
from services.db_context import db
|
||||
from services.db_context import Model
|
||||
|
||||
# 1.狂牙武器箱
|
||||
|
||||
|
||||
class BuffPrice(db.Model):
|
||||
__tablename__ = 'buff_prices'
|
||||
__table_args__ = {'extend_existing': True}
|
||||
class BuffPrice(Model):
|
||||
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
case_id = db.Column(db.Integer(), nullable=False)
|
||||
skin_name = db.Column(db.Unicode(), nullable=False)
|
||||
skin_price = db.Column(db.Float(), nullable=False)
|
||||
update_date = db.Column(db.DateTime(), nullable=False)
|
||||
|
||||
_idx1 = db.Index('buff_price_idx1', 'skin_name', unique=True)
|
||||
|
||||
@classmethod
|
||||
async def ensure(cls, skin_name: str, for_update: bool = False) -> 'BuffPrice':
|
||||
query = cls.query.where(
|
||||
(cls.skin_name == skin_name)
|
||||
)
|
||||
if for_update:
|
||||
query = query.with_for_update()
|
||||
user = await query.gino.first()
|
||||
return user or await cls.create(
|
||||
case_id=1,
|
||||
skin_name=skin_name,
|
||||
skin_price=0,
|
||||
update_date=datetime.min,
|
||||
)
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
case_id = fields.IntField()
|
||||
"""箱子id"""
|
||||
skin_name = fields.CharField(255, unique=True)
|
||||
"""皮肤名称"""
|
||||
skin_price = fields.FloatField()
|
||||
"""皮肤价格"""
|
||||
update_date = fields.DatetimeField()
|
||||
|
||||
class Meta:
|
||||
table = "buff_prices"
|
||||
table_description = "Buff价格数据表"
|
||||
|
||||
@@ -1,60 +1,51 @@
|
||||
from datetime import datetime
|
||||
from tortoise import fields
|
||||
|
||||
from services.db_context import db
|
||||
|
||||
|
||||
class OpenCasesUser(db.Model):
|
||||
__tablename__ = 'open_cases_users'
|
||||
__table_args__ = {'extend_existing': True}
|
||||
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||
group_id = db.Column(db.BigInteger(), nullable=False)
|
||||
total_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||
blue_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||
blue_st_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||
purple_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||
purple_st_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||
pink_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||
pink_st_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||
red_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||
red_st_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||
knife_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||
knife_st_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||
spend_money = db.Column(db.Integer(), nullable=False, default=0)
|
||||
make_money = db.Column(db.Float(), nullable=False, default=0)
|
||||
today_open_total = db.Column(db.Integer(), nullable=False, default=0)
|
||||
open_cases_time_last = db.Column(db.DateTime(timezone=True), nullable=False, default=datetime.now())
|
||||
knifes_name = db.Column(db.Unicode(), nullable=False, default="")
|
||||
|
||||
_idx1 = db.Index('open_cases_group_users_idx1', 'user_qq', 'group_id', unique=True)
|
||||
|
||||
@classmethod
|
||||
async def ensure(cls, user_qq: int, group_id: int, for_update: bool = False) -> 'OpenCasesUser':
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
)
|
||||
if for_update:
|
||||
query = query.with_for_update()
|
||||
user = await query.gino.first()
|
||||
return user or await cls.create(
|
||||
user_qq=user_qq,
|
||||
group_id=group_id,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def get_user_all(cls, group_id: int = None) -> 'list':
|
||||
user_list = []
|
||||
if not group_id:
|
||||
query = await cls.query.gino.all()
|
||||
else:
|
||||
query = await cls.query.where(
|
||||
(cls.group_id == group_id)
|
||||
).gino.all()
|
||||
for user in query:
|
||||
user_list.append(user)
|
||||
return user_list
|
||||
from services.db_context import Model
|
||||
|
||||
|
||||
class OpenCasesUser(Model):
|
||||
__tablename__ = "open_cases_users"
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
"""用户id"""
|
||||
group_id = fields.BigIntField()
|
||||
"""群聊id"""
|
||||
total_count = fields.IntField(default=0)
|
||||
"""总开启次数"""
|
||||
blue_count = fields.IntField(default=0)
|
||||
"""蓝色"""
|
||||
blue_st_count = fields.IntField(default=0)
|
||||
"""蓝色暗金"""
|
||||
purple_count = fields.IntField(default=0)
|
||||
"""紫色"""
|
||||
purple_st_count = fields.IntField(default=0)
|
||||
"""紫色暗金"""
|
||||
pink_count = fields.IntField(default=0)
|
||||
"""粉色"""
|
||||
pink_st_count = fields.IntField(default=0)
|
||||
"""粉色暗金"""
|
||||
red_count = fields.IntField(default=0)
|
||||
"""紫色"""
|
||||
red_st_count = fields.IntField(default=0)
|
||||
"""紫色暗金"""
|
||||
knife_count = fields.IntField(default=0)
|
||||
"""金色"""
|
||||
knife_st_count = fields.IntField(default=0)
|
||||
"""金色暗金"""
|
||||
spend_money = fields.IntField(default=0)
|
||||
"""花费金币"""
|
||||
make_money = fields.IntField(default=0)
|
||||
"""赚取金币"""
|
||||
today_open_total = fields.IntField(default=0)
|
||||
"""今日开箱数量"""
|
||||
open_cases_time_last = fields.DatetimeField()
|
||||
"""最后开箱日期"""
|
||||
knifes_name = fields.TextField(default="")
|
||||
"""已获取金色"""
|
||||
|
||||
class Meta:
|
||||
table = "open_cases_users"
|
||||
table_description = "开箱统计数据表"
|
||||
unique_together = ("user_qq", "group_id")
|
||||
|
||||
+191
-185
@@ -1,20 +1,22 @@
|
||||
from datetime import datetime, timedelta
|
||||
from .config import *
|
||||
from services.log import logger
|
||||
from services.db_context import db
|
||||
from .models.open_cases_user import OpenCasesUser
|
||||
from models.sign_group_user import SignGroupUser
|
||||
from utils.message_builder import image
|
||||
import pypinyin
|
||||
import random
|
||||
from .utils import get_price
|
||||
from .models.buff_prices import BuffPrice
|
||||
from PIL import Image
|
||||
from utils.image_utils import alpha2white_pil, BuildImage
|
||||
from configs.path_config import IMAGE_PATH
|
||||
import asyncio
|
||||
from utils.utils import cn2py
|
||||
import random
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import pypinyin
|
||||
from PIL import Image
|
||||
|
||||
from configs.config import Config
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from models.sign_group_user import SignGroupUser
|
||||
from services.log import logger
|
||||
from utils.image_utils import BuildImage, alpha2white_pil
|
||||
from utils.message_builder import image
|
||||
from utils.utils import cn2py
|
||||
|
||||
from .config import *
|
||||
from .models.buff_prices import BuffPrice
|
||||
from .models.open_cases_user import OpenCasesUser
|
||||
from .utils import get_price
|
||||
|
||||
|
||||
async def open_case(user_qq: int, group: int, case_name: str = "狂牙大行动") -> str:
|
||||
@@ -26,71 +28,76 @@ async def open_case(user_qq: int, group: int, case_name: str = "狂牙大行动"
|
||||
case = ""
|
||||
for i in pypinyin.pinyin(case_name, style=pypinyin.NORMAL):
|
||||
case += "".join(i)
|
||||
impression = (await SignGroupUser.ensure(user_qq, group)).impression
|
||||
user, _ = await SignGroupUser.get_or_create(user_qq=user_qq, group_id=group)
|
||||
impression = user.impression
|
||||
rand = random.random()
|
||||
async with db.transaction():
|
||||
user = await OpenCasesUser.ensure(user_qq, group, for_update=True)
|
||||
# 一天次数上限
|
||||
if user.today_open_total >= int(
|
||||
Config.get_config("open_cases", "INITIAL_OPEN_CASE_COUNT")
|
||||
+ int(impression)
|
||||
/ Config.get_config("open_cases", "EACH_IMPRESSION_ADD_COUNT")
|
||||
):
|
||||
return _handle_is_MAX_COUNT()
|
||||
skin, mosun = get_color_quality(rand, case_name)
|
||||
# 调侃
|
||||
if skin[:2] == "军规":
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[0] = 1
|
||||
else:
|
||||
uplist[1] = 1
|
||||
ridicule_result = random.choice(["这样看着才舒服", "是自己人,大伙把刀收好", "非常舒适~"])
|
||||
if skin[:2] == "受限":
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[2] = 1
|
||||
else:
|
||||
uplist[3] = 1
|
||||
ridicule_result = random.choice(
|
||||
["还行吧,勉强接受一下下", "居然不是蓝色,太假了", "运气-1-1-1-1-1..."]
|
||||
)
|
||||
if skin[:2] == "保密":
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[4] = 1
|
||||
else:
|
||||
uplist[5] = 1
|
||||
ridicule_result = random.choice(
|
||||
["开始不适....", "你妈妈买菜必涨价!涨三倍!", "你最近不适合出门,真的"]
|
||||
)
|
||||
if skin[:2] == "隐秘":
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[6] = 1
|
||||
else:
|
||||
uplist[7] = 1
|
||||
ridicule_result = random.choice(
|
||||
["已经非常不适", "好兄弟你开的什么箱子啊,一般箱子不是只有蓝色的吗", "开始拿阳寿开箱子了?"]
|
||||
)
|
||||
if skin[:2] == "罕见":
|
||||
knifes_flag = True
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[8] = 1
|
||||
else:
|
||||
uplist[9] = 1
|
||||
ridicule_result = random.choice(
|
||||
["你的好运我收到了,你可以去喂鲨鱼了", "最近该吃啥就迟点啥吧,哎,好好的一个人怎么就....哎", "众所周知,欧皇寿命极短."]
|
||||
)
|
||||
if skin.find("(") != -1:
|
||||
cskin = skin.split("(")
|
||||
skin = cskin[0].strip() + "(" + cskin[1].strip()
|
||||
skin = skin.split("|")[0].strip() + " | " + skin.split("|")[1].strip()
|
||||
# 价格
|
||||
if skin.find("无涂装") == -1:
|
||||
dbprice = await BuffPrice.ensure(skin[9:])
|
||||
await OpenCasesUser.get_or_none(user_qq=user_qq, group_id=group)
|
||||
# user, _ = await OpenCasesUser.get_or_create(user_qq=user_qq, group_id=group)
|
||||
user = await OpenCasesUser.get_or_none(user_qq=user_qq, group_id=group)
|
||||
if not user:
|
||||
user = await OpenCasesUser.create(
|
||||
user_qq=user_qq, group_id=group, open_cases_time_last=datetime.now()
|
||||
)
|
||||
# 一天次数上限
|
||||
if user.today_open_total >= int(
|
||||
Config.get_config("open_cases", "INITIAL_OPEN_CASE_COUNT")
|
||||
+ int(impression) / Config.get_config("open_cases", "EACH_IMPRESSION_ADD_COUNT")
|
||||
):
|
||||
return _handle_is_MAX_COUNT()
|
||||
skin, mosun = get_color_quality(rand, case_name)
|
||||
# 调侃
|
||||
if skin[:2] == "军规":
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[0] = 1
|
||||
else:
|
||||
dbprice = await BuffPrice.ensure(skin[9 : skin.rfind("(")].strip())
|
||||
if dbprice.skin_price != 0:
|
||||
price_result = dbprice.skin_price
|
||||
logger.info("数据库查询到价格: ", dbprice.skin_price)
|
||||
uplist[10] = dbprice.skin_price
|
||||
uplist[1] = 1
|
||||
ridicule_result = random.choice(["这样看着才舒服", "是自己人,大伙把刀收好", "非常舒适~"])
|
||||
if skin[:2] == "受限":
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[2] = 1
|
||||
else:
|
||||
uplist[3] = 1
|
||||
ridicule_result = random.choice(
|
||||
["还行吧,勉强接受一下下", "居然不是蓝色,太假了", "运气-1-1-1-1-1..."]
|
||||
)
|
||||
if skin[:2] == "保密":
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[4] = 1
|
||||
else:
|
||||
uplist[5] = 1
|
||||
ridicule_result = random.choice(["开始不适....", "你妈妈买菜必涨价!涨三倍!", "你最近不适合出门,真的"])
|
||||
if skin[:2] == "隐秘":
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[6] = 1
|
||||
else:
|
||||
uplist[7] = 1
|
||||
ridicule_result = random.choice(
|
||||
["已经非常不适", "好兄弟你开的什么箱子啊,一般箱子不是只有蓝色的吗", "开始拿阳寿开箱子了?"]
|
||||
)
|
||||
if skin[:2] == "罕见":
|
||||
knifes_flag = True
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[8] = 1
|
||||
else:
|
||||
uplist[9] = 1
|
||||
ridicule_result = random.choice(
|
||||
["你的好运我收到了,你可以去喂鲨鱼了", "最近该吃啥就迟点啥吧,哎,好好的一个人怎么就....哎", "众所周知,欧皇寿命极短."]
|
||||
)
|
||||
if skin.find("(") != -1:
|
||||
cskin = skin.split("(")
|
||||
skin = cskin[0].strip() + "(" + cskin[1].strip()
|
||||
skin = skin.split("|")[0].strip() + " | " + skin.split("|")[1].strip()
|
||||
# 价格
|
||||
if skin.find("无涂装") == -1:
|
||||
search_name = skin[9:]
|
||||
else:
|
||||
search_name = skin[9 : skin.rfind("(")].strip()
|
||||
price_result = 0
|
||||
if data := await BuffPrice.get_or_none(skin_name=search_name):
|
||||
if data.skin_price != 0:
|
||||
price_result = data.skin_price
|
||||
logger.info("数据库查询到价格: ", data.skin_price)
|
||||
uplist[10] = data.skin_price
|
||||
else:
|
||||
price = -1
|
||||
price_result = "未查询到"
|
||||
@@ -102,55 +109,56 @@ async def open_case(user_qq: int, group: int, case_name: str = "狂牙大行动"
|
||||
price = float(pcp[1].strip())
|
||||
break
|
||||
if price != -1:
|
||||
logger.info("存储入数据库---->", price)
|
||||
logger.info("存储入数据库---->{price}")
|
||||
uplist[10] = price
|
||||
price_result = str(price)
|
||||
await dbprice.update(
|
||||
skin_price=price,
|
||||
update_date=datetime.now(),
|
||||
).apply()
|
||||
# sp = skin.split("|")
|
||||
# cskin_word = sp[1][:sp[1].find("(") - 1].strip()
|
||||
if knifes_flag:
|
||||
await user.update(
|
||||
knifes_name=user.knifes_name
|
||||
+ f"{case}||{skin.split(':')[1].strip()} 磨损:{str(mosun)[:11]}, 价格:{uplist[10]},"
|
||||
).apply()
|
||||
cskin_word = skin.split(":")[1].replace("|", "-").replace("(StatTrak™)", "")
|
||||
cskin_word = cskin_word[: cskin_word.rfind("(")].strip()
|
||||
skin_name = cn2py(
|
||||
cskin_word.replace("|", "-").replace("(StatTrak™)", "").strip()
|
||||
data.skin_price = price
|
||||
data.update_date = datetime.now()
|
||||
await data.save(update_fields=["skin_price", "update_date"])
|
||||
# sp = skin.split("|")
|
||||
# cskin_word = sp[1][:sp[1].find("(") - 1].strip()
|
||||
if knifes_flag:
|
||||
await user.update(
|
||||
knifes_name=user.knifes_name
|
||||
+ f"{case}||{skin.split(':')[1].strip()} 磨损:{str(mosun)[:11]}, 价格:{uplist[10]},"
|
||||
).apply()
|
||||
cskin_word = skin.split(":")[1].replace("|", "-").replace("(StatTrak™)", "")
|
||||
cskin_word = cskin_word[: cskin_word.rfind("(")].strip()
|
||||
skin_name = cn2py(cskin_word.replace("|", "-").replace("(StatTrak™)", "").strip())
|
||||
img = image(IMAGE_PATH / "cases" / case / f"{skin_name}.png")
|
||||
# if knifes_flag:
|
||||
# await user.update(
|
||||
# knifes_name=user.knifes_name + f"{skin} 磨损:{mosun}, 价格:{uplist[10]}"
|
||||
# ).apply()
|
||||
if await update_user_total(user, uplist):
|
||||
logger.info(
|
||||
f"qq:{user_qq} 群:{group} 开启{case_name}武器箱 获得 {skin} 磨损:{mosun}, 价格:{uplist[10]}, 数据更新成功"
|
||||
)
|
||||
img = image(f"{skin_name}.png", "cases/" + case)
|
||||
# if knifes_flag:
|
||||
# await user.update(
|
||||
# knifes_name=user.knifes_name + f"{skin} 磨损:{mosun}, 价格:{uplist[10]}"
|
||||
# ).apply()
|
||||
if await update_user_total(user, uplist):
|
||||
logger.info(
|
||||
f"qq:{user_qq} 群:{group} 开启{case_name}武器箱 获得 {skin} 磨损:{mosun}, 价格:{uplist[10]}, 数据更新成功"
|
||||
)
|
||||
else:
|
||||
logger.warning(
|
||||
f"qq:{user_qq} 群:{group} 开启{case_name}武器箱 获得 {skin} 磨损:{mosun}, 价格:{uplist[10]}, 数据更新失败"
|
||||
)
|
||||
user = await OpenCasesUser.ensure(user_qq, group, for_update=True)
|
||||
over_count = int(
|
||||
else:
|
||||
logger.warning(
|
||||
f"qq:{user_qq} 群:{group} 开启{case_name}武器箱 获得 {skin} 磨损:{mosun}, 价格:{uplist[10]}, 数据更新失败"
|
||||
)
|
||||
user, _ = await OpenCasesUser.get_or_create(user_qq=user_qq, group_id=group)
|
||||
over_count = (
|
||||
int(
|
||||
Config.get_config("open_cases", "INITIAL_OPEN_CASE_COUNT")
|
||||
+ int(impression)
|
||||
/ Config.get_config("open_cases", "EACH_IMPRESSION_ADD_COUNT")
|
||||
) - user.today_open_total
|
||||
return (
|
||||
f"开启{case_name}武器箱.\n剩余开箱次数:{over_count}.\n" + img + "\n" + f"皮肤:{skin}\n"
|
||||
f"磨损:{mosun:.9f}\n"
|
||||
f"价格:{price_result}\n"
|
||||
f"{ridicule_result}"
|
||||
)
|
||||
- user.today_open_total
|
||||
)
|
||||
return (
|
||||
f"开启{case_name}武器箱.\n剩余开箱次数:{over_count}.\n" + img + "\n" + f"皮肤:{skin}\n"
|
||||
f"磨损:{mosun:.9f}\n"
|
||||
f"价格:{price_result}\n"
|
||||
f"{ridicule_result}"
|
||||
)
|
||||
|
||||
|
||||
async def open_shilian_case(user_qq: int, group: int, case_name: str, num: int = 10):
|
||||
user = await OpenCasesUser.ensure(user_qq, group, for_update=True)
|
||||
impression = (await SignGroupUser.ensure(user_qq, group)).impression
|
||||
user, _ = await OpenCasesUser.get_or_create(user_qq=user_qq, group_id=group)
|
||||
sign_user, _ = await SignGroupUser.get_or_create(user_qq=user_qq, group_id=group)
|
||||
impression = sign_user.impression
|
||||
max_count = int(
|
||||
Config.get_config("open_cases", "INITIAL_OPEN_CASE_COUNT")
|
||||
+ int(impression) / Config.get_config("open_cases", "EACH_IMPRESSION_ADD_COUNT")
|
||||
@@ -162,11 +170,10 @@ async def open_shilian_case(user_qq: int, group: int, case_name: str, num: int =
|
||||
f"今天开箱次数不足{num}次噢,请单抽试试看(也许单抽运气更好?)"
|
||||
f"\n剩余开箱次数:{max_count - user.today_open_total}"
|
||||
)
|
||||
await user.update(
|
||||
total_count=user.total_count + num,
|
||||
spend_money=user.spend_money + 17 * num,
|
||||
today_open_total=user.today_open_total + num,
|
||||
).apply()
|
||||
user.total_count = user.total_count + num
|
||||
user.spend_money = user.spend_money + 17 * num
|
||||
user.today_open_total = user.today_open_total + num
|
||||
await user.save(update_fields=["total_count", "spend_money", "today_open_total"])
|
||||
if num < 5:
|
||||
h = 270
|
||||
elif num % 5 == 0:
|
||||
@@ -180,46 +187,46 @@ async def open_shilian_case(user_qq: int, group: int, case_name: str, num: int =
|
||||
uplist = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0]
|
||||
img_list = []
|
||||
name_list = ["蓝", "蓝(暗金)", "紫", "紫(暗金)", "粉", "粉(暗金)", "红", "红(暗金)", "金", "金(暗金)"]
|
||||
async with db.transaction():
|
||||
for _ in range(num):
|
||||
knifes_flag = False
|
||||
rand = random.random()
|
||||
skin, mosun = get_color_quality(rand, case_name)
|
||||
if skin[:2] == "军规":
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[0] += 1
|
||||
else:
|
||||
uplist[1] += 1
|
||||
if skin[:2] == "受限":
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[2] += 1
|
||||
else:
|
||||
uplist[3] += 1
|
||||
if skin[:2] == "保密":
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[4] += 1
|
||||
else:
|
||||
uplist[5] += 1
|
||||
if skin[:2] == "隐秘":
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[6] += 1
|
||||
else:
|
||||
uplist[7] += 1
|
||||
if skin[:2] == "罕见":
|
||||
knifes_flag = True
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[8] += 1
|
||||
else:
|
||||
uplist[9] += 1
|
||||
if skin.find("(") != -1:
|
||||
cskin = skin.split("(")
|
||||
skin = cskin[0].strip() + "(" + cskin[1].strip()
|
||||
skin = skin.split("|")[0].strip() + " | " + skin.split("|")[1].strip()
|
||||
# 价格
|
||||
if skin.find("无涂装") == -1:
|
||||
dbprice = await BuffPrice.ensure(skin[9:])
|
||||
for _ in range(num):
|
||||
knifes_flag = False
|
||||
rand = random.random()
|
||||
skin, mosun = get_color_quality(rand, case_name)
|
||||
if skin[:2] == "军规":
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[0] += 1
|
||||
else:
|
||||
dbprice = await BuffPrice.ensure(skin[9 : skin.rfind("(")].strip())
|
||||
uplist[1] += 1
|
||||
if skin[:2] == "受限":
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[2] += 1
|
||||
else:
|
||||
uplist[3] += 1
|
||||
if skin[:2] == "保密":
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[4] += 1
|
||||
else:
|
||||
uplist[5] += 1
|
||||
if skin[:2] == "隐秘":
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[6] += 1
|
||||
else:
|
||||
uplist[7] += 1
|
||||
if skin[:2] == "罕见":
|
||||
knifes_flag = True
|
||||
if skin.find("StatTrak") == -1:
|
||||
uplist[8] += 1
|
||||
else:
|
||||
uplist[9] += 1
|
||||
if skin.find("(") != -1:
|
||||
cskin = skin.split("(")
|
||||
skin = cskin[0].strip() + "(" + cskin[1].strip()
|
||||
skin = skin.split("|")[0].strip() + " | " + skin.split("|")[1].strip()
|
||||
# 价格
|
||||
if skin.find("无涂装") == -1:
|
||||
search_name = skin[9:]
|
||||
else:
|
||||
search_name = skin[9 : skin.rfind("(")].strip()
|
||||
if dbprice := await BuffPrice.get_or_none(skin_name=search_name):
|
||||
if dbprice.skin_price != 0:
|
||||
price_result = dbprice.skin_price
|
||||
uplist[10] += price_result
|
||||
@@ -238,7 +245,6 @@ async def open_shilian_case(user_qq: int, group: int, case_name: str, num: int =
|
||||
style=pypinyin.NORMAL,
|
||||
):
|
||||
skin_name += "".join(i)
|
||||
# img = image(skin_name, "cases/" + case, "png")
|
||||
wImg = BuildImage(200, 270, 200, 200)
|
||||
wImg.paste(
|
||||
alpha2white_pil(
|
||||
@@ -296,7 +302,7 @@ def _handle_is_MAX_COUNT() -> str:
|
||||
|
||||
async def update_user_total(user: OpenCasesUser, up_list: list, num: int = 1) -> bool:
|
||||
try:
|
||||
await user.update(
|
||||
await user.update_or_create(
|
||||
total_count=user.total_count + num,
|
||||
blue_count=user.blue_count + up_list[0],
|
||||
blue_st_count=user.blue_st_count + up_list[1],
|
||||
@@ -312,36 +318,35 @@ async def update_user_total(user: OpenCasesUser, up_list: list, num: int = 1) ->
|
||||
make_money=user.make_money + up_list[10],
|
||||
today_open_total=user.today_open_total + num,
|
||||
open_cases_time_last=datetime.now(),
|
||||
).apply()
|
||||
)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
async def total_open_statistics(user_qq: int, group: int) -> str:
|
||||
async with db.transaction():
|
||||
user = await OpenCasesUser.ensure(user_qq, group, for_update=True)
|
||||
return (
|
||||
f"开箱总数:{user.total_count}\n"
|
||||
f"今日开箱:{user.today_open_total}\n"
|
||||
f"蓝色军规:{user.blue_count}\n"
|
||||
f"蓝色暗金:{user.blue_st_count}\n"
|
||||
f"紫色受限:{user.purple_count}\n"
|
||||
f"紫色暗金:{user.purple_st_count}\n"
|
||||
f"粉色保密:{user.pink_count}\n"
|
||||
f"粉色暗金:{user.pink_st_count}\n"
|
||||
f"红色隐秘:{user.red_count}\n"
|
||||
f"红色暗金:{user.red_st_count}\n"
|
||||
f"金色罕见:{user.knife_count}\n"
|
||||
f"金色暗金:{user.knife_st_count}\n"
|
||||
f"花费金额:{user.spend_money}\n"
|
||||
f"获取金额:{user.make_money:.2f}\n"
|
||||
f"最后开箱日期:{(user.open_cases_time_last + timedelta(hours=8)).date()}"
|
||||
)
|
||||
user, _ = await OpenCasesUser.get_or_create(user_qq=user_qq, group_id=group)
|
||||
return (
|
||||
f"开箱总数:{user.total_count}\n"
|
||||
f"今日开箱:{user.today_open_total}\n"
|
||||
f"蓝色军规:{user.blue_count}\n"
|
||||
f"蓝色暗金:{user.blue_st_count}\n"
|
||||
f"紫色受限:{user.purple_count}\n"
|
||||
f"紫色暗金:{user.purple_st_count}\n"
|
||||
f"粉色保密:{user.pink_count}\n"
|
||||
f"粉色暗金:{user.pink_st_count}\n"
|
||||
f"红色隐秘:{user.red_count}\n"
|
||||
f"红色暗金:{user.red_st_count}\n"
|
||||
f"金色罕见:{user.knife_count}\n"
|
||||
f"金色暗金:{user.knife_st_count}\n"
|
||||
f"花费金额:{user.spend_money}\n"
|
||||
f"获取金额:{user.make_money:.2f}\n"
|
||||
f"最后开箱日期:{user.open_cases_time_last.date()}"
|
||||
)
|
||||
|
||||
|
||||
async def group_statistics(group: int):
|
||||
user_list = await OpenCasesUser.get_user_all(group)
|
||||
user_list = await OpenCasesUser.filter(group_id=group).all()
|
||||
# lan zi fen hong jin pricei
|
||||
uplist = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0, 0, 0]
|
||||
for user in user_list:
|
||||
@@ -377,7 +382,8 @@ async def group_statistics(group: int):
|
||||
|
||||
|
||||
async def my_knifes_name(user_id: int, group: int):
|
||||
knifes_name = (await OpenCasesUser.ensure(user_id, group)).knifes_name
|
||||
user, _ = await OpenCasesUser.get_or_create(user_qq=user_id, group_id=group)
|
||||
knifes_name = user.knifes_name
|
||||
if knifes_name:
|
||||
knifes_list = knifes_name[:-1].split(",")
|
||||
length = len(knifes_list)
|
||||
|
||||
+124
-125
@@ -1,17 +1,19 @@
|
||||
from .models.buff_prices import BuffPrice
|
||||
from services.db_context import db
|
||||
from datetime import datetime, timedelta
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from .models.open_cases_user import OpenCasesUser
|
||||
from services.log import logger
|
||||
from utils.utils import get_bot, cn2py
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from nonebot.adapters.onebot.v11 import ActionFailed
|
||||
from configs.config import Config
|
||||
from utils.manager import group_manager
|
||||
from .config import *
|
||||
import os
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from nonebot.adapters.onebot.v11 import ActionFailed
|
||||
|
||||
from configs.config import Config
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from services.log import logger
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.manager import group_manager
|
||||
from utils.utils import cn2py, get_bot
|
||||
|
||||
from .config import *
|
||||
from .models.buff_prices import BuffPrice
|
||||
from .models.open_cases_user import OpenCasesUser
|
||||
|
||||
url = "https://buff.163.com/api/market/goods"
|
||||
# proxies = 'http://49.75.59.242:3128'
|
||||
@@ -49,108 +51,102 @@ async def util_get_buff_price(case_name: str = "狂牙大行动") -> str:
|
||||
"骷髅匕首 | 无涂装",
|
||||
]:
|
||||
skin = skin.split("|")[0].strip()
|
||||
async with db.transaction():
|
||||
name_list = []
|
||||
price_list = []
|
||||
parameter = {"game": "csgo", "page_num": "1", "search": skin}
|
||||
try:
|
||||
response = await AsyncHttpx.get(url, proxy=Config.get_config("open_cases", "BUFF_PROXY"),
|
||||
name_list = []
|
||||
price_list = []
|
||||
parameter = {"game": "csgo", "page_num": "1", "search": skin}
|
||||
try:
|
||||
response = await AsyncHttpx.get(
|
||||
url,
|
||||
proxy=Config.get_config("open_cases", "BUFF_PROXY"),
|
||||
params=parameter,
|
||||
cookies=cookie,)
|
||||
if response.status_code == 200:
|
||||
data = response.json()["data"]
|
||||
total_page = data["total_page"]
|
||||
data = data["items"]
|
||||
flag = False
|
||||
if (
|
||||
skin.find("|") == -1
|
||||
): # in ['蝴蝶刀', '求生匕首', '流浪者匕首', '系绳匕首', '骷髅匕首']:
|
||||
for i in range(1, total_page + 1):
|
||||
name_list = []
|
||||
price_list = []
|
||||
parameter = {
|
||||
"game": "csgo",
|
||||
"page_num": f"{i}",
|
||||
"search": skin,
|
||||
}
|
||||
res = await AsyncHttpx.get(url, params=parameter, cookies=cookie)
|
||||
data = res.json()["data"][
|
||||
"items"
|
||||
]
|
||||
for j in range(len(data)):
|
||||
if data[j]["name"] in [f"{skin}(★)"]:
|
||||
name = data[j]["name"]
|
||||
price = data[j][
|
||||
"sell_reference_price"
|
||||
]
|
||||
name_list.append(
|
||||
name.split("(")[0].strip()
|
||||
+ " | 无涂装"
|
||||
)
|
||||
price_list.append(price)
|
||||
flag = True
|
||||
break
|
||||
if flag:
|
||||
cookies=cookie,
|
||||
)
|
||||
if response.status_code == 200:
|
||||
data = response.json()["data"]
|
||||
total_page = data["total_page"]
|
||||
data = data["items"]
|
||||
flag = False
|
||||
if (
|
||||
skin.find("|") == -1
|
||||
): # in ['蝴蝶刀', '求生匕首', '流浪者匕首', '系绳匕首', '骷髅匕首']:
|
||||
for i in range(1, total_page + 1):
|
||||
name_list = []
|
||||
price_list = []
|
||||
parameter = {
|
||||
"game": "csgo",
|
||||
"page_num": f"{i}",
|
||||
"search": skin,
|
||||
}
|
||||
res = await AsyncHttpx.get(
|
||||
url, params=parameter, cookies=cookie
|
||||
)
|
||||
data = res.json()["data"]["items"]
|
||||
for j in range(len(data)):
|
||||
if data[j]["name"] in [f"{skin}(★)"]:
|
||||
name = data[j]["name"]
|
||||
price = data[j]["sell_reference_price"]
|
||||
name_list.append(
|
||||
name.split("(")[0].strip() + " | 无涂装"
|
||||
)
|
||||
price_list.append(price)
|
||||
flag = True
|
||||
break
|
||||
else:
|
||||
try:
|
||||
for _ in range(total_page):
|
||||
for i in range(len(data)):
|
||||
name = data[i]["name"]
|
||||
price = data[i]["sell_reference_price"]
|
||||
name_list.append(name)
|
||||
price_list.append(price)
|
||||
except Exception as e:
|
||||
failed_list.append(skin)
|
||||
logger.warning(f"{skin}更新失败")
|
||||
if flag:
|
||||
break
|
||||
else:
|
||||
failed_list.append(skin)
|
||||
logger.warning(f"{skin}更新失败")
|
||||
except Exception:
|
||||
try:
|
||||
for _ in range(total_page):
|
||||
for i in range(len(data)):
|
||||
name = data[i]["name"]
|
||||
price = data[i]["sell_reference_price"]
|
||||
name_list.append(name)
|
||||
price_list.append(price)
|
||||
except Exception as e:
|
||||
failed_list.append(skin)
|
||||
logger.warning(f"{skin}更新失败")
|
||||
else:
|
||||
failed_list.append(skin)
|
||||
logger.warning(f"{skin}更新失败")
|
||||
continue
|
||||
for i in range(len(name_list)):
|
||||
name = name_list[i].strip()
|
||||
price = float(price_list[i])
|
||||
if name.find("(★)") != -1:
|
||||
name = name[: name.find("(")] + name[name.find(")") + 1 :]
|
||||
if name.find("消音") != -1 and name.find("(S") != -1:
|
||||
name = name.split("(")[0][:-4] + "(" + name.split("(")[1]
|
||||
name = (
|
||||
name.split("|")[0].strip()
|
||||
+ " | "
|
||||
+ name.split("|")[1].strip()
|
||||
)
|
||||
elif name.find("消音") != -1:
|
||||
name = (
|
||||
name.split("|")[0][:-5].strip()
|
||||
+ " | "
|
||||
+ name.split("|")[1].strip()
|
||||
)
|
||||
if name.find(" 18 ") != -1 and name.find("(S") != -1:
|
||||
name = name.split("(")[0][:-5] + "(" + name.split("(")[1]
|
||||
name = (
|
||||
name.split("|")[0].strip()
|
||||
+ " | "
|
||||
+ name.split("|")[1].strip()
|
||||
)
|
||||
elif name.find(" 18 ") != -1:
|
||||
name = (
|
||||
name.split("|")[0][:-6].strip()
|
||||
+ " | "
|
||||
+ name.split("|")[1].strip()
|
||||
)
|
||||
dbskin = await BuffPrice.ensure(name, True)
|
||||
if (
|
||||
dbskin.update_date + timedelta(8)
|
||||
).date() == datetime.now().date():
|
||||
except Exception:
|
||||
failed_list.append(skin)
|
||||
logger.warning(f"{skin}更新失败")
|
||||
continue
|
||||
for i in range(len(name_list)):
|
||||
name = name_list[i].strip()
|
||||
price = float(price_list[i])
|
||||
if name.find("(★)") != -1:
|
||||
name = name[: name.find("(")] + name[name.find(")") + 1 :]
|
||||
if name.find("消音") != -1 and name.find("(S") != -1:
|
||||
name = name.split("(")[0][:-4] + "(" + name.split("(")[1]
|
||||
name = (
|
||||
name.split("|")[0].strip() + " | " + name.split("|")[1].strip()
|
||||
)
|
||||
elif name.find("消音") != -1:
|
||||
name = (
|
||||
name.split("|")[0][:-5].strip()
|
||||
+ " | "
|
||||
+ name.split("|")[1].strip()
|
||||
)
|
||||
if name.find(" 18 ") != -1 and name.find("(S") != -1:
|
||||
name = name.split("(")[0][:-5] + "(" + name.split("(")[1]
|
||||
name = (
|
||||
name.split("|")[0].strip() + " | " + name.split("|")[1].strip()
|
||||
)
|
||||
elif name.find(" 18 ") != -1:
|
||||
name = (
|
||||
name.split("|")[0][:-6].strip()
|
||||
+ " | "
|
||||
+ name.split("|")[1].strip()
|
||||
)
|
||||
if dbskin := await BuffPrice.get_or_none(skin_name=name):
|
||||
if dbskin.update_date.date() == datetime.now().date():
|
||||
continue
|
||||
await dbskin.update(
|
||||
case_id=case_id,
|
||||
skin_price=price,
|
||||
update_date=datetime.now(),
|
||||
).apply()
|
||||
dbskin.case_id = case_id
|
||||
dbskin.skin_price = price
|
||||
dbskin.update_date = datetime.now()
|
||||
await dbskin.save(
|
||||
update_fields=["case_id", "skin_price", "update_date"]
|
||||
)
|
||||
logger.info(f"{name_list[i]}---------->成功更新")
|
||||
result = None
|
||||
if failed_list:
|
||||
@@ -186,14 +182,16 @@ async def util_get_buff_img(case_name: str = "狂牙大行动") -> str:
|
||||
logger.info(f"开始更新----->{skin}")
|
||||
skin_name = ""
|
||||
# try:
|
||||
response = await AsyncHttpx.get(url, proxy=Config.get_config("open_cases", "BUFF_PROXY"), params=parameter)
|
||||
response = await AsyncHttpx.get(
|
||||
url,
|
||||
proxy=Config.get_config("open_cases", "BUFF_PROXY"),
|
||||
params=parameter,
|
||||
)
|
||||
if response.status_code == 200:
|
||||
data = response.json()["data"]
|
||||
total_page = data["total_page"]
|
||||
flag = False
|
||||
if (
|
||||
skin.find("|") == -1
|
||||
): # in ['蝴蝶刀', '求生匕首', '流浪者匕首', '系绳匕首', '骷髅匕首']:
|
||||
if skin.find("|") == -1: # in ['蝴蝶刀', '求生匕首', '流浪者匕首', '系绳匕首', '骷髅匕首']:
|
||||
for i in range(1, total_page + 1):
|
||||
res = await AsyncHttpx.get(url, params=parameter)
|
||||
data = res.json()["data"]["items"]
|
||||
@@ -201,17 +199,21 @@ async def util_get_buff_img(case_name: str = "狂牙大行动") -> str:
|
||||
if data[j]["name"] in [f"{skin}(★)"]:
|
||||
img_url = data[j]["goods_info"]["icon_url"]
|
||||
skin_name = cn2py(skin + "无涂装")
|
||||
await AsyncHttpx.download_file(img_url, path / f"{skin_name}.png")
|
||||
await AsyncHttpx.download_file(
|
||||
img_url, path / f"{skin_name}.png"
|
||||
)
|
||||
flag = True
|
||||
break
|
||||
if flag:
|
||||
break
|
||||
else:
|
||||
img_url = (await response.json())["data"]["items"][0][
|
||||
"goods_info"
|
||||
]["icon_url"]
|
||||
img_url = (await response.json())["data"]["items"][0]["goods_info"][
|
||||
"icon_url"
|
||||
]
|
||||
skin_name += cn2py(skin.replace("|", "-").strip())
|
||||
if await AsyncHttpx.download_file(img_url, path / f"{skin_name}.png"):
|
||||
if await AsyncHttpx.download_file(
|
||||
img_url, path / f"{skin_name}.png"
|
||||
):
|
||||
logger.info(f"------->写入 {skin} 成功")
|
||||
else:
|
||||
logger.info(f"------->写入 {skin} 失败")
|
||||
@@ -255,18 +257,15 @@ async def get_price(d_name):
|
||||
|
||||
async def update_count_daily():
|
||||
try:
|
||||
users = await OpenCasesUser.get_user_all()
|
||||
if users:
|
||||
for user in users:
|
||||
await user.update(
|
||||
today_open_total=0,
|
||||
).apply()
|
||||
await OpenCasesUser.all().update(today_open_total=0)
|
||||
bot = get_bot()
|
||||
gl = await bot.get_group_list()
|
||||
gl = [g["group_id"] for g in gl]
|
||||
for g in gl:
|
||||
try:
|
||||
await bot.send_group_msg(group_id=g, message="[[_task|open_case_reset_remind]]今日开箱次数重置成功")
|
||||
await bot.send_group_msg(
|
||||
group_id=g, message="[[_task|open_case_reset_remind]]今日开箱次数重置成功"
|
||||
)
|
||||
except ActionFailed:
|
||||
logger.warning(f"{g} 群被禁言,无法发送 开箱重置提醒")
|
||||
logger.info("今日开箱次数重置成功")
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
from nonebot import on_message
|
||||
from services.log import logger
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, ActionFailed
|
||||
|
||||
from utils.manager import group_manager
|
||||
from utils.utils import get_message_json, get_local_proxy, is_number, get_message_text
|
||||
from nonebot.adapters.onebot.v11.permission import GROUP
|
||||
from utils.message_builder import image
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.browser import get_browser
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from configs.config import Config
|
||||
from utils.user_agent import get_user_agent
|
||||
import aiohttp
|
||||
import asyncio
|
||||
import time
|
||||
|
||||
import aiohttp
|
||||
import ujson as json
|
||||
from bilireq import video
|
||||
from nonebot import on_message
|
||||
from nonebot.adapters.onebot.v11 import ActionFailed, GroupMessageEvent
|
||||
from nonebot.adapters.onebot.v11.permission import GROUP
|
||||
|
||||
from configs.config import Config
|
||||
from configs.path_config import IMAGE_PATH, TEMP_PATH
|
||||
from services.log import logger
|
||||
from utils.browser import get_browser
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.manager import group_manager
|
||||
from utils.message_builder import image
|
||||
from utils.user_agent import get_user_agent
|
||||
from utils.utils import get_local_proxy, get_message_json, get_message_text, is_number
|
||||
|
||||
__zx_plugin_name__ = "B站转发解析"
|
||||
__plugin_usage__ = """
|
||||
usage:
|
||||
@@ -39,7 +41,10 @@ Config.add_plugin_config(
|
||||
async def plugin_on_checker(event: GroupMessageEvent) -> bool:
|
||||
return group_manager.get_plugin_status("parse_bilibili_json", event.group_id)
|
||||
|
||||
parse_bilibili_json = on_message(priority=1, permission=GROUP, block=False, rule=plugin_on_checker)
|
||||
|
||||
parse_bilibili_json = on_message(
|
||||
priority=1, permission=GROUP, block=False, rule=plugin_on_checker
|
||||
)
|
||||
|
||||
_tmp = {}
|
||||
|
||||
@@ -55,16 +60,14 @@ async def _(event: GroupMessageEvent):
|
||||
data = None
|
||||
if data:
|
||||
# 转发视频
|
||||
if data.get("desc") == "哔哩哔哩" or data.get('prompt').find('哔哩哔哩') != -1:
|
||||
async with aiohttp.ClientSession(
|
||||
headers=get_user_agent()
|
||||
) as session:
|
||||
if data.get("desc") == "哔哩哔哩" or "哔哩哔哩" in data.get("prompt"):
|
||||
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
|
||||
async with session.get(
|
||||
data["meta"]["detail_1"]["qqdocurl"],
|
||||
timeout=7,
|
||||
data["meta"]["detail_1"]["qqdocurl"],
|
||||
timeout=7,
|
||||
) as response:
|
||||
url = str(response.url).split("?")[0]
|
||||
if url[-1] == '/':
|
||||
if url[-1] == "/":
|
||||
url = url[:-1]
|
||||
bvid = url.split("/")[-1]
|
||||
vd_info = await video.get_video_base_info(bvid)
|
||||
@@ -93,10 +96,11 @@ async def _(event: GroupMessageEvent):
|
||||
timeout=100000,
|
||||
)
|
||||
await asyncio.get_event_loop().run_in_executor(
|
||||
None, resize, f"{IMAGE_PATH}/temp/cv_{event.user_id}.png"
|
||||
None, resize, TEMP_PATH / f"cv_{event.user_id}.png"
|
||||
)
|
||||
await parse_bilibili_json.send(
|
||||
"[[_task|bilibili_parse]]" + image(f"cv_{event.user_id}.png", "temp")
|
||||
"[[_task|bilibili_parse]]"
|
||||
+ image(TEMP_PATH / f"cv_{event.user_id}.png")
|
||||
)
|
||||
await page.close()
|
||||
logger.info(
|
||||
@@ -121,15 +125,13 @@ async def _(event: GroupMessageEvent):
|
||||
msg = msg[index + 2 : index + 11]
|
||||
if is_number(msg):
|
||||
url = f"https://www.bilibili.com/video/av{msg}"
|
||||
vd_info = await video.get_video_base_info('av' + msg)
|
||||
vd_info = await video.get_video_base_info("av" + msg)
|
||||
elif "https://b23.tv" in msg:
|
||||
url = "https://" + msg[msg.find("b23.tv"): msg.find("b23.tv") + 14]
|
||||
async with aiohttp.ClientSession(
|
||||
headers=get_user_agent()
|
||||
) as session:
|
||||
url = "https://" + msg[msg.find("b23.tv") : msg.find("b23.tv") + 14]
|
||||
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
|
||||
async with session.get(
|
||||
url,
|
||||
timeout=7,
|
||||
url,
|
||||
timeout=7,
|
||||
) as response:
|
||||
url = (str(response.url).split("?")[0]).strip("/")
|
||||
bvid = url.split("/")[-1]
|
||||
@@ -150,8 +152,9 @@ async def _(event: GroupMessageEvent):
|
||||
date = time.strftime("%Y-%m-%d", time.localtime(vd_info["ctime"]))
|
||||
try:
|
||||
await parse_bilibili_json.send(
|
||||
"[[_task|bilibili_parse]]" +
|
||||
image(vd_info["pic"]) + f"\nav{aid}\n标题:{title}\n"
|
||||
"[[_task|bilibili_parse]]"
|
||||
+ image(vd_info["pic"])
|
||||
+ f"\nav{aid}\n标题:{title}\n"
|
||||
f"UP:{author}\n"
|
||||
f"上传日期:{date}\n"
|
||||
f"回复:{reply},收藏:{favorite},投币:{coin}\n"
|
||||
|
||||
+10
-10
@@ -1,17 +1,17 @@
|
||||
from asyncio.exceptions import TimeoutError
|
||||
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, Message, GroupMessageEvent
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message, MessageEvent
|
||||
from nonebot.params import Arg, CommandArg
|
||||
from nonebot.typing import T_State
|
||||
|
||||
from configs.config import Config
|
||||
from utils.utils import is_number, change_pixiv_image_links
|
||||
from utils.message_builder import image
|
||||
from configs.path_config import IMAGE_PATH, TEMP_PATH
|
||||
from services.log import logger
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from utils.manager import withdraw_message_manager
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from nonebot.params import CommandArg, Arg
|
||||
|
||||
from utils.manager import withdraw_message_manager
|
||||
from utils.message_builder import image
|
||||
from utils.utils import change_pixiv_image_links, is_number
|
||||
|
||||
__zx_plugin_name__ = "pid搜索"
|
||||
__plugin_usage__ = """
|
||||
@@ -88,7 +88,7 @@ async def _g(event: MessageEvent, state: T_State, pid: str = Arg("pid")):
|
||||
img_url = change_pixiv_image_links(img_url)
|
||||
if not await AsyncHttpx.download_file(
|
||||
img_url,
|
||||
IMAGE_PATH / "temp" / f"pid_search_{event.user_id}_{i}.png",
|
||||
TEMP_PATH / f"pid_search_{event.user_id}_{i}.png",
|
||||
headers=headers,
|
||||
):
|
||||
await pid_search.send("图片下载失败了....", at_sender=True)
|
||||
@@ -101,7 +101,7 @@ async def _g(event: MessageEvent, state: T_State, pid: str = Arg("pid")):
|
||||
f"pid:{pid}\n"
|
||||
f"author:{author}\n"
|
||||
f"author_id:{author_id}\n"
|
||||
f'{image(f"pid_search_{event.user_id}_{i}.png", "temp")}'
|
||||
f'{image(TEMP_PATH / f"pid_search_{event.user_id}_{i}.png")}'
|
||||
f"{tmp}"
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from configs.config import Config
|
||||
from utils.utils import GDict
|
||||
import nonebot
|
||||
|
||||
from configs.config import Config
|
||||
from utils.utils import GDict
|
||||
|
||||
Config.add_plugin_config(
|
||||
"hibiapi",
|
||||
@@ -10,59 +10,42 @@ Config.add_plugin_config(
|
||||
help_="如果没有自建或其他hibiapi请不要修改",
|
||||
default_value="https://api.obfs.dev",
|
||||
)
|
||||
Config.add_plugin_config(
|
||||
"pixiv",
|
||||
"PIXIV_NGINX_URL",
|
||||
"i.pximg.cf",
|
||||
help_="Pixiv反向代理"
|
||||
)
|
||||
Config.add_plugin_config("pixiv", "PIXIV_NGINX_URL", "i.pximg.cf", help_="Pixiv反向代理")
|
||||
Config.add_plugin_config(
|
||||
"pix",
|
||||
"PIX_IMAGE_SIZE",
|
||||
"master",
|
||||
name="PIX图库",
|
||||
help_="PIX图库下载的画质 可能的值:original:原图,master:缩略图(加快发送速度)",
|
||||
default_value="master"
|
||||
default_value="master",
|
||||
)
|
||||
Config.add_plugin_config(
|
||||
"pix",
|
||||
"SEARCH_HIBIAPI_BOOKMARKS",
|
||||
5000,
|
||||
help_="最低收藏,PIX使用HIBIAPI搜索图片时达到最低收藏才会添加至图库",
|
||||
default_value=5000
|
||||
default_value=5000,
|
||||
)
|
||||
Config.add_plugin_config(
|
||||
"pix",
|
||||
"WITHDRAW_PIX_MESSAGE",
|
||||
(0, 1),
|
||||
help_="自动撤回,参1:延迟撤回色图时间(秒),0 为关闭 | 参2:监控聊天类型,0(私聊) 1(群聊) 2(群聊+私聊)",
|
||||
default_value=(0, 1)
|
||||
default_value=(0, 1),
|
||||
)
|
||||
Config.add_plugin_config(
|
||||
"pix",
|
||||
"PIX_OMEGA_PIXIV_RATIO",
|
||||
(10, 0),
|
||||
help_="PIX图库 与 额外图库OmegaPixivIllusts 混合搜索的比例 参1:PIX图库 参2:OmegaPixivIllusts扩展图库(没有此图库请设置为0)",
|
||||
default_value=(10, 0)
|
||||
)
|
||||
Config.add_plugin_config(
|
||||
"pix",
|
||||
"TIMEOUT",
|
||||
10,
|
||||
help_="下载图片超时限制(秒)",
|
||||
default_value=10
|
||||
default_value=(10, 0),
|
||||
)
|
||||
Config.add_plugin_config("pix", "TIMEOUT", 10, help_="下载图片超时限制(秒)", default_value=10)
|
||||
|
||||
Config.add_plugin_config(
|
||||
"pix",
|
||||
"SHOW_INFO",
|
||||
True,
|
||||
help_="是否显示图片的基本信息,如PID等",
|
||||
default_value=True
|
||||
"pix", "SHOW_INFO", True, help_="是否显示图片的基本信息,如PID等", default_value=True
|
||||
)
|
||||
|
||||
GDict['run_sql'].append("ALTER TABLE omega_pixiv_illusts ADD classified Integer;")
|
||||
GDict["run_sql"].append("ALTER TABLE omega_pixiv_illusts ADD classified Integer;")
|
||||
|
||||
nonebot.load_plugins("plugins/pix_gallery")
|
||||
|
||||
|
||||
|
||||
+123
-116
@@ -1,19 +1,23 @@
|
||||
from asyncpg.exceptions import UniqueViolationError
|
||||
from ._model.omega_pixiv_illusts import OmegaPixivIllusts
|
||||
from asyncio.locks import Semaphore
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from ._model.pixiv import Pixiv
|
||||
from typing import List, Optional
|
||||
from utils.utils import change_pixiv_image_links, change_img_md5
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from services.log import logger
|
||||
from configs.config import Config
|
||||
from configs.path_config import TEMP_PATH
|
||||
import aiofiles
|
||||
import platform
|
||||
import asyncio
|
||||
import math
|
||||
import platform
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from asyncio.locks import Semaphore
|
||||
from copy import deepcopy
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
import aiofiles
|
||||
from asyncpg.exceptions import UniqueViolationError
|
||||
|
||||
from configs.config import Config
|
||||
from configs.path_config import TEMP_PATH
|
||||
from services.log import logger
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.utils import change_img_md5, change_pixiv_image_links
|
||||
|
||||
from ._model.omega_pixiv_illusts import OmegaPixivIllusts
|
||||
from ._model.pixiv import Pixiv
|
||||
|
||||
try:
|
||||
import ujson as json
|
||||
@@ -65,9 +69,7 @@ async def start_update_image_url(
|
||||
params = {"word": keyword, "page": page}
|
||||
tasks.append(
|
||||
asyncio.ensure_future(
|
||||
search_image(
|
||||
url, keyword, params, semaphore, page, black_pid
|
||||
)
|
||||
search_image(url, keyword, params, semaphore, page, black_pid)
|
||||
)
|
||||
)
|
||||
if keyword.startswith("pid:"):
|
||||
@@ -101,96 +103,91 @@ async def search_image(
|
||||
pic_count = 0
|
||||
pid_count = 0
|
||||
async with semaphore:
|
||||
try:
|
||||
data = (await AsyncHttpx.get(url, params=params)).json()
|
||||
if (
|
||||
not data
|
||||
or data.get("error")
|
||||
or (not data.get("illusts") and not data.get("illust"))
|
||||
):
|
||||
return 0, 0
|
||||
if url != f"{HIBIAPI}/api/pixiv/illust":
|
||||
logger.info(f'{keyword}: 获取数据成功...数据总量:{len(data["illusts"])}')
|
||||
data = data["illusts"]
|
||||
# try:
|
||||
data = (await AsyncHttpx.get(url, params=params)).json()
|
||||
if (
|
||||
not data
|
||||
or data.get("error")
|
||||
or (not data.get("illusts") and not data.get("illust"))
|
||||
):
|
||||
return 0, 0
|
||||
if url != f"{HIBIAPI}/api/pixiv/illust":
|
||||
logger.info(f'{keyword}: 获取数据成功...数据总量:{len(data["illusts"])}')
|
||||
data = data["illusts"]
|
||||
else:
|
||||
logger.info(f'获取数据成功...PID:{params.get("id")}')
|
||||
data = [data["illust"]]
|
||||
img_data = {}
|
||||
for x in data:
|
||||
pid = x["id"]
|
||||
title = x["title"]
|
||||
width = x["width"]
|
||||
height = x["height"]
|
||||
view = x["total_view"]
|
||||
bookmarks = x["total_bookmarks"]
|
||||
uid = x["user"]["id"]
|
||||
author = x["user"]["name"]
|
||||
tags = []
|
||||
for tag in x["tags"]:
|
||||
for i in tag:
|
||||
if tag[i]:
|
||||
tags.append(tag[i])
|
||||
img_urls = []
|
||||
if x["page_count"] == 1:
|
||||
img_urls.append(x["meta_single_page"]["original_image_url"])
|
||||
else:
|
||||
logger.info(f'获取数据成功...PID:{params.get("id")}')
|
||||
data = [data["illust"]]
|
||||
img_data = {}
|
||||
for x in data:
|
||||
pid = x["id"]
|
||||
title = x["title"]
|
||||
width = x["width"]
|
||||
height = x["height"]
|
||||
view = x["total_view"]
|
||||
bookmarks = x["total_bookmarks"]
|
||||
uid = x["user"]["id"]
|
||||
author = x["user"]["name"]
|
||||
tags = []
|
||||
for tag in x["tags"]:
|
||||
for i in tag:
|
||||
if tag[i]:
|
||||
tags.append(tag[i])
|
||||
img_urls = []
|
||||
if x["page_count"] == 1:
|
||||
img_urls.append(x["meta_single_page"]["original_image_url"])
|
||||
else:
|
||||
for urls in x["meta_pages"]:
|
||||
img_urls.append(urls["image_urls"]["original"])
|
||||
if (
|
||||
(
|
||||
bookmarks
|
||||
>= Config.get_config("pix", "SEARCH_HIBIAPI_BOOKMARKS")
|
||||
or (
|
||||
url == f"{HIBIAPI}/api/pixiv/member_illust"
|
||||
and bookmarks >= 1500
|
||||
)
|
||||
or (url == f"{HIBIAPI}/api/pixiv/illust")
|
||||
for urls in x["meta_pages"]:
|
||||
img_urls.append(urls["image_urls"]["original"])
|
||||
if (
|
||||
(
|
||||
bookmarks >= Config.get_config("pix", "SEARCH_HIBIAPI_BOOKMARKS")
|
||||
or (
|
||||
url == f"{HIBIAPI}/api/pixiv/member_illust"
|
||||
and bookmarks >= 1500
|
||||
)
|
||||
and len(img_urls) < 10
|
||||
and _check_black(img_urls, black)
|
||||
or (url == f"{HIBIAPI}/api/pixiv/illust")
|
||||
)
|
||||
and len(img_urls) < 10
|
||||
and _check_black(img_urls, black)
|
||||
):
|
||||
img_data[pid] = {
|
||||
"pid": pid,
|
||||
"title": title,
|
||||
"width": width,
|
||||
"height": height,
|
||||
"view": view,
|
||||
"bookmarks": bookmarks,
|
||||
"img_urls": img_urls,
|
||||
"uid": uid,
|
||||
"author": author,
|
||||
"tags": tags,
|
||||
}
|
||||
else:
|
||||
continue
|
||||
for x in img_data.keys():
|
||||
data = img_data[x]
|
||||
data_copy = deepcopy(data)
|
||||
del data_copy["img_urls"]
|
||||
for img_url in data["img_urls"]:
|
||||
img_p = img_url[img_url.rfind("_") + 1 : img_url.rfind(".")]
|
||||
data_copy["img_url"] = img_url
|
||||
data_copy["img_p"] = img_p
|
||||
data_copy["is_r18"] = "R-18" in data["tags"]
|
||||
if not await Pixiv.exists(
|
||||
pid=data["pid"], img_url=img_url, img_p=img_p
|
||||
):
|
||||
img_data[pid] = {
|
||||
"pid": pid,
|
||||
"title": title,
|
||||
"width": width,
|
||||
"height": height,
|
||||
"view": view,
|
||||
"bookmarks": bookmarks,
|
||||
"img_urls": img_urls,
|
||||
"uid": uid,
|
||||
"author": author,
|
||||
"tags": tags,
|
||||
}
|
||||
data_copy["img_url"] = img_url
|
||||
await Pixiv.create(**data_copy)
|
||||
if data["pid"] not in tmp_pid:
|
||||
pid_count += 1
|
||||
tmp_pid.append(data["pid"])
|
||||
pic_count += 1
|
||||
logger.info(f'存储图片PID:{data["pid"]} IMG_P:{img_p}')
|
||||
else:
|
||||
continue
|
||||
for x in img_data.keys():
|
||||
data = img_data[x]
|
||||
for img_url in data["img_urls"]:
|
||||
img_p = img_url[img_url.rfind("_") + 1 : img_url.rfind(".")]
|
||||
try:
|
||||
if await Pixiv.add_image_data(
|
||||
data["pid"],
|
||||
data["title"],
|
||||
data["width"],
|
||||
data["height"],
|
||||
data["view"],
|
||||
data["bookmarks"],
|
||||
img_url,
|
||||
img_p,
|
||||
data["uid"],
|
||||
data["author"],
|
||||
",".join(data["tags"]),
|
||||
):
|
||||
if data["pid"] not in tmp_pid:
|
||||
pid_count += 1
|
||||
tmp_pid.append(data["pid"])
|
||||
pic_count += 1
|
||||
logger.info(f'存储图片PID:{data["pid"]} IMG_P:{img_p}')
|
||||
except UniqueViolationError:
|
||||
logger.warning(f'{data["pid"]} | {img_url} 已存在...')
|
||||
except Exception as e:
|
||||
logger.warning(f"PIX在线搜索图片错误,已再次调用 {type(e)}:{e}")
|
||||
await search_image(url, keyword, params, semaphore, page, black)
|
||||
logger.warning(f'{data["pid"]} | {img_url} 已存在...')
|
||||
# except Exception as e:
|
||||
# logger.warning(f"PIX在线搜索图片错误,已再次调用 {type(e)}:{e}")
|
||||
# await search_image(url, keyword, params, semaphore, page, black)
|
||||
return pid_count, pic_count
|
||||
|
||||
|
||||
@@ -206,7 +203,9 @@ async def get_image(img_url: str, user_id: int) -> Optional[str]:
|
||||
params = {"id": pid}
|
||||
for _ in range(3):
|
||||
try:
|
||||
response = await AsyncHttpx.get(f"{HIBIAPI}/api/pixiv/illust", params=params)
|
||||
response = await AsyncHttpx.get(
|
||||
f"{HIBIAPI}/api/pixiv/illust", params=params
|
||||
)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("illust"):
|
||||
@@ -215,22 +214,28 @@ async def get_image(img_url: str, user_id: int) -> Optional[str]:
|
||||
"original_image_url"
|
||||
]
|
||||
else:
|
||||
img_url = data["illust"]["meta_pages"][0][
|
||||
"image_urls"
|
||||
]["original"]
|
||||
img_url = data["illust"]["meta_pages"][0]["image_urls"][
|
||||
"original"
|
||||
]
|
||||
break
|
||||
except TimeoutError:
|
||||
pass
|
||||
old_img_url = img_url
|
||||
img_url = change_pixiv_image_links(
|
||||
img_url, Config.get_config("pix", "PIX_IMAGE_SIZE"), Config.get_config("pixiv", "PIXIV_NGINX_URL")
|
||||
img_url,
|
||||
Config.get_config("pix", "PIX_IMAGE_SIZE"),
|
||||
Config.get_config("pixiv", "PIXIV_NGINX_URL"),
|
||||
)
|
||||
old_img_url = change_pixiv_image_links(
|
||||
old_img_url, None, Config.get_config("pixiv", "PIXIV_NGINX_URL")
|
||||
)
|
||||
for _ in range(3):
|
||||
try:
|
||||
response = await AsyncHttpx.get(img_url, headers=headers, timeout=Config.get_config("pix", "TIMEOUT"),)
|
||||
response = await AsyncHttpx.get(
|
||||
img_url,
|
||||
headers=headers,
|
||||
timeout=Config.get_config("pix", "TIMEOUT"),
|
||||
)
|
||||
if response.status_code == 404:
|
||||
img_url = old_img_url
|
||||
continue
|
||||
@@ -238,7 +243,9 @@ 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"
|
||||
) as f:
|
||||
await f.write(response.content)
|
||||
change_img_md5(TEMP_PATH / f"pix_{user_id}_{img_url.split('/')[-1][:-4]}.jpg")
|
||||
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"
|
||||
except TimeoutError:
|
||||
logger.warning(f"PIX:{img_url} 图片下载超时...")
|
||||
@@ -264,7 +271,7 @@ async def uid_pid_exists(id_: str) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
async def get_keyword_num(keyword: str) -> "int, int, int, int, int":
|
||||
async def get_keyword_num(keyword: str) -> Tuple[int, int, int, int, int]:
|
||||
"""
|
||||
查看图片相关 tag 数量
|
||||
:param keyword: 关键词tag
|
||||
@@ -276,7 +283,7 @@ async def get_keyword_num(keyword: str) -> "int, int, int, int, int":
|
||||
return count, r18_count, count_, setu_count, r18_count_
|
||||
|
||||
|
||||
async def remove_image(pid: int, img_p: str) -> bool:
|
||||
async def remove_image(pid: int, img_p: Optional[str]):
|
||||
"""
|
||||
删除置顶图片
|
||||
:param pid: pid
|
||||
@@ -285,7 +292,10 @@ async def remove_image(pid: int, img_p: str) -> bool:
|
||||
if img_p:
|
||||
if "p" not in img_p:
|
||||
img_p = f"p{img_p}"
|
||||
return await Pixiv.remove_image_data(pid, img_p)
|
||||
if img_p:
|
||||
await Pixiv.filter(pid=pid, img_p=img_p).delete()
|
||||
else:
|
||||
await Pixiv.filter(pid=pid).delete()
|
||||
|
||||
|
||||
def gen_keyword_pic(
|
||||
@@ -392,6 +402,3 @@ def _check_black(img_urls: List[str], black: List[str]) -> bool:
|
||||
if b in img_url:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,79 +1,50 @@
|
||||
from typing import Optional, List, Tuple
|
||||
from services.db_context import db
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
from tortoise import fields
|
||||
from tortoise.contrib.postgres.functions import Random
|
||||
|
||||
from services.db_context import Model
|
||||
|
||||
|
||||
class OmegaPixivIllusts(db.Model):
|
||||
__tablename__ = "omega_pixiv_illusts"
|
||||
__table_args__ = {'extend_existing': True}
|
||||
class OmegaPixivIllusts(Model):
|
||||
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
pid = db.Column(db.BigInteger(), nullable=False)
|
||||
uid = db.Column(db.BigInteger(), nullable=False)
|
||||
title = db.Column(db.String(), nullable=False)
|
||||
uname = db.Column(db.String(), nullable=False)
|
||||
classified = db.Column(db.Integer(), nullable=False)
|
||||
nsfw_tag = db.Column(db.Integer(), nullable=False)
|
||||
width = db.Column(db.Integer(), nullable=False)
|
||||
height = db.Column(db.Integer(), nullable=False)
|
||||
tags = db.Column(db.String(), nullable=False)
|
||||
url = db.Column(db.String(), nullable=False)
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
pid = fields.BigIntField()
|
||||
"""pid"""
|
||||
uid = fields.BigIntField()
|
||||
"""uid"""
|
||||
title = fields.CharField(255)
|
||||
"""标题"""
|
||||
uname = fields.CharField(255)
|
||||
"""画师名称"""
|
||||
classified = fields.IntField()
|
||||
"""标记标签, 0=未标记, 1=已人工标记或从可信已标记来源获取"""
|
||||
nsfw_tag = fields.IntField()
|
||||
"""nsfw标签,-1=未标记, 0=safe, 1=setu. 2=r18"""
|
||||
width = fields.IntField()
|
||||
"""宽度"""
|
||||
height = fields.IntField()
|
||||
"""高度"""
|
||||
tags = fields.TextField()
|
||||
"""tags"""
|
||||
url = fields.CharField(255)
|
||||
"""pixiv url链接"""
|
||||
|
||||
_idx1 = db.Index("omega_pixiv_illusts_idx1", "pid", "url", unique=True)
|
||||
|
||||
@classmethod
|
||||
async def add_image_data(
|
||||
cls,
|
||||
pid: int,
|
||||
title: str,
|
||||
width: int,
|
||||
height: int,
|
||||
url: str,
|
||||
uid: int,
|
||||
uname: str,
|
||||
classified: int,
|
||||
nsfw_tag: int,
|
||||
tags: str,
|
||||
):
|
||||
"""
|
||||
说明:
|
||||
添加图片信息
|
||||
参数:
|
||||
:param pid: pid
|
||||
:param title: 标题
|
||||
:param width: 宽度
|
||||
:param height: 长度
|
||||
:param url: url链接
|
||||
:param uid: 作者uid
|
||||
:param uname: 作者名称
|
||||
:param classified: 标记标签, 0=未标记, 1=已人工标记或从可信已标记来源获取
|
||||
:param nsfw_tag: nsfw标签,-1=未标记, 0=safe, 1=setu. 2=r18
|
||||
:param tags: 相关tag
|
||||
"""
|
||||
if not await cls.check_exists(pid):
|
||||
await cls.create(
|
||||
pid=pid,
|
||||
title=title,
|
||||
width=width,
|
||||
height=height,
|
||||
url=url,
|
||||
uid=uid,
|
||||
uname=uname,
|
||||
classified=classified,
|
||||
nsfw_tag=nsfw_tag,
|
||||
tags=tags,
|
||||
)
|
||||
return True
|
||||
return False
|
||||
class Meta:
|
||||
table = "omega_pixiv_illusts"
|
||||
table_description = "omega图库数据表"
|
||||
unique_together = ("pid", "url")
|
||||
|
||||
@classmethod
|
||||
async def query_images(
|
||||
cls,
|
||||
keywords: Optional[List[str]] = None,
|
||||
uid: Optional[int] = None,
|
||||
pid: Optional[int] = None,
|
||||
nsfw_tag: Optional[int] = 0,
|
||||
num: int = 100
|
||||
) -> List[Optional["OmegaPixivIllusts"]]:
|
||||
cls,
|
||||
keywords: Optional[List[str]] = None,
|
||||
uid: Optional[int] = None,
|
||||
pid: Optional[int] = None,
|
||||
nsfw_tag: Optional[int] = 0,
|
||||
num: int = 100,
|
||||
) -> List["OmegaPixivIllusts"]:
|
||||
"""
|
||||
说明:
|
||||
查找符合条件的图片
|
||||
@@ -84,66 +55,38 @@ class OmegaPixivIllusts(db.Model):
|
||||
:param nsfw_tag: nsfw标签, 0=safe, 1=setu. 2=r18
|
||||
:param num: 获取图片数量
|
||||
"""
|
||||
if not num:
|
||||
return []
|
||||
query = cls
|
||||
if nsfw_tag is not None:
|
||||
query = cls.query.where(cls.nsfw_tag == nsfw_tag)
|
||||
else:
|
||||
query = cls.query
|
||||
query = cls.filter(nsfw_tag=nsfw_tag)
|
||||
if keywords:
|
||||
for keyword in keywords:
|
||||
query = query.where(cls.tags.contains(keyword))
|
||||
query = query.filter(tags__contains=keyword)
|
||||
elif uid:
|
||||
query = query.where(cls.uid == uid)
|
||||
query = query.filter(uid=uid)
|
||||
elif pid:
|
||||
query = query.where(cls.uid == pid)
|
||||
query = query.order_by(db.func.random()).limit(num)
|
||||
return await query.gino.all()
|
||||
query = query.filter(pid=pid)
|
||||
query = query.annotate(rand=Random()).limit(num)
|
||||
return await query.all() # type: ignore
|
||||
|
||||
@classmethod
|
||||
async def check_exists(cls, pid: int) -> bool:
|
||||
"""
|
||||
说明:
|
||||
检测pid是否已存在
|
||||
参数:
|
||||
:param pid: 图片PID
|
||||
"""
|
||||
query = await cls.query.where(cls.pid == pid).gino.all()
|
||||
return bool(query)
|
||||
|
||||
@classmethod
|
||||
async def get_keyword_num(cls, tags: List[str] = None) -> Tuple[int, int, int]:
|
||||
async def get_keyword_num(
|
||||
cls, tags: Optional[List[str]] = None
|
||||
) -> Tuple[int, int, int]:
|
||||
"""
|
||||
说明:
|
||||
获取相关关键词(keyword, tag)在图库中的数量
|
||||
参数:
|
||||
:param tags: 关键词/Tag
|
||||
"""
|
||||
setattr(OmegaPixivIllusts, 'count', db.func.count(cls.pid).label('count'))
|
||||
query = cls.select('count')
|
||||
query = cls
|
||||
if tags:
|
||||
for tag in tags:
|
||||
query = query.where(cls.tags.contains(tag))
|
||||
count = await query.where(cls.nsfw_tag == 0).gino.first()
|
||||
setu_count = await query.where(cls.nsfw_tag == 1).gino.first()
|
||||
r18_count = await query.where(cls.nsfw_tag == 2).gino.first()
|
||||
return count[0], setu_count[0], r18_count[0]
|
||||
|
||||
@classmethod
|
||||
async def get_all_pid(cls) -> List[int]:
|
||||
"""
|
||||
说明:
|
||||
获取所有图片PID
|
||||
"""
|
||||
data = await cls.select('pid').gino.all()
|
||||
return [x[0] for x in data]
|
||||
|
||||
# async def test(cls, nsfw_tag: int = 1):
|
||||
# if nsfw_tag is not None:
|
||||
# query = cls.query.where(cls.nsfw_tag == nsfw_tag)
|
||||
# else:
|
||||
# query = cls.query
|
||||
# query = query.where((cls.width - cls.height) < 50)
|
||||
# for x in await query.gino.all():
|
||||
# print(x.pid)
|
||||
|
||||
|
||||
|
||||
query = query.filter(tags__contains=tag)
|
||||
else:
|
||||
query = query.all()
|
||||
count = await query.filter(nsfw_tag=0).count()
|
||||
setu_count = await query.filter(nsfw_tag=1).count()
|
||||
r18_count = await query.filter(nsfw_tag=2).count()
|
||||
return count, setu_count, r18_count
|
||||
|
||||
@@ -1,105 +1,43 @@
|
||||
from typing import Optional, List
|
||||
from services.db_context import db
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
from tortoise import fields
|
||||
from tortoise.contrib.postgres.functions import Random
|
||||
|
||||
from services.db_context import Model
|
||||
|
||||
|
||||
class Pixiv(db.Model):
|
||||
__tablename__ = "pixiv"
|
||||
__table_args__ = {'extend_existing': True}
|
||||
class Pixiv(Model):
|
||||
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
pid = db.Column(db.BigInteger(), nullable=False)
|
||||
title = db.Column(db.String(), nullable=False)
|
||||
width = db.Column(db.Integer(), nullable=False)
|
||||
height = db.Column(db.Integer(), nullable=False)
|
||||
view = db.Column(db.Integer(), nullable=False)
|
||||
bookmarks = db.Column(db.Integer(), nullable=False)
|
||||
img_url = db.Column(db.String(), nullable=False)
|
||||
img_p = db.Column(db.String(), nullable=False)
|
||||
uid = db.Column(db.BigInteger(), nullable=False)
|
||||
author = db.Column(db.String(), nullable=False)
|
||||
is_r18 = db.Column(db.Boolean(), nullable=False)
|
||||
tags = db.Column(db.String(), nullable=False)
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
pid = fields.BigIntField()
|
||||
"""pid"""
|
||||
uid = fields.BigIntField()
|
||||
"""uid"""
|
||||
author = fields.CharField(255)
|
||||
"""作者"""
|
||||
title = fields.CharField(255)
|
||||
"""标题"""
|
||||
width = fields.IntField()
|
||||
"""宽度"""
|
||||
height = fields.IntField()
|
||||
"""高度"""
|
||||
view = fields.IntField()
|
||||
"""pixiv查看数"""
|
||||
bookmarks = fields.IntField()
|
||||
"""收藏数"""
|
||||
tags = fields.TextField()
|
||||
"""tags"""
|
||||
img_url = fields.CharField(255)
|
||||
"""pixiv url链接"""
|
||||
img_p = fields.CharField(255)
|
||||
"""图片pN"""
|
||||
is_r18 = fields.BooleanField()
|
||||
|
||||
_idx1 = db.Index("pixiv_idx1", "pid", "img_url", unique=True)
|
||||
|
||||
@classmethod
|
||||
async def add_image_data(
|
||||
cls,
|
||||
pid: int,
|
||||
title: str,
|
||||
width: int,
|
||||
height: int,
|
||||
view: int,
|
||||
bookmarks: int,
|
||||
img_url: str,
|
||||
img_p: str,
|
||||
uid: int,
|
||||
author: str,
|
||||
tags: str,
|
||||
):
|
||||
"""
|
||||
说明:
|
||||
添加图片信息
|
||||
参数:
|
||||
:param pid: pid
|
||||
:param title: 标题
|
||||
:param width: 宽度
|
||||
:param height: 长度
|
||||
:param view: 被查看次数
|
||||
:param bookmarks: 收藏数
|
||||
:param img_url: url链接
|
||||
:param img_p: 张数
|
||||
:param uid: 作者uid
|
||||
:param author: 作者名称
|
||||
:param tags: 相关tag
|
||||
"""
|
||||
if not await cls.check_exists(pid, img_p):
|
||||
await cls.create(
|
||||
pid=pid,
|
||||
title=title,
|
||||
width=width,
|
||||
height=height,
|
||||
view=view,
|
||||
bookmarks=bookmarks,
|
||||
img_url=img_url,
|
||||
img_p=img_p,
|
||||
uid=uid,
|
||||
author=author,
|
||||
is_r18=True if "R-18" in tags else False,
|
||||
tags=tags,
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def remove_image_data(cls, pid: int, img_p: str) -> bool:
|
||||
"""
|
||||
说明:
|
||||
删除图片数据
|
||||
参数:
|
||||
:param pid: 图片pid
|
||||
:param img_p: 图片pid的张数,如:p0,p1
|
||||
"""
|
||||
try:
|
||||
if img_p:
|
||||
await cls.delete.where(
|
||||
(cls.pid == pid) & (cls.img_p == img_p)
|
||||
).gino.status()
|
||||
else:
|
||||
await cls.delete.where(cls.pid == pid).gino.status()
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def get_all_pid(cls) -> List[int]:
|
||||
"""
|
||||
说明:
|
||||
获取所有PID
|
||||
"""
|
||||
query = await cls.query.select("pid").gino.first()
|
||||
pid = [x[0] for x in query]
|
||||
return list(set(pid))
|
||||
class Meta:
|
||||
table = "pixiv"
|
||||
table_description = "pix图库数据表"
|
||||
unique_together = ("pid", "img_url", "img_p")
|
||||
|
||||
# 0:非r18 1:r18 2:混合
|
||||
@classmethod
|
||||
@@ -109,7 +47,7 @@ class Pixiv(db.Model):
|
||||
uid: Optional[int] = None,
|
||||
pid: Optional[int] = None,
|
||||
r18: Optional[int] = 0,
|
||||
num: int = 100
|
||||
num: int = 100,
|
||||
) -> List[Optional["Pixiv"]]:
|
||||
"""
|
||||
说明:
|
||||
@@ -121,50 +59,37 @@ class Pixiv(db.Model):
|
||||
:param r18: 是否r18,0:非r18 1:r18 2:混合
|
||||
:param num: 查找图片的数量
|
||||
"""
|
||||
if not num:
|
||||
return []
|
||||
query = cls
|
||||
if r18 == 0:
|
||||
query = cls.query.where(cls.is_r18 == False)
|
||||
query = query.filter(is_r18=False)
|
||||
elif r18 == 1:
|
||||
query = cls.query.where(cls.is_r18 == True)
|
||||
else:
|
||||
query = cls.query
|
||||
query = query.filter(is_r18=True)
|
||||
if keywords:
|
||||
for keyword in keywords:
|
||||
query = query.where(cls.tags.contains(keyword))
|
||||
query = query.filter(tags__contains=keyword)
|
||||
elif uid:
|
||||
query = query.where(cls.uid == uid)
|
||||
query = query.filter(uid=uid)
|
||||
elif pid:
|
||||
query = query.where(cls.pid == pid)
|
||||
query = query.order_by(db.func.random()).limit(num)
|
||||
return await query.gino.all()
|
||||
query = query.filter(pid=pid)
|
||||
query = query.annotate(rand=Random()).limit(num)
|
||||
return await query.all() # type: ignore
|
||||
|
||||
@classmethod
|
||||
async def check_exists(cls, pid: int, img_p: str) -> bool:
|
||||
"""
|
||||
说明:
|
||||
检测pid是否已存在
|
||||
参数:
|
||||
:param pid: 图片PID
|
||||
:param img_p: 张数
|
||||
"""
|
||||
query = await cls.query.where(
|
||||
(cls.pid == pid) & (cls.img_p == img_p)
|
||||
).gino.all()
|
||||
return bool(query)
|
||||
|
||||
@classmethod
|
||||
async def get_keyword_num(cls, tags: List[str] = None) -> "int, int":
|
||||
async def get_keyword_num(cls, tags: Optional[List[str]] = None) -> Tuple[int, int]:
|
||||
"""
|
||||
说明:
|
||||
获取相关关键词(keyword, tag)在图库中的数量
|
||||
参数:
|
||||
:param tags: 关键词/Tag
|
||||
"""
|
||||
setattr(Pixiv, 'count', db.func.count(cls.pid).label('count'))
|
||||
query = cls.select('count')
|
||||
query = cls
|
||||
if tags:
|
||||
for tag in tags:
|
||||
query = query.where(cls.tags.contains(tag))
|
||||
count = await query.where(cls.is_r18 == False).gino.first()
|
||||
r18_count = await query.where(cls.is_r18 == True).gino.first()
|
||||
return count[0], r18_count[0]
|
||||
|
||||
query = query.filter(tags__contains=tag)
|
||||
else:
|
||||
query = query.all()
|
||||
count = await query.filter(is_r18=False).count()
|
||||
r18_count = await query.filter(is_r18=True).count()
|
||||
return count, r18_count
|
||||
|
||||
@@ -1,101 +1,42 @@
|
||||
from services.db_context import db
|
||||
from typing import Set, List
|
||||
from typing import List, Set, Tuple
|
||||
|
||||
from tortoise import fields
|
||||
|
||||
from services.db_context import Model
|
||||
|
||||
|
||||
class PixivKeywordUser(db.Model):
|
||||
class PixivKeywordUser(Model):
|
||||
__tablename__ = "pixiv_keyword_users"
|
||||
__table_args__ = {'extend_existing': True}
|
||||
__table_args__ = {"extend_existing": True}
|
||||
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||
group_id = db.Column(db.BigInteger(), nullable=False)
|
||||
keyword = db.Column(db.String(), nullable=False)
|
||||
is_pass = db.Column(db.Boolean(), default=False)
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
"""用户id"""
|
||||
group_id = fields.BigIntField()
|
||||
"""群聊id"""
|
||||
keyword = fields.CharField(255, unique=True)
|
||||
"""关键词"""
|
||||
is_pass = fields.BooleanField()
|
||||
"""是否通过"""
|
||||
|
||||
_idx1 = db.Index("pixiv_keyword_users_idx1", "keyword", unique=True)
|
||||
class Meta:
|
||||
table = "pixiv_keyword_users"
|
||||
table_description = "pixiv关键词数据表"
|
||||
|
||||
@classmethod
|
||||
async def add_keyword(
|
||||
cls, user_qq: int, group_id: int, keyword: str, superusers: Set[str]
|
||||
) -> bool:
|
||||
"""
|
||||
说明:
|
||||
添加搜图的关键词
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 群号
|
||||
:param keyword: 关键词
|
||||
:param superusers: 是否为超级用户
|
||||
"""
|
||||
is_pass = True if str(user_qq) in superusers else False
|
||||
if not await cls._check_keyword_exists(keyword):
|
||||
await cls.create(
|
||||
user_qq=user_qq, group_id=group_id, keyword=keyword, is_pass=is_pass
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def delete_keyword(cls, keyword: str) -> bool:
|
||||
"""
|
||||
说明:
|
||||
删除关键词
|
||||
参数:
|
||||
:param keyword: 关键词
|
||||
"""
|
||||
if await cls._check_keyword_exists(keyword):
|
||||
query = cls.query.where(cls.keyword == keyword).with_for_update()
|
||||
query = await query.gino.first()
|
||||
await query.delete()
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def set_keyword_pass(cls, keyword: str, is_pass: bool) -> "int, int":
|
||||
"""
|
||||
说明:
|
||||
通过或禁用关键词
|
||||
参数:
|
||||
:param keyword: 关键词
|
||||
:param is_pass: 通过状态
|
||||
"""
|
||||
if await cls._check_keyword_exists(keyword):
|
||||
query = cls.query.where(cls.keyword == keyword).with_for_update()
|
||||
query = await query.gino.first()
|
||||
await query.update(
|
||||
is_pass=is_pass,
|
||||
).apply()
|
||||
return query.user_qq, query.group_id
|
||||
return 0, 0
|
||||
|
||||
@classmethod
|
||||
async def get_all_user_dict(cls) -> dict:
|
||||
"""
|
||||
说明:
|
||||
获取关键词数据库各个用户贡献的关键词字典
|
||||
"""
|
||||
tmp = {}
|
||||
query = await cls.query.gino.all()
|
||||
for user in query:
|
||||
if not tmp.get(user.user_qq):
|
||||
tmp[user.user_qq] = {"keyword": []}
|
||||
tmp[user.user_qq]["keyword"].append(user.keyword)
|
||||
return tmp
|
||||
|
||||
@classmethod
|
||||
async def get_current_keyword(cls) -> "List[str], List[str]":
|
||||
async def get_current_keyword(cls) -> Tuple[List[str], List[str]]:
|
||||
"""
|
||||
说明:
|
||||
获取当前通过与未通过的关键词
|
||||
"""
|
||||
pass_keyword = []
|
||||
not_pass_keyword = []
|
||||
query = await cls.query.gino.all()
|
||||
for user in query:
|
||||
if user.is_pass:
|
||||
pass_keyword.append(user.keyword)
|
||||
for data in await cls.all().values_list("keyword", "is_pass"):
|
||||
if data[1]:
|
||||
pass_keyword.append(data[0])
|
||||
else:
|
||||
not_pass_keyword.append(user.keyword)
|
||||
not_pass_keyword.append(data[0])
|
||||
return pass_keyword, not_pass_keyword
|
||||
|
||||
@classmethod
|
||||
@@ -105,23 +46,9 @@ class PixivKeywordUser(db.Model):
|
||||
获取黑名单PID
|
||||
"""
|
||||
black_pid = []
|
||||
query = await cls.query.where(cls.user_qq == 114514).gino.all()
|
||||
for image in query:
|
||||
black_pid.append(image.keyword[6:])
|
||||
keyword_list = await cls.filter(user_qq=114514).values_list(
|
||||
"keyword", flat=True
|
||||
)
|
||||
for image in keyword_list:
|
||||
black_pid.append(image[6:])
|
||||
return black_pid
|
||||
|
||||
@classmethod
|
||||
async def _check_keyword_exists(cls, keyword: str) -> bool:
|
||||
"""
|
||||
说明:
|
||||
检测关键词是否已存在
|
||||
参数:
|
||||
:param keyword: 关键词
|
||||
"""
|
||||
current_keyword = []
|
||||
query = await cls.query.gino.all()
|
||||
for user in query:
|
||||
current_keyword.append(user.keyword)
|
||||
if keyword in current_keyword:
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
from nonebot import on_command
|
||||
from utils.utils import is_number
|
||||
from services.log import logger
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GroupMessageEvent, Message
|
||||
from nonebot.params import CommandArg, Command
|
||||
from typing import Tuple
|
||||
from ._data_source import uid_pid_exists
|
||||
from ._model.pixiv_keyword_user import PixivKeywordUser
|
||||
from ._model.pixiv import Pixiv
|
||||
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message, MessageEvent
|
||||
from nonebot.params import Command, CommandArg
|
||||
from nonebot.permission import SUPERUSER
|
||||
|
||||
from services.log import logger
|
||||
from utils.utils import is_number
|
||||
|
||||
from ._data_source import uid_pid_exists
|
||||
from ._model.pixiv import Pixiv
|
||||
from ._model.pixiv_keyword_user import PixivKeywordUser
|
||||
|
||||
__zx_plugin_name__ = "PIX关键词/UID/PID添加管理 [Superuser]"
|
||||
__plugin_usage__ = """
|
||||
usage:
|
||||
@@ -46,9 +49,16 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
group_id = event.group_id
|
||||
if msg:
|
||||
if await PixivKeywordUser.add_keyword(
|
||||
event.user_id, group_id, msg, bot.config.superusers
|
||||
):
|
||||
# if await PixivKeywordUser.add_keyword(
|
||||
# event.user_id, group_id, msg, bot.config.superusers
|
||||
# ):
|
||||
if not await PixivKeywordUser.exists(keyword=msg):
|
||||
await PixivKeywordUser.create(
|
||||
user_qq=event.user_id,
|
||||
group_id=group_id,
|
||||
keyword=msg,
|
||||
is_pass=str(event.user_id) in bot.config.superusers,
|
||||
)
|
||||
await add_keyword.send(
|
||||
f"已成功添加pixiv搜图关键词:{msg},请等待管理员通过该关键词!", at_sender=True
|
||||
)
|
||||
@@ -63,7 +73,12 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
|
||||
|
||||
@add_uid_pid.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
|
||||
async def _(
|
||||
bot: Bot,
|
||||
event: MessageEvent,
|
||||
cmd: Tuple[str, ...] = Command(),
|
||||
arg: Message = CommandArg(),
|
||||
):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
exists_flag = True
|
||||
if msg.find("-f") != -1 and str(event.user_id) in bot.config.superusers:
|
||||
@@ -77,16 +92,23 @@ async def _(bot: Bot, event: MessageEvent, cmd: Tuple[str, ...] = Command(), arg
|
||||
msg = f"uid:{msg}"
|
||||
else:
|
||||
msg = f"pid:{msg}"
|
||||
if await Pixiv.check_exists(int(msg[4:]), "p0"):
|
||||
if await Pixiv.get_or_none(pid=int(msg[4:]), img_p="p0"):
|
||||
await add_uid_pid.finish(f"该PID:{msg[4:]}已存在...", at_sender=True)
|
||||
if not await uid_pid_exists(msg) and exists_flag:
|
||||
await add_uid_pid.finish("画师或作品不存在或搜索正在CD,请稍等...", at_sender=True)
|
||||
group_id = -1
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
group_id = event.group_id
|
||||
if await PixivKeywordUser.add_keyword(
|
||||
event.user_id, group_id, msg, bot.config.superusers
|
||||
):
|
||||
# if await PixivKeywordUser.add_keyword(
|
||||
# event.user_id, group_id, msg, bot.config.superusers
|
||||
# ):
|
||||
if not await PixivKeywordUser.exists(keyword=msg):
|
||||
await PixivKeywordUser.create(
|
||||
user_qq=event.user_id,
|
||||
group_id=group_id,
|
||||
keyword=msg,
|
||||
is_pass=str(event.user_id) in bot.config.superusers,
|
||||
)
|
||||
await add_uid_pid.send(
|
||||
f"已成功添加pixiv搜图UID/PID:{msg[4:]},请等待管理员通过!", at_sender=True
|
||||
)
|
||||
@@ -106,12 +128,21 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
pid = pid[: pid.find("p")]
|
||||
if not is_number(pid):
|
||||
await add_black_pid.finish("PID必须全部是数字!", at_sender=True)
|
||||
if await PixivKeywordUser.add_keyword(
|
||||
114514,
|
||||
114514,
|
||||
f"black:{pid}{f'_p{img_p}' if img_p else ''}",
|
||||
bot.config.superusers,
|
||||
# if await PixivKeywordUser.add_keyword(
|
||||
# 114514,
|
||||
# 114514,
|
||||
# f"black:{pid}{f'_p{img_p}' if img_p else ''}",
|
||||
# bot.config.superusers,
|
||||
# ):
|
||||
if not await PixivKeywordUser.exists(
|
||||
keyword=f"black:{pid}{f'_p{img_p}' if img_p else ''}"
|
||||
):
|
||||
await PixivKeywordUser.create(
|
||||
user_qq=114514,
|
||||
group_id=114514,
|
||||
keyword=f"black:{pid}{f'_p{img_p}' if img_p else ''}",
|
||||
is_pass=str(event.user_id) in bot.config.superusers,
|
||||
)
|
||||
await add_black_pid.send(f"已添加PID:{pid} 至黑名单中...")
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
from nonebot import on_command
|
||||
from utils.utils import is_number
|
||||
from utils.message_builder import at
|
||||
from services.log import logger
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GroupMessageEvent, Message
|
||||
from nonebot.params import CommandArg, Command
|
||||
from nonebot.permission import SUPERUSER
|
||||
from ._data_source import remove_image
|
||||
from ._model.pixiv_keyword_user import PixivKeywordUser
|
||||
from ._model.pixiv import Pixiv
|
||||
from typing import Tuple
|
||||
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message, MessageEvent
|
||||
from nonebot.params import Command, CommandArg
|
||||
from nonebot.permission import SUPERUSER
|
||||
|
||||
from services.log import logger
|
||||
from utils.message_builder import at
|
||||
from utils.utils import is_number
|
||||
|
||||
from ._data_source import remove_image
|
||||
from ._model.pixiv import Pixiv
|
||||
from ._model.pixiv_keyword_user import PixivKeywordUser
|
||||
|
||||
__zx_plugin_name__ = "PIX关键词/UID/PID删除管理 [Superuser]"
|
||||
__plugin_usage__ = """
|
||||
@@ -60,7 +62,8 @@ async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
msg = f"uid:{msg}"
|
||||
if msg.lower().startswith("pid"):
|
||||
msg = "pid:" + msg.replace("pid", "").replace(":", "")
|
||||
if await PixivKeywordUser.delete_keyword(msg):
|
||||
if data := await PixivKeywordUser.get_or_none(keyword=msg):
|
||||
await data.delete()
|
||||
await del_keyword.send(f"删除搜图关键词/UID:{msg} 成功...")
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
@@ -97,22 +100,31 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
if await remove_image(int(pid), img_p):
|
||||
msg += f'{pid}{f"_p{img_p}" if img_p else ""},'
|
||||
if flag:
|
||||
if await PixivKeywordUser.add_keyword(
|
||||
114514,
|
||||
114514,
|
||||
f"black:{pid}{f'_p{img_p}' if img_p else ''}",
|
||||
bot.config.superusers,
|
||||
# if await PixivKeywordUser.add_keyword(
|
||||
# 114514,
|
||||
# 114514,
|
||||
# f"black:{pid}{f'_p{img_p}' if img_p else ''}",
|
||||
# bot.config.superusers,
|
||||
# ):
|
||||
if await PixivKeywordUser.exists(
|
||||
keyword=f"black:{pid}{f'_p{img_p}' if img_p else ''}"
|
||||
):
|
||||
await PixivKeywordUser.create(
|
||||
user_qq=114514,
|
||||
group_id=114514,
|
||||
keyword=f"black:{pid}{f'_p{img_p}' if img_p else ''}",
|
||||
is_pass=False,
|
||||
)
|
||||
black_pid += f'{pid}{f"_p{img_p}" if img_p else ""},'
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
f" 删除了PIX图片 PID:{pid}{f'_p{img_p}' if img_p else ''}"
|
||||
)
|
||||
else:
|
||||
await del_pic.send(
|
||||
f"PIX:删除pid:{pid}{f'_p{img_p}' if img_p else ''} 失败.."
|
||||
)
|
||||
# else:
|
||||
# await del_pic.send(
|
||||
# f"PIX:删除pid:{pid}{f'_p{img_p}' if img_p else ''} 失败.."
|
||||
# )
|
||||
else:
|
||||
await del_pic.send(
|
||||
f"PIX:图片pix:{pid}{f'_p{img_p}' if img_p else ''} 不存在...无法删除.."
|
||||
@@ -127,7 +139,12 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
|
||||
|
||||
@pass_keyword.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
|
||||
async def _(
|
||||
bot: Bot,
|
||||
event: MessageEvent,
|
||||
cmd: Tuple[str, ...] = Command(),
|
||||
arg: Message = CommandArg(),
|
||||
):
|
||||
tmp = {"group": {}, "private": {}}
|
||||
msg = arg.extract_plain_text().strip()
|
||||
if not msg:
|
||||
@@ -145,7 +162,13 @@ async def _(bot: Bot, event: MessageEvent, cmd: Tuple[str, ...] = Command(), arg
|
||||
if not is_number(x[4:]):
|
||||
await pass_keyword.send(f"UID/PID:{x} 非全数字,跳过该关键词...")
|
||||
continue
|
||||
user_id, group_id = await PixivKeywordUser.set_keyword_pass(x, flag)
|
||||
data = await PixivKeywordUser.get_or_none(keyword=x)
|
||||
user_id = 0
|
||||
group_id = 0
|
||||
if data:
|
||||
data.is_pass = flag
|
||||
await data.save(update_fields=["is_pass"])
|
||||
user_id, group_id = data.user_qq, data.group_id
|
||||
if not user_id:
|
||||
await pass_keyword.send(f"未找到关键词/UID:{x},请检查关键词/UID是否存在...")
|
||||
continue
|
||||
@@ -163,7 +186,7 @@ async def _(bot: Bot, event: MessageEvent, cmd: Tuple[str, ...] = Command(), arg
|
||||
else:
|
||||
tmp["group"][group_id][user_id]["keyword"].append(x)
|
||||
msg = " ".join(msg)
|
||||
await pass_keyword.send(f'已成功{cmd[0][:2]}搜图关键词:{msg}....')
|
||||
await pass_keyword.send(f"已成功{cmd[0][:2]}搜图关键词:{msg}....")
|
||||
for user in tmp["private"]:
|
||||
x = ",".join(tmp["private"][user]["keyword"])
|
||||
await bot.send_private_msg(
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
from nonebot import on_command
|
||||
from utils.message_builder import image
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, Message
|
||||
from ._data_source import gen_keyword_pic, get_keyword_num
|
||||
from ._model.pixiv_keyword_user import PixivKeywordUser
|
||||
from nonebot.params import CommandArg
|
||||
import asyncio
|
||||
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import Bot, Message, MessageEvent
|
||||
from nonebot.params import CommandArg
|
||||
|
||||
from utils.message_builder import image
|
||||
|
||||
from ._data_source import gen_keyword_pic, get_keyword_num
|
||||
from ._model.pixiv_keyword_user import PixivKeywordUser
|
||||
|
||||
__zx_plugin_name__ = "查看pix图库"
|
||||
__plugin_usage__ = """
|
||||
@@ -35,12 +37,12 @@ show_pix = on_command("查看pix图库", priority=1, block=True)
|
||||
|
||||
@my_keyword.handle()
|
||||
async def _(event: MessageEvent):
|
||||
data = await PixivKeywordUser.get_all_user_dict()
|
||||
if data.get(event.user_id) is None or not data[event.user_id]["keyword"]:
|
||||
await my_keyword.finish("您目前没有提供任何Pixiv搜图关键字...", at_sender=True)
|
||||
await my_keyword.send(
|
||||
f"您目前提供的如下关键字:\n\t" + ",".join(data[event.user_id]["keyword"])
|
||||
data = await PixivKeywordUser.filter(user_qq=event.user_id).values_list(
|
||||
"keyword", flat=True
|
||||
)
|
||||
if not data:
|
||||
await my_keyword.finish("您目前没有提供任何Pixiv搜图关键字...", at_sender=True)
|
||||
await my_keyword.send(f"您目前提供的如下关键字:\n\t" + ",".join(data))
|
||||
|
||||
|
||||
@show_keyword.handle()
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
import re
|
||||
|
||||
from nonebot import on_command
|
||||
from utils.utils import is_number
|
||||
from nonebot.permission import SUPERUSER
|
||||
from ._data_source import start_update_image_url
|
||||
from ._model.pixiv_keyword_user import PixivKeywordUser
|
||||
from ._model.omega_pixiv_illusts import OmegaPixivIllusts
|
||||
from ._model.pixiv import Pixiv
|
||||
from nonebot.adapters.onebot.v11 import Message
|
||||
from nonebot.params import CommandArg
|
||||
import time
|
||||
from services.log import logger
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
import asyncio
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import Message
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.permission import SUPERUSER
|
||||
|
||||
from services.log import logger
|
||||
from utils.utils import is_number
|
||||
|
||||
from ._data_source import start_update_image_url
|
||||
from ._model.omega_pixiv_illusts import OmegaPixivIllusts
|
||||
from ._model.pixiv import Pixiv
|
||||
from ._model.pixiv_keyword_user import PixivKeywordUser
|
||||
|
||||
__zx_plugin_name__ = "pix检查更新 [Superuser]"
|
||||
__plugin_usage__ = """
|
||||
@@ -146,11 +147,11 @@ async def _(arg: Message = CommandArg()):
|
||||
async def _():
|
||||
async def _tasks(line: str, all_pid: List[int], length: int, index: int):
|
||||
data = line.split("VALUES", maxsplit=1)[-1].strip()[1:-2]
|
||||
num_list = re.findall(r'(\d+)', data)
|
||||
num_list = re.findall(r"(\d+)", data)
|
||||
pid = int(num_list[1])
|
||||
uid = int(num_list[2])
|
||||
id_ = 3
|
||||
while num_list[id_] not in ['0', '1']:
|
||||
while num_list[id_] not in ["0", "1"]:
|
||||
id_ += 1
|
||||
classified = int(num_list[id_])
|
||||
nsfw_tag = int(num_list[id_ + 1])
|
||||
@@ -164,23 +165,25 @@ async def _():
|
||||
if pid in all_pid:
|
||||
logger.info(f"添加OmegaPixivIllusts图库数据已存在 ---> pid:{pid}")
|
||||
return
|
||||
if await OmegaPixivIllusts.add_image_data(
|
||||
pid=pid,
|
||||
title=title,
|
||||
width=width,
|
||||
height=height,
|
||||
url=url,
|
||||
uid=uid,
|
||||
nsfw_tag=nsfw_tag,
|
||||
tags=tags,
|
||||
uname=uname,
|
||||
classified=classified
|
||||
):
|
||||
_, is_create = await OmegaPixivIllusts.get_or_create(
|
||||
pid=pid,
|
||||
title=title,
|
||||
width=width,
|
||||
height=height,
|
||||
url=url,
|
||||
uid=uid,
|
||||
nsfw_tag=nsfw_tag,
|
||||
tags=tags,
|
||||
uname=uname,
|
||||
classified=classified,
|
||||
)
|
||||
if is_create:
|
||||
logger.info(
|
||||
f"成功添加OmegaPixivIllusts图库数据 pid:{pid} 本次预计存储 {length} 张,已更新第 {index} 张"
|
||||
)
|
||||
else:
|
||||
logger.info(f"添加OmegaPixivIllusts图库数据已存在 ---> pid:{pid}")
|
||||
|
||||
omega_pixiv_illusts = None
|
||||
for file in os.listdir("."):
|
||||
if "omega_pixiv_artwork" in file and ".sql" in file:
|
||||
@@ -190,13 +193,13 @@ async def _():
|
||||
lines = f.readlines()
|
||||
tasks = []
|
||||
length = len([x for x in lines if "INSERT INTO" in x.upper()])
|
||||
all_pid = await OmegaPixivIllusts.get_all_pid()
|
||||
all_pid = await OmegaPixivIllusts.all().values_list("pid", flat=True)
|
||||
index = 0
|
||||
logger.info("检测到OmegaPixivIllusts数据库,准备开始更新....")
|
||||
for line in lines:
|
||||
if "INSERT INTO" in line.upper():
|
||||
index += 1
|
||||
logger.info(f'line: {line} 加入更新计划')
|
||||
logger.info(f"line: {line} 加入更新计划")
|
||||
tasks.append(
|
||||
asyncio.ensure_future(_tasks(line, all_pid, length, index))
|
||||
)
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
from configs.path_config import IMAGE_PATH
|
||||
import platform
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from configs.config import Config
|
||||
from configs.path_config import IMAGE_PATH, TEMP_PATH
|
||||
from services.log import logger
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.message_builder import image
|
||||
from utils.utils import change_img_md5
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from configs.config import Config
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from typing import Optional
|
||||
from services.log import logger
|
||||
from pathlib import Path
|
||||
import platform
|
||||
|
||||
# if platform.system() == "Windows":
|
||||
# import asyncio
|
||||
@@ -133,9 +134,9 @@ async def download_pixiv_imgs(
|
||||
)
|
||||
try:
|
||||
file = (
|
||||
f"{IMAGE_PATH}/temp/{user_id}_{forward_msg_index}_{index}_pixiv.jpg"
|
||||
TEMP_PATH / f"{user_id}_{forward_msg_index}_{index}_pixiv.jpg"
|
||||
if forward_msg_index is not None
|
||||
else f"{IMAGE_PATH}/temp/{user_id}_{index}_pixiv.jpg"
|
||||
else TEMP_PATH / f"{user_id}_{index}_pixiv.jpg"
|
||||
)
|
||||
file = Path(file)
|
||||
try:
|
||||
@@ -147,11 +148,11 @@ async def download_pixiv_imgs(
|
||||
change_img_md5(file)
|
||||
if forward_msg_index is not None:
|
||||
result += image(
|
||||
f"{user_id}_{forward_msg_index}_{index}_pixiv.jpg",
|
||||
"temp",
|
||||
TEMP_PATH
|
||||
/ f"{user_id}_{forward_msg_index}_{index}_pixiv.jpg",
|
||||
)
|
||||
else:
|
||||
result += image(f"{user_id}_{index}_pixiv.jpg", "temp")
|
||||
result += image(TEMP_PATH / f"{user_id}_{index}_pixiv.jpg")
|
||||
index += 1
|
||||
except OSError:
|
||||
if file.exists():
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import os
|
||||
import random
|
||||
|
||||
from nonebot import on_notice
|
||||
from nonebot.adapters.onebot.v11 import PokeNotifyEvent
|
||||
from configs.path_config import RECORD_PATH, IMAGE_PATH
|
||||
from utils.message_builder import record, image, poke
|
||||
from services.log import logger
|
||||
import random
|
||||
from utils.utils import CountLimiter
|
||||
|
||||
from configs.path_config import IMAGE_PATH, RECORD_PATH
|
||||
from models.ban_user import BanUser
|
||||
import os
|
||||
from services.log import logger
|
||||
from utils.message_builder import image, poke, record
|
||||
from utils.utils import CountLimiter
|
||||
|
||||
__zx_plugin_name__ = "戳一戳"
|
||||
|
||||
@@ -64,13 +66,17 @@ async def _poke_event(event: PokeNotifyEvent):
|
||||
rand = random.random()
|
||||
path = random.choice(["luoli", "meitu"])
|
||||
if rand <= 0.3 and len(os.listdir(IMAGE_PATH / "image_management" / path)) > 0:
|
||||
index = random.randint(0, len(os.listdir(IMAGE_PATH / "image_management" / path)) - 1)
|
||||
result = f"id:{index}" + image(f"{index}.jpg", "image_management/" + path)
|
||||
index = random.randint(
|
||||
0, len(os.listdir(IMAGE_PATH / "image_management" / path)) - 1
|
||||
)
|
||||
result = f"id:{index}" + image(
|
||||
IMAGE_PATH / "image_management" / path / f"{index}.jpg"
|
||||
)
|
||||
await poke_.send(result)
|
||||
logger.info(f"USER {event.user_id} 戳了戳我 回复: {result} {result}")
|
||||
elif 0.3 < rand < 0.6:
|
||||
voice = random.choice(os.listdir(RECORD_PATH / "dinggong"))
|
||||
result = record(voice, "dinggong")
|
||||
result = record(RECORD_PATH / "dinggong" / voice)
|
||||
await poke_.send(result)
|
||||
await poke_.send(voice.split("_")[1])
|
||||
logger.info(
|
||||
|
||||
+30
-20
@@ -1,20 +1,22 @@
|
||||
import asyncio
|
||||
import random
|
||||
import time
|
||||
from typing import Tuple
|
||||
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import GROUP, Bot, GroupMessageEvent, Message
|
||||
from nonebot.params import ArgStr, Command, CommandArg
|
||||
from nonebot.typing import T_State
|
||||
from utils.utils import is_number, get_message_at
|
||||
from nonebot.params import CommandArg, Command, ArgStr
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from utils.message_builder import at, image
|
||||
from .model import RussianUser
|
||||
from models.bag_user import BagUser
|
||||
from services.log import logger
|
||||
from .data_source import rank
|
||||
from configs.config import NICKNAME, Config
|
||||
from typing import Tuple
|
||||
import random
|
||||
import asyncio
|
||||
import time
|
||||
|
||||
from configs.config import NICKNAME, Config
|
||||
from models.bag_user import BagUser
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from services.log import logger
|
||||
from utils.message_builder import at, image
|
||||
from utils.utils import get_message_at, is_number
|
||||
|
||||
from .data_source import rank
|
||||
from .model import RussianUser
|
||||
|
||||
__zx_plugin_name__ = "俄罗斯轮盘"
|
||||
__plugin_usage__ = """
|
||||
@@ -156,7 +158,9 @@ async def _(event: GroupMessageEvent):
|
||||
await accept.finish("又不是找你决斗,你拒绝什么啊!气!", at_sender=True)
|
||||
if rs_player[event.group_id]["at"] == event.user_id:
|
||||
at_player_name = (
|
||||
await GroupInfoUser.get_member_info(event.user_id, event.group_id)
|
||||
await GroupInfoUser.get_or_none(
|
||||
user_qq=event.user_id, group_id=event.group_id
|
||||
)
|
||||
).user_name
|
||||
await accept.send(
|
||||
Message(f"{at(rs_player[event.group_id][1])}\n" f"{at_player_name}拒绝了你的对决!")
|
||||
@@ -291,7 +295,7 @@ async def _(
|
||||
at_ = at_[0]
|
||||
try:
|
||||
at_player_name = (
|
||||
await GroupInfoUser.get_member_info(at_, event.group_id)
|
||||
await GroupInfoUser.get_or_none(user_qq=at_, group_id=event.group_id)
|
||||
).user_name
|
||||
except AttributeError:
|
||||
at_player_name = at(at_)
|
||||
@@ -359,14 +363,14 @@ async def _(bot: Bot, event: GroupMessageEvent):
|
||||
[
|
||||
f"不要打扰 {player1_name} 和 {player2_name} 的决斗啊!",
|
||||
f"给我好好做好一个观众!不然{NICKNAME}就要生气了",
|
||||
f"不要捣乱啊baka{(await GroupInfoUser.get_member_info(event.user_id, event.group_id)).user_name}!",
|
||||
f"不要捣乱啊baka{(await GroupInfoUser.get_or_none(user_qq=event.user_id, group_id=event.group_id)).user_name}!",
|
||||
]
|
||||
),
|
||||
at_sender=True,
|
||||
)
|
||||
await shot.finish(
|
||||
f"你的左轮不是连发的!该 "
|
||||
f'{(await GroupInfoUser.get_member_info(int(rs_player[event.group_id]["next"]), event.group_id)).user_name} 开枪了'
|
||||
f'{(await GroupInfoUser.get_or_none(user_qq=int(rs_player[event.group_id]["next"]), group_id=event.group_id)).user_name} 开枪了'
|
||||
)
|
||||
if rs_player[event.group_id]["bullet"][rs_player[event.group_id]["index"]] != 1:
|
||||
await shot.send(
|
||||
@@ -440,8 +444,12 @@ async def end_game(bot: Bot, event: GroupMessageEvent):
|
||||
await RussianUser.money(lose_user_id, event.group_id, "lose", money)
|
||||
await BagUser.add_gold(win_user_id, event.group_id, money - fee)
|
||||
await BagUser.spend_gold(lose_user_id, event.group_id, money)
|
||||
win_user = await RussianUser.ensure(win_user_id, event.group_id)
|
||||
lose_user = await RussianUser.ensure(lose_user_id, event.group_id)
|
||||
win_user, _ = await RussianUser.get_or_create(
|
||||
user_qq=win_user_id, group_id=event.group_id
|
||||
)
|
||||
lose_user, _ = await RussianUser.get_or_create(
|
||||
user_qq=lose_user_id, group_id=event.group_id
|
||||
)
|
||||
bullet_str = ""
|
||||
for x in rs_player[event.group_id]["bullet"]:
|
||||
bullet_str += "__ " if x == 0 else "| "
|
||||
@@ -467,7 +475,9 @@ async def end_game(bot: Bot, event: GroupMessageEvent):
|
||||
|
||||
@record.handle()
|
||||
async def _(event: GroupMessageEvent):
|
||||
user = await RussianUser.ensure(event.user_id, event.group_id)
|
||||
user, _ = await RussianUser.get_or_create(
|
||||
user_qq=event.user_id, group_id=event.group_id
|
||||
)
|
||||
await record.send(
|
||||
f"俄罗斯轮盘\n"
|
||||
f"总胜利场次:{user.win_count}\n"
|
||||
|
||||
@@ -1,42 +1,33 @@
|
||||
from .model import RussianUser
|
||||
from typing import Optional
|
||||
|
||||
from utils.data_utils import init_rank
|
||||
from utils.image_utils import BuildMat
|
||||
|
||||
from .model import RussianUser
|
||||
|
||||
|
||||
async def rank(group_id: int, itype: str, num: int) -> Optional[BuildMat]:
|
||||
all_users = await RussianUser.get_all_user(group_id)
|
||||
all_users = await RussianUser.filter(group_id=group_id).all()
|
||||
all_user_id = [user.user_qq for user in all_users]
|
||||
if itype == 'win_rank':
|
||||
rank_name = '胜场排行榜'
|
||||
if itype == "win_rank":
|
||||
rank_name = "胜场排行榜"
|
||||
all_user_data = [user.win_count for user in all_users]
|
||||
elif itype == 'lose_rank':
|
||||
rank_name = '败场排行榜'
|
||||
elif itype == "lose_rank":
|
||||
rank_name = "败场排行榜"
|
||||
all_user_data = [user.fail_count for user in all_users]
|
||||
elif itype == 'make_money':
|
||||
rank_name = '赢取金币排行榜'
|
||||
elif itype == "make_money":
|
||||
rank_name = "赢取金币排行榜"
|
||||
all_user_data = [user.make_money for user in all_users]
|
||||
elif itype == 'spend_money':
|
||||
rank_name = '输掉金币排行榜'
|
||||
elif itype == "spend_money":
|
||||
rank_name = "输掉金币排行榜"
|
||||
all_user_data = [user.lose_money for user in all_users]
|
||||
elif itype == 'max_winning_streak':
|
||||
rank_name = '最高连胜排行榜'
|
||||
elif itype == "max_winning_streak":
|
||||
rank_name = "最高连胜排行榜"
|
||||
all_user_data = [user.max_winning_streak for user in all_users]
|
||||
else:
|
||||
rank_name = '最高连败排行榜'
|
||||
rank_name = "最高连败排行榜"
|
||||
all_user_data = [user.max_losing_streak for user in all_users]
|
||||
rst = None
|
||||
if all_users:
|
||||
rst = await init_rank(rank_name, all_user_id, all_user_data, group_id, num)
|
||||
return rst
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+74
-102
@@ -1,43 +1,41 @@
|
||||
from services.db_context import db
|
||||
from typing import List
|
||||
|
||||
from tortoise import fields
|
||||
|
||||
from services.db_context import Model
|
||||
|
||||
|
||||
class RussianUser(db.Model):
|
||||
__tablename__ = "russian_users"
|
||||
__table_args__ = {'extend_existing': True}
|
||||
class RussianUser(Model):
|
||||
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||
group_id = db.Column(db.BigInteger(), nullable=False)
|
||||
win_count = db.Column(db.Integer(), default=0)
|
||||
fail_count = db.Column(db.Integer(), default=0)
|
||||
make_money = db.Column(db.Integer(), default=0)
|
||||
lose_money = db.Column(db.Integer(), default=0)
|
||||
winning_streak = db.Column(db.Integer(), default=0)
|
||||
losing_streak = db.Column(db.Integer(), default=0)
|
||||
max_winning_streak = db.Column(db.Integer(), default=0)
|
||||
max_losing_streak = db.Column(db.Integer(), default=0)
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
"""用户id"""
|
||||
group_id = fields.BigIntField()
|
||||
"""群聊id"""
|
||||
win_count = fields.IntField(default=0)
|
||||
"""胜利次数"""
|
||||
fail_count = fields.IntField(default=0)
|
||||
"""失败次数"""
|
||||
make_money = fields.IntField(default=0)
|
||||
"""赢得金币"""
|
||||
lose_money = fields.IntField(default=0)
|
||||
"""输得金币"""
|
||||
winning_streak = fields.IntField(default=0)
|
||||
"""当前连胜"""
|
||||
losing_streak = fields.IntField(default=0)
|
||||
"""当前连败"""
|
||||
max_winning_streak = fields.IntField(default=0)
|
||||
"""最大连胜"""
|
||||
max_losing_streak = fields.IntField(default=0)
|
||||
"""最大连败"""
|
||||
|
||||
_idx1 = db.Index("russian_group_users_idx1", "user_qq", "group_id", unique=True)
|
||||
class Meta:
|
||||
table = "russian_users"
|
||||
table_description = "俄罗斯轮盘数据表"
|
||||
unique_together = ("user_qq", "group_id")
|
||||
|
||||
@classmethod
|
||||
async def ensure(cls, user_qq: int, group_id: int) -> "RussianUser":
|
||||
"""
|
||||
说明:
|
||||
获取用户对象
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 群号
|
||||
"""
|
||||
user = (
|
||||
await cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
.with_for_update()
|
||||
.gino.first()
|
||||
)
|
||||
return user or await cls.create(user_qq=user_qq, group_id=group_id)
|
||||
|
||||
@classmethod
|
||||
async def add_count(cls, user_qq: int, group_id: int, itype: str) -> bool:
|
||||
async def add_count(cls, user_qq: int, group_id: int, itype: str):
|
||||
"""
|
||||
说明:
|
||||
添加用户输赢次数
|
||||
@@ -46,43 +44,43 @@ class RussianUser(db.Model):
|
||||
:param group_id: 群号
|
||||
:param itype: 输或赢 'win' or 'lose'
|
||||
"""
|
||||
try:
|
||||
user = (
|
||||
await cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
)
|
||||
.with_for_update()
|
||||
.gino.first()
|
||||
user, _ = await cls.get_or_create(user_qq=user_qq, group_id=group_id)
|
||||
if itype == "win":
|
||||
_max = (
|
||||
user.max_winning_streak
|
||||
if user.max_winning_streak > user.winning_streak + 1
|
||||
else user.winning_streak + 1
|
||||
)
|
||||
user.win_count = user.win_count + 1
|
||||
user.winning_streak = user.winning_streak + 1
|
||||
user.losing_streak = 0
|
||||
user.max_winning_streak = _max
|
||||
await user.save(
|
||||
update_fields=[
|
||||
"win_count",
|
||||
"winning_streak",
|
||||
"losing_streak",
|
||||
"max_winning_streak",
|
||||
]
|
||||
)
|
||||
elif itype == "lose":
|
||||
_max = (
|
||||
user.max_losing_streak
|
||||
if user.max_losing_streak > user.losing_streak + 1
|
||||
else user.losing_streak + 1
|
||||
)
|
||||
user.fail_count = user.fail_count + 1
|
||||
user.losing_streak = user.losing_streak + 1
|
||||
user.winning_streak = 0
|
||||
user.max_losing_streak = _max
|
||||
await user.save(
|
||||
update_fields=[
|
||||
"fail_count",
|
||||
"winning_streak",
|
||||
"losing_streak",
|
||||
"max_losing_streak",
|
||||
]
|
||||
)
|
||||
if not user:
|
||||
user = await cls.create(user_qq=user_qq, group_id=group_id)
|
||||
if itype == "win":
|
||||
_max = (
|
||||
user.max_winning_streak
|
||||
if user.max_winning_streak > user.winning_streak + 1
|
||||
else user.winning_streak + 1
|
||||
)
|
||||
await user.update(
|
||||
win_count=user.win_count + 1,
|
||||
winning_streak=user.winning_streak + 1,
|
||||
losing_streak=0,
|
||||
max_winning_streak=_max
|
||||
).apply()
|
||||
elif itype == "lose":
|
||||
_max = (
|
||||
user.max_losing_streak
|
||||
if user.max_losing_streak > user.losing_streak + 1
|
||||
else user.losing_streak + 1
|
||||
)
|
||||
await user.update(
|
||||
fail_count=user.fail_count + 1,
|
||||
losing_streak=user.losing_streak + 1,
|
||||
winning_streak=0,
|
||||
max_losing_streak=_max,
|
||||
).apply()
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def money(cls, user_qq: int, group_id: int, itype: str, count: int) -> bool:
|
||||
@@ -95,35 +93,9 @@ class RussianUser(db.Model):
|
||||
:param itype: 输或赢 'win' or 'lose'
|
||||
:param count: 金钱数量
|
||||
"""
|
||||
try:
|
||||
user = (
|
||||
await cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
)
|
||||
.with_for_update()
|
||||
.gino.first()
|
||||
)
|
||||
if not user:
|
||||
user = await cls.create(user_qq=user_qq, group_id=group_id)
|
||||
if itype == "win":
|
||||
await user.update(
|
||||
make_money=user.make_money + count,
|
||||
).apply()
|
||||
elif itype == "lose":
|
||||
await user.update(
|
||||
lose_money=user.lose_money + count,
|
||||
).apply()
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def get_all_user(cls, group_id: int) -> List["RussianUser"]:
|
||||
"""
|
||||
说明:
|
||||
获取该群所有用户对象
|
||||
参数:
|
||||
:param group_id: 群号
|
||||
"""
|
||||
users = await cls.query.where((cls.group_id == group_id)).gino.all()
|
||||
return users
|
||||
user, _ = await cls.get_or_create(user_qq=user_qq, group_id=group_id)
|
||||
if itype == "win":
|
||||
user.make_money = user.make_money + count
|
||||
elif itype == "lose":
|
||||
user.lose_money = user.lose_money + count
|
||||
await user.save(update_fields=["make_money", "lose_money"])
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import os
|
||||
import random
|
||||
|
||||
from nonebot import on_keyword
|
||||
from utils.message_builder import record
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, MessageEvent
|
||||
from nonebot.rule import to_me
|
||||
from nonebot.typing import T_State
|
||||
|
||||
from configs.path_config import RECORD_PATH
|
||||
from services.log import logger
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GroupMessageEvent
|
||||
from nonebot.rule import to_me
|
||||
import random
|
||||
import os
|
||||
from utils.message_builder import record
|
||||
|
||||
__zx_plugin_name__ = "骂我"
|
||||
__plugin_usage__ = """
|
||||
@@ -25,10 +27,7 @@ __plugin_settings__ = {
|
||||
"limit_superuser": False,
|
||||
"cmd": ["骂老子", "骂我"],
|
||||
}
|
||||
__plugin_cd_limit__ = {
|
||||
"cd": 3,
|
||||
"rst": "就...就算求我骂你也得慢慢来..."
|
||||
}
|
||||
__plugin_cd_limit__ = {"cd": 3, "rst": "就...就算求我骂你也得慢慢来..."}
|
||||
|
||||
|
||||
dg_voice = on_keyword({"骂"}, rule=to_me(), priority=5, block=True)
|
||||
@@ -38,7 +37,9 @@ dg_voice = on_keyword({"骂"}, rule=to_me(), priority=5, block=True)
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
if len(str((event.get_message()))) > 1:
|
||||
voice = random.choice(os.listdir(RECORD_PATH / "dinggong"))
|
||||
result = record(voice, "dinggong")
|
||||
result = record(
|
||||
RECORD_PATH / "dinggong" / voice,
|
||||
)
|
||||
await dg_voice.send(result)
|
||||
await dg_voice.send(voice.split("_")[1])
|
||||
logger.info(
|
||||
|
||||
+48
-161
@@ -1,64 +1,44 @@
|
||||
from services.db_context import db
|
||||
from typing import List, Optional
|
||||
|
||||
from tortoise import fields
|
||||
from tortoise.contrib.postgres.functions import Random
|
||||
from tortoise.expressions import Q
|
||||
|
||||
class Setu(db.Model):
|
||||
__tablename__ = "setu"
|
||||
__table_args__ = {'extend_existing': True}
|
||||
from services.db_context import Model
|
||||
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
local_id = db.Column(db.Integer(), nullable=False)
|
||||
title = db.Column(db.String(), nullable=False)
|
||||
author = db.Column(db.String(), nullable=False)
|
||||
pid = db.Column(db.BigInteger(), nullable=False)
|
||||
img_hash = db.Column(db.String(), nullable=False)
|
||||
img_url = db.Column(db.String(), nullable=False)
|
||||
is_r18 = db.Column(db.Boolean(), nullable=False)
|
||||
tags = db.Column(db.String())
|
||||
|
||||
_idx1 = db.Index("setu_pid_img_url_idx1", "pid", "img_url", unique=True)
|
||||
class Setu(Model):
|
||||
|
||||
@classmethod
|
||||
async def add_setu_data(
|
||||
cls,
|
||||
local_id: int,
|
||||
title: str,
|
||||
author: str,
|
||||
pid: int,
|
||||
img_hash: str,
|
||||
img_url: str,
|
||||
tags: str,
|
||||
):
|
||||
"""
|
||||
说明:
|
||||
添加一份色图数据
|
||||
参数:
|
||||
:param local_id: 本地存储id
|
||||
:param title: 标题
|
||||
:param author: 作者
|
||||
:param pid: 图片pid
|
||||
:param img_hash: 图片hash值
|
||||
:param img_url: 图片链接
|
||||
:param tags: 图片标签
|
||||
"""
|
||||
if not await cls._check_exists(pid, img_url):
|
||||
await cls.create(
|
||||
local_id=local_id,
|
||||
title=title,
|
||||
author=author,
|
||||
pid=pid,
|
||||
img_hash=img_hash,
|
||||
img_url=img_url,
|
||||
is_r18=True if "R-18" in tags else False,
|
||||
tags=tags,
|
||||
)
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
local_id = fields.IntField()
|
||||
"""本地存储下标"""
|
||||
title = fields.CharField(255)
|
||||
"""标题"""
|
||||
author = fields.CharField(255)
|
||||
"""作者"""
|
||||
pid = fields.BigIntField()
|
||||
"""pid"""
|
||||
img_hash = fields.TextField()
|
||||
"""图片hash"""
|
||||
img_url = fields.CharField(255)
|
||||
"""pixiv url链接"""
|
||||
is_r18 = fields.BooleanField()
|
||||
"""是否r18"""
|
||||
tags = fields.TextField()
|
||||
"""tags"""
|
||||
|
||||
class Meta:
|
||||
table = "setu"
|
||||
table_description = "色图数据表"
|
||||
unique_together = ("pid", "img_url")
|
||||
|
||||
@classmethod
|
||||
async def query_image(
|
||||
cls,
|
||||
local_id: Optional[int] = None,
|
||||
tags: Optional[List[str]] = None,
|
||||
r18: int = 0,
|
||||
r18: bool = False,
|
||||
limit: int = 50,
|
||||
):
|
||||
"""
|
||||
@@ -71,58 +51,17 @@ class Setu(db.Model):
|
||||
:param limit: 获取数量
|
||||
"""
|
||||
if local_id:
|
||||
flag = True if r18 == 1 else False
|
||||
return await cls.query.where(
|
||||
(cls.local_id == local_id) & (cls.is_r18 == flag)
|
||||
).gino.first()
|
||||
if r18 == 0:
|
||||
query = cls.query.where(cls.is_r18 == False)
|
||||
elif r18 == 1:
|
||||
query = cls.query.where(cls.is_r18 == True)
|
||||
else:
|
||||
query = cls.query
|
||||
return await cls.filter(is_r18=r18, local_id=local_id).first()
|
||||
query = cls.filter(is_r18=r18)
|
||||
if tags:
|
||||
for tag in tags:
|
||||
query = query.where(cls.tags.contains(tag) | cls.title.contains(tag) | cls.author.contains(tag))
|
||||
query = query.order_by(db.func.random()).limit(limit)
|
||||
return await query.gino.all()
|
||||
|
||||
@classmethod
|
||||
async def get_image_count(cls, r18: int = 0) -> int:
|
||||
"""
|
||||
说明:
|
||||
查询图片数量
|
||||
"""
|
||||
flag = False if r18 == 0 else True
|
||||
setattr(Setu, 'count', db.func.count(cls.local_id).label('count'))
|
||||
count = await cls.select('count').where(cls.is_r18 == flag).gino.first()
|
||||
return count[0]
|
||||
|
||||
@classmethod
|
||||
async def get_image_in_hash(cls, img_hash: str) -> "Setu":
|
||||
"""
|
||||
说明:
|
||||
通过图像hash获取图像信息
|
||||
参数:
|
||||
:param img_hash: = 图像hash值
|
||||
"""
|
||||
query = await cls.query.where(cls.img_hash == img_hash).gino.first()
|
||||
return query
|
||||
|
||||
@classmethod
|
||||
async def _check_exists(cls, pid: int, img_url: str) -> bool:
|
||||
"""
|
||||
说明:
|
||||
检测图片是否存在
|
||||
参数:
|
||||
:param pid: 图片pid
|
||||
:param img_url: 图片链接
|
||||
"""
|
||||
return bool(
|
||||
await cls.query.where(
|
||||
(cls.pid == pid) & (cls.img_url == img_url)
|
||||
).gino.first()
|
||||
)
|
||||
query = query.filter(
|
||||
Q(tags__contains=tag)
|
||||
| Q(title__contains=tag)
|
||||
| Q(author__contains=tag)
|
||||
)
|
||||
query = query.annotate(rand=Random()).limit(limit)
|
||||
return await query.all()
|
||||
|
||||
@classmethod
|
||||
async def delete_image(cls, pid: int) -> int:
|
||||
@@ -132,66 +71,14 @@ class Setu(db.Model):
|
||||
参数:
|
||||
:param pid: 图片pid
|
||||
"""
|
||||
query = await cls.query.where(cls.pid == pid).gino.first()
|
||||
return_id = -1
|
||||
query = await cls.get_or_none(pid=pid)
|
||||
if query:
|
||||
is_r18 = query.is_r18
|
||||
num = await cls.get_image_count(is_r18)
|
||||
x = await cls.query.where((cls.is_r18 == is_r18) & (cls.local_id == num - 1)).gino.first()
|
||||
_tmp_local_id = x.local_id
|
||||
if x:
|
||||
x.update(local_id=query.local_id).apply()
|
||||
await cls.delete.where(cls.pid == pid).gino.status()
|
||||
return _tmp_local_id
|
||||
return -1
|
||||
|
||||
@classmethod
|
||||
async def update_setu_data(
|
||||
cls,
|
||||
pid: int,
|
||||
*,
|
||||
local_id: Optional[int] = None,
|
||||
title: Optional[str] = None,
|
||||
author: Optional[str] = None,
|
||||
img_hash: Optional[str] = None,
|
||||
img_url: Optional[str] = None,
|
||||
tags: Optional[str] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
说明:
|
||||
根据PID修改图片数据
|
||||
参数:
|
||||
:param local_id: 本地id
|
||||
:param pid: 图片pid
|
||||
:param title: 标题
|
||||
:param author: 作者
|
||||
:param img_hash: 图片hash值
|
||||
:param img_url: 图片链接
|
||||
:param tags: 图片标签
|
||||
"""
|
||||
query = cls.query.where(cls.pid == pid).with_for_update()
|
||||
image_list = await query.gino.all()
|
||||
if image_list:
|
||||
for image in image_list:
|
||||
if local_id:
|
||||
await image.update(local_id=local_id).apply()
|
||||
if title:
|
||||
await image.update(title=title).apply()
|
||||
if author:
|
||||
await image.update(author=author).apply()
|
||||
if img_hash:
|
||||
await image.update(img_hash=img_hash).apply()
|
||||
if img_url:
|
||||
await image.update(img_url=img_url).apply()
|
||||
if tags:
|
||||
await image.update(tags=tags).apply()
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def get_all_setu(cls) -> List["Setu"]:
|
||||
"""
|
||||
说明:
|
||||
获取所有图片对象
|
||||
"""
|
||||
return await cls.query.gino.all()
|
||||
|
||||
num = await cls.filter(is_r18=query.is_r18).count()
|
||||
last_image = await cls.get_or_none(is_r18=query.is_r18, local_id=num - 1)
|
||||
if last_image:
|
||||
return_id = last_image.local_id
|
||||
last_image.local_id = query.local_id
|
||||
await last_image.save(update_fields=["local_id"])
|
||||
await query.delete()
|
||||
return return_id
|
||||
|
||||
@@ -1,42 +1,40 @@
|
||||
import random
|
||||
from nonebot import on_command, on_regex
|
||||
from services.log import logger
|
||||
from models.sign_group_user import SignGroupUser
|
||||
from nonebot.message import run_postprocessor
|
||||
from nonebot.matcher import Matcher
|
||||
from typing import Optional, Type, Any
|
||||
from gino.exceptions import UninitializedError
|
||||
import re
|
||||
from typing import Any, Optional, Tuple, Type
|
||||
|
||||
from utils.message_builder import custom_forward_msg
|
||||
from utils.utils import (
|
||||
is_number,
|
||||
)
|
||||
from nonebot.typing import T_State
|
||||
from nonebot import on_command, on_regex
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
Bot,
|
||||
ActionFailed,
|
||||
MessageEvent,
|
||||
GroupMessageEvent,
|
||||
PrivateMessageEvent,
|
||||
Message,
|
||||
Bot,
|
||||
Event,
|
||||
GroupMessageEvent,
|
||||
Message,
|
||||
MessageEvent,
|
||||
PrivateMessageEvent,
|
||||
)
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.message import run_postprocessor
|
||||
from nonebot.params import Command, CommandArg, RegexGroup
|
||||
from nonebot.typing import T_State
|
||||
|
||||
from configs.config import NICKNAME, Config
|
||||
from models.sign_group_user import SignGroupUser
|
||||
from services.log import logger
|
||||
from utils.manager import withdraw_message_manager
|
||||
from utils.message_builder import custom_forward_msg
|
||||
from utils.utils import is_number
|
||||
|
||||
from .._model import Setu
|
||||
from .data_source import (
|
||||
get_setu_list,
|
||||
get_luoxiang,
|
||||
search_online_setu,
|
||||
get_setu_urls,
|
||||
add_data_to_database,
|
||||
check_local_exists_or_download,
|
||||
find_img_index,
|
||||
gen_message,
|
||||
check_local_exists_or_download,
|
||||
add_data_to_database,
|
||||
get_setu_count,
|
||||
get_luoxiang,
|
||||
get_setu_list,
|
||||
get_setu_urls,
|
||||
search_online_setu,
|
||||
)
|
||||
from configs.config import Config, NICKNAME
|
||||
from utils.manager import withdraw_message_manager
|
||||
from nonebot.params import CommandArg, Command, RegexGroup
|
||||
from typing import Tuple
|
||||
import re
|
||||
|
||||
try:
|
||||
import ujson as json
|
||||
@@ -126,7 +124,7 @@ async def do_something(
|
||||
await add_data_to_database(setu_data_list)
|
||||
logger.info("色图数据自动存储数据库成功...")
|
||||
setu_data_list = []
|
||||
except UninitializedError:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
@@ -146,17 +144,18 @@ async def _(
|
||||
):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
impression = (
|
||||
await SignGroupUser.ensure(event.user_id, event.group_id)
|
||||
).impression
|
||||
user, _ = await SignGroupUser.get_or_create(
|
||||
user_qq=event.user_id, group_id=event.group_id
|
||||
)
|
||||
impression = user.impression
|
||||
luox = get_luoxiang(impression)
|
||||
if luox:
|
||||
await setu.finish(luox)
|
||||
r18 = 0
|
||||
r18 = False
|
||||
num = 1
|
||||
# 是否看r18
|
||||
if cmd[0] == "色图r" and isinstance(event, PrivateMessageEvent):
|
||||
r18 = 1
|
||||
r18 = True
|
||||
num = 10
|
||||
elif cmd[0] == "色图r" and isinstance(event, GroupMessageEvent):
|
||||
if not Config.get_config("send_setu", "ALLOW_GROUP_R18"):
|
||||
@@ -164,18 +163,20 @@ async def _(
|
||||
random.choice(["这种不好意思的东西怎么可能给这么多人看啦", "羞羞脸!给我滚出克私聊!", "变态变态变态变态大变态!"])
|
||||
)
|
||||
else:
|
||||
r18 = 1
|
||||
r18 = False
|
||||
# 有 数字 的话先尝试本地色图id
|
||||
if msg and is_number(msg):
|
||||
setu_list, code = await get_setu_list(int(msg), r18=r18)
|
||||
if code != 200:
|
||||
await setu.finish(setu_list[0], at_sender=True)
|
||||
setu_img, code = await check_local_exists_or_download(setu_list[0])
|
||||
msg_id = await setu.send(gen_message(setu_list[0]) + setu_img, at_sender=True)
|
||||
msg_id = await setu.send(
|
||||
Message(gen_message(setu_list[0])) + setu_img, at_sender=True
|
||||
)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
f" 发送色图 {setu_list[0].local_id}.png"
|
||||
f" 发送色图 {setu_list[0].local_id}.jpd"
|
||||
)
|
||||
if msg_id:
|
||||
withdraw_message_manager.withdraw_message(
|
||||
@@ -205,9 +206,10 @@ num_key = {
|
||||
@setu_reg.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, reg_group: Tuple[Any, ...] = RegexGroup()):
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
impression = (
|
||||
await SignGroupUser.ensure(event.user_id, event.group_id)
|
||||
).impression
|
||||
user, _ = await SignGroupUser.get_or_create(
|
||||
user_qq=event.user_id, group_id=event.group_id
|
||||
)
|
||||
impression = user.impression
|
||||
luox = get_luoxiang(impression)
|
||||
if luox:
|
||||
await setu.finish(luox, at_sender=True)
|
||||
@@ -220,7 +222,7 @@ async def _(bot: Bot, event: MessageEvent, reg_group: Tuple[Any, ...] = RegexGro
|
||||
num = int(num)
|
||||
except ValueError:
|
||||
num = 1
|
||||
await send_setu_handle(bot, setu_reg, event, "色图", tags, num, 0)
|
||||
await send_setu_handle(bot, setu_reg, event, "色图", tags, num, False)
|
||||
|
||||
|
||||
async def send_setu_handle(
|
||||
@@ -230,7 +232,7 @@ async def send_setu_handle(
|
||||
command: str,
|
||||
msg: str,
|
||||
num: int,
|
||||
r18: int,
|
||||
r18: bool,
|
||||
):
|
||||
global setu_data_list
|
||||
# 非 id,在线搜索
|
||||
@@ -240,7 +242,7 @@ async def send_setu_handle(
|
||||
await matcher.finish("咳咳咳,虽然我很可爱,但是我木有自己的色图~~~有的话记得发我一份呀")
|
||||
# 本地先拿图,下载失败补上去
|
||||
setu_list, code = None, 200
|
||||
setu_count = await get_setu_count(r18)
|
||||
setu_count = await Setu.filter(is_r18=r18).count()
|
||||
if (
|
||||
not Config.get_config("send_setu", "ONLY_USE_LOCAL_SETU") and tags
|
||||
) or setu_count <= 0:
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
from configs.path_config import IMAGE_PATH, TEMP_PATH
|
||||
from utils.message_builder import image
|
||||
from services.log import logger
|
||||
from utils.image_utils import get_img_hash, compressed_image
|
||||
from utils.utils import change_img_md5
|
||||
from asyncpg.exceptions import UniqueViolationError
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from typing import List, Optional
|
||||
from configs.config import NICKNAME, Config
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from .._model import Setu
|
||||
import asyncio
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from typing import List, Optional, Tuple, Union
|
||||
|
||||
from asyncpg.exceptions import UniqueViolationError
|
||||
from nonebot.adapters.onebot.v11 import Message, MessageSegment
|
||||
|
||||
from configs.config import NICKNAME, Config
|
||||
from configs.path_config import IMAGE_PATH, TEMP_PATH
|
||||
from services.log import logger
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.image_utils import compressed_image, get_img_hash
|
||||
from utils.message_builder import image
|
||||
from utils.utils import change_img_md5
|
||||
|
||||
from .._model import Setu
|
||||
|
||||
try:
|
||||
import ujson as json
|
||||
@@ -28,11 +32,11 @@ host_pattern = re.compile(r"https?://([^/]+)")
|
||||
|
||||
# 获取url
|
||||
async def get_setu_urls(
|
||||
tags: List[str], num: int = 1, r18: int = 0, command: str = ""
|
||||
) -> "List[str], List[str], List[tuple], int":
|
||||
tags: List[str], num: int = 1, r18: bool = False, command: str = ""
|
||||
) -> Tuple[List[str], List[str], List[tuple], int]:
|
||||
tags = tags[:3] if len(tags) > 3 else tags
|
||||
params = {
|
||||
"r18": r18, # 添加r18参数 0为否,1为是,2为混合
|
||||
"r18": 1 if r18 else 0, # 添加r18参数 0为否,1为是,2为混合
|
||||
"tag": tags, # 若指定tag
|
||||
"num": 20, # 一次返回的结果数量
|
||||
"size": ["original"],
|
||||
@@ -82,7 +86,7 @@ headers = {
|
||||
|
||||
async def search_online_setu(
|
||||
url_: str, id_: Optional[int] = None, path_: Optional[str] = None
|
||||
) -> "MessageSegment, int":
|
||||
) -> Tuple[Union[MessageSegment, str], int]:
|
||||
"""
|
||||
下载色图
|
||||
:param url_: 色图url
|
||||
@@ -108,10 +112,7 @@ async def search_online_setu(
|
||||
):
|
||||
continue
|
||||
if id_ is not None:
|
||||
if (
|
||||
os.path.getsize(path_ / f"{index}.jpg")
|
||||
> 1024 * 1024 * 1.5
|
||||
):
|
||||
if os.path.getsize(path_ / f"{index}.jpg") > 1024 * 1024 * 1.5:
|
||||
compressed_image(
|
||||
path_ / f"{index}.jpg",
|
||||
)
|
||||
@@ -126,7 +127,9 @@ async def search_online_setu(
|
||||
|
||||
|
||||
# 检测本地是否有id涩图,无的话则下载
|
||||
async def check_local_exists_or_download(setu_image: Setu) -> "MessageSegment, int":
|
||||
async def check_local_exists_or_download(
|
||||
setu_image: Setu,
|
||||
) -> Tuple[MessageSegment, int]:
|
||||
path_ = None
|
||||
id_ = None
|
||||
if Config.get_config("send_setu", "DOWNLOAD_SETU"):
|
||||
@@ -148,27 +151,28 @@ async def add_data_to_database(lst: List[tuple]):
|
||||
if tmp:
|
||||
for x in tmp:
|
||||
try:
|
||||
r18 = 1 if "R-18" in x[5] else 0
|
||||
idx = await Setu.get_image_count(r18)
|
||||
await Setu.add_setu_data(
|
||||
idx,
|
||||
x[0],
|
||||
x[1],
|
||||
x[2],
|
||||
x[3],
|
||||
x[4],
|
||||
x[5],
|
||||
)
|
||||
idx = await Setu.filter(is_r18="R-18" in x[5]).count()
|
||||
if not await Setu.exists(pid=x[2], img_url=x[4]):
|
||||
await Setu.create(
|
||||
local_id=idx,
|
||||
title=x[0],
|
||||
author=x[1],
|
||||
pid=x[2],
|
||||
img_hash=x[3],
|
||||
img_url=x[4],
|
||||
tags=x[5],
|
||||
is_r18="R-18" in x[5],
|
||||
)
|
||||
except UniqueViolationError:
|
||||
pass
|
||||
|
||||
|
||||
# 拿到本地色图列表
|
||||
async def get_setu_list(
|
||||
index: Optional[int] = None, tags: Optional[List[str]] = None, r18: int = 0
|
||||
) -> "list, int":
|
||||
index: Optional[int] = None, tags: Optional[List[str]] = None, r18: bool = False
|
||||
) -> Tuple[list, int]:
|
||||
if index:
|
||||
image_count = await Setu.get_image_count(r18) - 1
|
||||
image_count = await Setu.filter(is_r18=r18).count() - 1
|
||||
if index < 0 or index > image_count:
|
||||
return [f"超过当前上下限!({image_count})"], 999
|
||||
image_list = [await Setu.query_image(index, r18=r18)]
|
||||
@@ -182,44 +186,44 @@ async def get_setu_list(
|
||||
|
||||
|
||||
# 初始化消息
|
||||
def gen_message(setu_image: Setu, img_msg: bool = False) -> str:
|
||||
def gen_message(
|
||||
setu_image: Setu, img_msg: bool = False
|
||||
) -> Union[Message, MessageSegment]:
|
||||
local_id = setu_image.local_id
|
||||
title = setu_image.title
|
||||
author = setu_image.author
|
||||
pid = setu_image.pid
|
||||
path_ = r18_path if setu_image.is_r18 else path
|
||||
image_path = IMAGE_PATH / path_ / f"{local_id}.jpg"
|
||||
if Config.get_config("send_setu", "SHOW_INFO"):
|
||||
return (
|
||||
return Message(
|
||||
f"id:{local_id}\n"
|
||||
f"title:{title}\n"
|
||||
f"author:{author}\n"
|
||||
f"PID:{pid}\n"
|
||||
f"{image(f'{local_id}', f'{r18_path if setu_image.is_r18 else path}') if img_msg else ''}"
|
||||
f"PID:{pid}\n" + image(image_path)
|
||||
)
|
||||
return f"{image(f'{local_id}', f'{r18_path if setu_image.is_r18 else path}') if img_msg else ''}"
|
||||
return image(image_path)
|
||||
|
||||
|
||||
# 罗翔老师!
|
||||
def get_luoxiang(impression):
|
||||
probability = (
|
||||
impression + Config.get_config("send_setu", "INITIAL_SETU_PROBABILITY") * 100
|
||||
float(impression)
|
||||
+ Config.get_config("send_setu", "INITIAL_SETU_PROBABILITY") * 100
|
||||
)
|
||||
if probability < random.randint(1, 101):
|
||||
return (
|
||||
"我为什么要给你发这个?"
|
||||
+ image(random.choice(os.listdir(IMAGE_PATH / "luoxiang")), "luoxiang")
|
||||
+ image(
|
||||
IMAGE_PATH
|
||||
/ "luoxiang"
|
||||
/ random.choice(os.listdir(IMAGE_PATH / "luoxiang"))
|
||||
)
|
||||
+ f"\n(快向{NICKNAME}签到提升好感度吧!)"
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
async def get_setu_count(r18: int) -> int:
|
||||
"""
|
||||
获取色图数量
|
||||
:param r18: r18类型
|
||||
"""
|
||||
return await Setu.get_image_count(r18)
|
||||
|
||||
|
||||
async def find_img_index(img_url, user_id):
|
||||
if not await AsyncHttpx.download_file(
|
||||
img_url,
|
||||
@@ -228,8 +232,7 @@ async def find_img_index(img_url, user_id):
|
||||
):
|
||||
return "检索图片下载上失败..."
|
||||
img_hash = str(get_img_hash(TEMP_PATH / f"{user_id}_find_setu_index.jpg"))
|
||||
setu_img = await Setu.get_image_in_hash(img_hash)
|
||||
if setu_img:
|
||||
if setu_img := await Setu.get_or_none(img_hash=img_hash):
|
||||
return (
|
||||
f"id:{setu_img.local_id}\n"
|
||||
f"title:{setu_img.title}\n"
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
from configs.path_config import IMAGE_PATH, TEXT_PATH, TEMP_PATH
|
||||
from services.log import logger
|
||||
from datetime import datetime
|
||||
from utils.image_utils import compressed_image, get_img_hash
|
||||
from utils.utils import get_bot
|
||||
from PIL import UnidentifiedImageError
|
||||
from .._model import Setu
|
||||
from asyncpg.exceptions import UniqueViolationError
|
||||
from configs.config import Config
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from nonebot import Driver
|
||||
import nonebot
|
||||
import os
|
||||
import ujson as json
|
||||
import shutil
|
||||
from datetime import datetime
|
||||
|
||||
import nonebot
|
||||
import ujson as json
|
||||
from asyncpg.exceptions import UniqueViolationError
|
||||
from nonebot import Driver
|
||||
from PIL import UnidentifiedImageError
|
||||
|
||||
from configs.config import Config
|
||||
from configs.path_config import IMAGE_PATH, TEMP_PATH, TEXT_PATH
|
||||
from services.log import logger
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.image_utils import compressed_image, get_img_hash
|
||||
from utils.utils import change_pixiv_image_links, get_bot
|
||||
|
||||
from .._model import Setu
|
||||
|
||||
driver: Driver = nonebot.get_driver()
|
||||
|
||||
@@ -47,15 +50,17 @@ async def update_old_setu_data():
|
||||
)
|
||||
# idx = r18_index if 'R-18' in data[x]["tags"] else index
|
||||
try:
|
||||
await Setu.add_setu_data(
|
||||
idx,
|
||||
data[x]["title"],
|
||||
data[x]["author"],
|
||||
data[x]["pid"],
|
||||
data[x]["img_hash"],
|
||||
img_url,
|
||||
",".join(data[x]["tags"]),
|
||||
)
|
||||
if not await Setu.exists(pid=data[x]["pid"], url=img_url):
|
||||
await Setu.create(
|
||||
local_id=idx,
|
||||
title=data[x]["title"],
|
||||
author=data[x]["author"],
|
||||
pid=data[x]["pid"],
|
||||
img_hash=data[x]["img_hash"],
|
||||
img_url=img_url,
|
||||
is_r18="R-18" in data[x]["tags"],
|
||||
tags=",".join(data[x]["tags"]),
|
||||
)
|
||||
count += 1
|
||||
if "R-18" in data[x]["tags"]:
|
||||
r18_index += 1
|
||||
@@ -94,7 +99,7 @@ async def update_setu_img(flag: bool = False):
|
||||
更新色图
|
||||
:param flag: 是否手动更新
|
||||
"""
|
||||
image_list = await Setu.get_all_setu()
|
||||
image_list = await Setu.all().order_by("local_id")
|
||||
image_list.reverse()
|
||||
_success = 0
|
||||
error_info = []
|
||||
@@ -110,12 +115,7 @@ async def update_setu_img(flag: bool = False):
|
||||
temp_file = TEMP_PATH / f"{image.local_id}.jpg"
|
||||
if temp_file.exists():
|
||||
temp_file.unlink()
|
||||
url_ = image.img_url
|
||||
ws_url = Config.get_config("pixiv", "PIXIV_NGINX_URL")
|
||||
if ws_url:
|
||||
url_ = url_.replace("i.pximg.net", ws_url).replace(
|
||||
"i.pixiv.cat", ws_url
|
||||
)
|
||||
url_ = change_pixiv_image_links(image.img_url)
|
||||
try:
|
||||
if not await AsyncHttpx.download_file(
|
||||
url_, TEMP_PATH / f"{image.local_id}.jpg"
|
||||
@@ -146,15 +146,20 @@ async def update_setu_img(flag: bool = False):
|
||||
logger.warning(f"文件 {image.local_id}.jpg 不存在,跳过...")
|
||||
continue
|
||||
img_hash = str(get_img_hash(f"{path}/{image.local_id}.jpg"))
|
||||
await Setu.update_setu_data(image.pid, img_hash=img_hash)
|
||||
image.img_hash = img_hash
|
||||
await image.save(update_fields=["img_hash"])
|
||||
# await Setu.update_setu_data(image.pid, img_hash=img_hash)
|
||||
except UnidentifiedImageError:
|
||||
# 图片已删除
|
||||
with open(local_image, 'r') as f:
|
||||
if '404 Not Found' in f.read():
|
||||
max_num = await Setu.delete_image(image.pid)
|
||||
local_image.unlink()
|
||||
os.rename(path / f"{max_num}.jpg", local_image)
|
||||
logger.warning(f"更新色图 PID:{image.pid} 404,已删除并替换")
|
||||
unlink = False
|
||||
with open(local_image, "r") as f:
|
||||
if "404 Not Found" in f.read():
|
||||
unlink = True
|
||||
if unlink:
|
||||
local_image.unlink()
|
||||
max_num = await Setu.delete_image(image.pid)
|
||||
os.rename(path / f"{max_num}.jpg", local_image)
|
||||
logger.warning(f"更新色图 PID:{image.pid} 404,已删除并替换")
|
||||
except Exception as e:
|
||||
_success -= 1
|
||||
logger.error(f"更新色图 {image.local_id}.jpg 错误 {type(e)}: {e}")
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
from models.sign_group_user import SignGroupUser
|
||||
from configs.config import Config
|
||||
from nonebot import Driver
|
||||
from utils.decorator.shop import shop_register, NotMeetUseConditionsException
|
||||
import nonebot
|
||||
from nonebot import Driver
|
||||
|
||||
from configs.config import Config
|
||||
from models.sign_group_user import SignGroupUser
|
||||
from utils.decorator.shop import NotMeetUseConditionsException, shop_register
|
||||
|
||||
driver: Driver = nonebot.get_driver()
|
||||
|
||||
@@ -22,13 +22,18 @@ async def _():
|
||||
"下次签到双倍好感度概率 + 20%(平平庸庸)(同类商品将覆盖)",
|
||||
"下次签到双倍好感度概率 + 30%(金币才是真命天子!)(同类商品将覆盖)",
|
||||
),
|
||||
load_status=Config.get_config("shop", "IMPORT_DEFAULT_SHOP_GOODS"),
|
||||
icon=("favorability_card_1.png", "favorability_card_2.png", "favorability_card_3.png"),
|
||||
** {"好感度双倍加持卡Ⅰ_prob": 0.1, "好感度双倍加持卡Ⅱ_prob": 0.2, "好感度双倍加持卡Ⅲ_prob": 0.3},
|
||||
load_status=bool(Config.get_config("shop", "IMPORT_DEFAULT_SHOP_GOODS")),
|
||||
icon=(
|
||||
"favorability_card_1.png",
|
||||
"favorability_card_2.png",
|
||||
"favorability_card_3.png",
|
||||
),
|
||||
**{"好感度双倍加持卡Ⅰ_prob": 0.1, "好感度双倍加持卡Ⅱ_prob": 0.2, "好感度双倍加持卡Ⅲ_prob": 0.3},
|
||||
)
|
||||
async def sign_card(user_id: int, group_id: int, prob: float):
|
||||
user = await SignGroupUser.ensure(user_id, group_id)
|
||||
await user.update(add_probability=prob).apply()
|
||||
user, _ = await SignGroupUser.get_or_create(user_qq=user_id, group_id=group_id)
|
||||
user.add_probability = prob
|
||||
await user.save(update_fields=["add_probability"])
|
||||
|
||||
@shop_register(
|
||||
name="测试道具A",
|
||||
@@ -38,20 +43,17 @@ async def _():
|
||||
icon="sword.png",
|
||||
)
|
||||
async def _(user_id: int, group_id: int):
|
||||
print(user_id, group_id, '使用测试道具')
|
||||
print(user_id, group_id, "使用测试道具")
|
||||
|
||||
@shop_register.before_handle(name="测试道具A", load_status=False)
|
||||
async def _(user_id: int, group_id: int):
|
||||
print(user_id, group_id, '第一个使用前函数(before handle)')
|
||||
print(user_id, group_id, "第一个使用前函数(before handle)")
|
||||
|
||||
@shop_register.before_handle(name="测试道具A", load_status=False)
|
||||
async def _(user_id: int, group_id: int):
|
||||
print(user_id, group_id, '第二个使用前函数(before handle)222')
|
||||
raise NotMeetUseConditionsException("太笨了!") # 抛出异常,阻断使用,并返回信息
|
||||
print(user_id, group_id, "第二个使用前函数(before handle)222")
|
||||
raise NotMeetUseConditionsException("太笨了!") # 抛出异常,阻断使用,并返回信息
|
||||
|
||||
@shop_register.after_handle(name="测试道具A", load_status=False)
|
||||
async def _(user_id: int, group_id: int):
|
||||
print(user_id, group_id, '第一个使用后函数(after handle)')
|
||||
|
||||
|
||||
|
||||
print(user_id, group_id, "第一个使用后函数(after handle)")
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
from datetime import datetime, timedelta
|
||||
from models.sign_group_user import SignGroupUser
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from models.bag_user import BagUser
|
||||
from configs.config import NICKNAME
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
from utils.image_utils import BuildImage, BuildMat
|
||||
from services.db_context import db
|
||||
from .utils import get_card, SIGN_TODAY_CARD_PATH
|
||||
from typing import Optional
|
||||
from services.log import logger
|
||||
from .random_event import random_event
|
||||
from utils.data_utils import init_rank
|
||||
from utils.utils import get_user_avatar
|
||||
from io import BytesIO
|
||||
import random
|
||||
import math
|
||||
import asyncio
|
||||
import secrets
|
||||
import math
|
||||
import os
|
||||
import random
|
||||
import secrets
|
||||
from datetime import datetime, timedelta
|
||||
from io import BytesIO
|
||||
from typing import Optional
|
||||
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
|
||||
from configs.config import NICKNAME
|
||||
from models.bag_user import BagUser
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from models.sign_group_user import SignGroupUser
|
||||
from services.log import logger
|
||||
from utils.data_utils import init_rank
|
||||
from utils.image_utils import BuildImage, BuildMat
|
||||
from utils.utils import get_user_avatar
|
||||
|
||||
from .random_event import random_event
|
||||
from .utils import SIGN_TODAY_CARD_PATH, get_card
|
||||
|
||||
|
||||
async def group_user_check_in(
|
||||
@@ -25,18 +27,17 @@ async def group_user_check_in(
|
||||
) -> MessageSegment:
|
||||
"Returns string describing the result of checking in"
|
||||
present = datetime.now()
|
||||
async with db.transaction():
|
||||
# 取得相应用户
|
||||
user = await SignGroupUser.ensure(user_qq, group, for_update=True)
|
||||
# 如果同一天签到过,特殊处理
|
||||
if (
|
||||
user.checkin_time_last + timedelta(hours=8)
|
||||
).date() >= present.date() or f"{user}_{group}_sign_{datetime.now().date()}" in os.listdir(
|
||||
SIGN_TODAY_CARD_PATH
|
||||
):
|
||||
gold = await BagUser.get_gold(user_qq, group)
|
||||
return await get_card(user, nickname, -1, gold, "")
|
||||
return await _handle_check_in(nickname, user_qq, group, present) # ok
|
||||
# 取得相应用户
|
||||
user, is_create = await SignGroupUser.get_or_create(user_qq=user_qq, group_id=group)
|
||||
# 如果同一天签到过,特殊处理
|
||||
if not is_create and (
|
||||
user.checkin_time_last.date() >= present.date()
|
||||
or f"{user}_{group}_sign_{datetime.now().date()}"
|
||||
in os.listdir(SIGN_TODAY_CARD_PATH)
|
||||
):
|
||||
gold = await BagUser.get_gold(user_qq, group)
|
||||
return await get_card(user, nickname, -1, gold, "")
|
||||
return await _handle_check_in(nickname, user_qq, group, present) # ok
|
||||
|
||||
|
||||
async def check_in_all(nickname: str, user_qq: int):
|
||||
@@ -47,40 +48,39 @@ async def check_in_all(nickname: str, user_qq: int):
|
||||
:param nickname: 昵称
|
||||
:param user_qq: 用户qq
|
||||
"""
|
||||
async with db.transaction():
|
||||
present = datetime.now()
|
||||
for u in await SignGroupUser.get_user_all_data(user_qq):
|
||||
group = u.group_id
|
||||
if not ((
|
||||
u.checkin_time_last + timedelta(hours=8)
|
||||
).date() >= present.date() or f"{u}_{group}_sign_{datetime.now().date()}" in os.listdir(
|
||||
SIGN_TODAY_CARD_PATH
|
||||
)):
|
||||
await _handle_check_in(nickname, user_qq, group, present)
|
||||
present = datetime.now()
|
||||
for u in await SignGroupUser.filter(user_qq=user_qq).all():
|
||||
group = u.group_id
|
||||
if not (
|
||||
u.checkin_time_last.date() >= present.date()
|
||||
or f"{u}_{group}_sign_{datetime.now().date()}"
|
||||
in os.listdir(SIGN_TODAY_CARD_PATH)
|
||||
):
|
||||
await _handle_check_in(nickname, user_qq, group, present)
|
||||
|
||||
|
||||
async def _handle_check_in(
|
||||
nickname: str, user_qq: int, group: int, present: datetime
|
||||
) -> MessageSegment:
|
||||
user = await SignGroupUser.ensure(user_qq, group, for_update=True)
|
||||
impression_added = (secrets.randbelow(99)+1)/100
|
||||
user, _ = await SignGroupUser.get_or_create(user_qq=user_qq, group_id=group)
|
||||
impression_added = (secrets.randbelow(99) + 1) / 100
|
||||
critx2 = random.random()
|
||||
add_probability = user.add_probability
|
||||
add_probability = float(user.add_probability)
|
||||
specify_probability = user.specify_probability
|
||||
if critx2 + add_probability > 0.97:
|
||||
impression_added *= 2
|
||||
elif critx2 < specify_probability:
|
||||
impression_added *= 2
|
||||
await SignGroupUser.sign(user, impression_added, present)
|
||||
await SignGroupUser.sign(user, impression_added)
|
||||
gold = random.randint(1, 100)
|
||||
gift, gift_type = random_event(user.impression)
|
||||
gift, gift_type = random_event(float(user.impression))
|
||||
if gift_type == "gold":
|
||||
await BagUser.add_gold(user_qq, group, gold + gift)
|
||||
gift = f"额外金币 + {gift}"
|
||||
else:
|
||||
await BagUser.add_gold(user_qq, group, gold)
|
||||
await BagUser.add_property(user_qq, group, gift)
|
||||
gift += ' + 1'
|
||||
gift += " + 1"
|
||||
|
||||
logger.info(
|
||||
f"(USER {user.user_qq}, GROUP {user.group_id})"
|
||||
@@ -95,7 +95,7 @@ async def _handle_check_in(
|
||||
|
||||
async def group_user_check(nickname: str, user_qq: int, group: int) -> MessageSegment:
|
||||
# heuristic: if users find they have never checked in they are probable to check in
|
||||
user = await SignGroupUser.ensure(user_qq, group)
|
||||
user, _ = await SignGroupUser.get_or_create(user_qq=user_qq, group_id=group)
|
||||
gold = await BagUser.get_gold(user_qq, group)
|
||||
return await get_card(user, nickname, None, gold, "", is_card_view=True)
|
||||
|
||||
@@ -171,18 +171,14 @@ async def _pst(users: list, impressions: list, groups: list):
|
||||
impressions.pop(index)
|
||||
users.pop(index)
|
||||
groups.pop(index)
|
||||
try:
|
||||
user_name = (
|
||||
await GroupInfoUser.get_member_info(user, group)
|
||||
).user_name
|
||||
except AttributeError:
|
||||
if user_ := await GroupInfoUser.get_or_none(user_qq=user, group_id=group):
|
||||
user_name = user_.user_name
|
||||
else:
|
||||
user_name = f"我名字呢?"
|
||||
user_name = user_name if len(user_name) < 11 else user_name[:10] + "..."
|
||||
ava = await get_user_avatar(user)
|
||||
if ava:
|
||||
ava = BuildImage(
|
||||
50, 50, background=BytesIO(ava)
|
||||
)
|
||||
ava = BuildImage(50, 50, background=BytesIO(ava))
|
||||
else:
|
||||
ava = BuildImage(50, 50, color="white")
|
||||
ava.circle()
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
from configs.config import Config
|
||||
import random
|
||||
from typing import Tuple, Union
|
||||
|
||||
from configs.config import Config
|
||||
|
||||
PROB_DATA = None
|
||||
|
||||
|
||||
def random_event(impression: float) -> 'Union[str, int], str':
|
||||
def random_event(impression: float) -> Tuple[Union[str, int], str]:
|
||||
"""
|
||||
签到随机事件
|
||||
:param impression: 好感度
|
||||
@@ -14,20 +15,17 @@ def random_event(impression: float) -> 'Union[str, int], str':
|
||||
global PROB_DATA
|
||||
if not PROB_DATA:
|
||||
PROB_DATA = {
|
||||
Config.get_config("sign_in", "SIGN_CARD3_PROB"): '好感度双倍加持卡Ⅲ',
|
||||
Config.get_config("sign_in", "SIGN_CARD2_PROB"): '好感度双倍加持卡Ⅱ',
|
||||
Config.get_config("sign_in", "SIGN_CARD1_PROB"): '好感度双倍加持卡Ⅰ'
|
||||
Config.get_config("sign_in", "SIGN_CARD3_PROB"): "好感度双倍加持卡Ⅲ",
|
||||
Config.get_config("sign_in", "SIGN_CARD2_PROB"): "好感度双倍加持卡Ⅱ",
|
||||
Config.get_config("sign_in", "SIGN_CARD1_PROB"): "好感度双倍加持卡Ⅰ",
|
||||
}
|
||||
rand = random.random() - impression / 1000
|
||||
for prob in PROB_DATA.keys():
|
||||
if rand <= prob:
|
||||
return PROB_DATA[prob], 'props'
|
||||
gold = random.randint(1, random.randint(1, int(1 if impression < 1 else impression)))
|
||||
return PROB_DATA[prob], "props"
|
||||
gold = random.randint(
|
||||
1, random.randint(1, int(1 if impression < 1 else impression))
|
||||
)
|
||||
max_sign_gold = Config.get_config("sign_in", "MAX_SIGN_GOLD")
|
||||
gold = max_sign_gold if gold > max_sign_gold else gold
|
||||
return gold, 'gold'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return gold, "gold"
|
||||
|
||||
+50
-33
@@ -1,31 +1,33 @@
|
||||
from .config import (
|
||||
SIGN_RESOURCE_PATH,
|
||||
SIGN_TODAY_CARD_PATH,
|
||||
SIGN_BORDER_PATH,
|
||||
SIGN_BACKGROUND_PATH,
|
||||
lik2level,
|
||||
lik2relation,
|
||||
level2attitude,
|
||||
weekdays,
|
||||
)
|
||||
from models.sign_group_user import SignGroupUser
|
||||
from models.group_member_info import GroupInfoUser
|
||||
import asyncio
|
||||
import os
|
||||
import random
|
||||
from datetime import datetime
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
from typing import List, Optional
|
||||
|
||||
import nonebot
|
||||
from nonebot import Driver
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
from configs.config import Config
|
||||
from utils.utils import get_user_avatar
|
||||
|
||||
from configs.config import NICKNAME, Config
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from models.sign_group_user import SignGroupUser
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.message_builder import image
|
||||
from configs.config import NICKNAME
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
from typing import Optional, List
|
||||
from nonebot import Driver
|
||||
from io import BytesIO
|
||||
import asyncio
|
||||
import random
|
||||
import nonebot
|
||||
import os
|
||||
from utils.utils import get_user_avatar
|
||||
|
||||
from .config import (
|
||||
SIGN_BACKGROUND_PATH,
|
||||
SIGN_BORDER_PATH,
|
||||
SIGN_RESOURCE_PATH,
|
||||
SIGN_TODAY_CARD_PATH,
|
||||
level2attitude,
|
||||
lik2level,
|
||||
lik2relation,
|
||||
weekdays,
|
||||
)
|
||||
|
||||
driver: Driver = nonebot.get_driver()
|
||||
|
||||
@@ -34,10 +36,13 @@ driver: Driver = nonebot.get_driver()
|
||||
async def init_image():
|
||||
SIGN_RESOURCE_PATH.mkdir(parents=True, exist_ok=True)
|
||||
SIGN_TODAY_CARD_PATH.mkdir(exist_ok=True, parents=True)
|
||||
await GroupInfoUser.add_member_info(114514, 114514, "", datetime.min, 0)
|
||||
_u = await GroupInfoUser.get_member_info(114514, 114514)
|
||||
if _u.uid is None:
|
||||
await _u.update(uid=0).apply()
|
||||
if not await GroupInfoUser.get_or_none(user_qq=114514):
|
||||
await GroupInfoUser.create(
|
||||
user_qq=114514,
|
||||
group_id=114514,
|
||||
user_name="",
|
||||
uid=0,
|
||||
)
|
||||
generate_progress_bar_pic()
|
||||
clear_sign_data_pic()
|
||||
|
||||
@@ -58,7 +63,12 @@ async def get_card(
|
||||
Path(SIGN_TODAY_CARD_PATH) / f"{user_id}_{user.group_id}_{_type}_{date}.png"
|
||||
)
|
||||
if card_file.exists():
|
||||
return image(f"{user_id}_{user.group_id}_{_type}_{date}.png", "sign/today_card")
|
||||
return image(
|
||||
IMAGE_PATH
|
||||
/ "sign"
|
||||
/ "today_card"
|
||||
/ f"{user_id}_{user.group_id}_{_type}_{date}.png"
|
||||
)
|
||||
else:
|
||||
if add_impression == -1:
|
||||
card_file = (
|
||||
@@ -67,8 +77,10 @@ async def get_card(
|
||||
)
|
||||
if card_file.exists():
|
||||
return image(
|
||||
f"{user_id}_{user.group_id}_view_{date}.png",
|
||||
"sign/today_card",
|
||||
IMAGE_PATH
|
||||
/ "sign"
|
||||
/ "today_card"
|
||||
/ f"{user_id}_{user.group_id}_view_{date}.png"
|
||||
)
|
||||
is_card_view = True
|
||||
ava = BytesIO(await get_user_avatar(user_id))
|
||||
@@ -244,7 +256,7 @@ def _generate_card(
|
||||
)
|
||||
today_data.text(
|
||||
(0, 50),
|
||||
f"色图概率:{(default_setu_prob + user.impression if user.impression < 100 else 100):.2f}%",
|
||||
f"色图概率:{(default_setu_prob + float(user.impression) if user.impression < 100 else 100):.2f}%",
|
||||
)
|
||||
today_data.text((0, 75), f"开箱次数:{(20 + int(user.impression / 3))}")
|
||||
_type = "view"
|
||||
@@ -285,7 +297,12 @@ def _generate_card(
|
||||
bk.paste(today_data, (580, 220), True)
|
||||
bk.paste(watermark, (15, 400), True)
|
||||
bk.save(SIGN_TODAY_CARD_PATH / f"{user_id}_{user.group_id}_{_type}_{data}.png")
|
||||
return image(f"{user_id}_{user.group_id}_{_type}_{data}.png", "sign/today_card")
|
||||
return image(
|
||||
IMAGE_PATH
|
||||
/ "sign"
|
||||
/ "today_card"
|
||||
/ f"{user_id}_{user.group_id}_{_type}_{data}.png"
|
||||
)
|
||||
|
||||
|
||||
def generate_progress_bar_pic():
|
||||
|
||||
@@ -1,30 +1,23 @@
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from services.db_context import db
|
||||
|
||||
|
||||
class Statistics(db.Model):
|
||||
__tablename__ = "statistics"
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||
group_id = db.Column(db.BigInteger())
|
||||
plugin_name = db.Column(db.String(), nullable=False)
|
||||
create_time = db.Column(db.DateTime(timezone=True), nullable=False)
|
||||
from tortoise import fields
|
||||
|
||||
@classmethod
|
||||
async def add_statistic(cls, user_qq: int, group_id: Optional[int], plugin_name: str):
|
||||
"""
|
||||
说明:
|
||||
添加记录
|
||||
参数:
|
||||
:param user_qq: qq
|
||||
:param group_id: 群号
|
||||
:param plugin_name: 插件model
|
||||
"""
|
||||
await cls.create(
|
||||
user_qq=user_qq,
|
||||
group_id=group_id,
|
||||
plugin_name=plugin_name,
|
||||
create_time=datetime.now(),
|
||||
)
|
||||
from services.db_context import Model
|
||||
|
||||
|
||||
class Statistics(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
"""用户id"""
|
||||
group_id = fields.BigIntField(null=True)
|
||||
"""群聊id"""
|
||||
plugin_name = fields.CharField(255)
|
||||
"""插件名称"""
|
||||
create_time = fields.DatetimeField(auto_now=True)
|
||||
"""添加日期"""
|
||||
|
||||
class Meta:
|
||||
table = "statistics"
|
||||
table_description = "用户权限数据库"
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, MessageEvent, Message
|
||||
from models.group_info import GroupInfo
|
||||
from configs.path_config import DATA_PATH, IMAGE_PATH
|
||||
from nonebot.params import CommandArg, Command
|
||||
from utils.image_utils import BuildMat
|
||||
from utils.message_builder import image
|
||||
from utils.manager import plugins2settings_manager
|
||||
from typing import Tuple
|
||||
import asyncio
|
||||
import os
|
||||
from typing import Tuple
|
||||
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message, MessageEvent
|
||||
from nonebot.params import Command, CommandArg
|
||||
|
||||
from configs.path_config import DATA_PATH, IMAGE_PATH
|
||||
from models.group_info import GroupInfo
|
||||
from utils.image_utils import BuildMat
|
||||
from utils.manager import plugins2settings_manager
|
||||
from utils.message_builder import image
|
||||
|
||||
try:
|
||||
import ujson as json
|
||||
@@ -160,8 +162,8 @@ async def _(bot: Bot, event: MessageEvent, cmd: Tuple[str, ...] = Command(), arg
|
||||
day_index = data["day_index"]
|
||||
data = data[arg][key]
|
||||
if _type == "group":
|
||||
name = await GroupInfo.get_group_info(event.group_id)
|
||||
name = name.group_name if name else str(event.group_id)
|
||||
group = await GroupInfo.filter(group_id=event.group_id).first()
|
||||
name = name.group_name if group else str(event.group_id)
|
||||
else:
|
||||
name = event.sender.card or event.sender.nickname
|
||||
img = await generate_statistics_img(data, arg, name, plugin, day_index)
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
from configs.path_config import DATA_PATH
|
||||
from datetime import datetime
|
||||
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, MessageEvent
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.message import run_postprocessor
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, MessageEvent
|
||||
from datetime import datetime
|
||||
from nonebot.typing import Optional, T_State
|
||||
|
||||
from configs.path_config import DATA_PATH
|
||||
from utils.manager import plugins2settings_manager
|
||||
from utils.utils import scheduler
|
||||
from nonebot.typing import Optional
|
||||
|
||||
from ._model import Statistics
|
||||
|
||||
try:
|
||||
@@ -99,10 +101,11 @@ async def _(
|
||||
and matcher.priority not in [1, 999]
|
||||
and matcher.plugin_name not in ["update_info", "statistics_handle"]
|
||||
):
|
||||
await Statistics.add_statistic(
|
||||
event.user_id,
|
||||
event.group_id if isinstance(event, GroupMessageEvent) else None,
|
||||
matcher.plugin_name,
|
||||
await Statistics.create(
|
||||
user_qq=event.user_id,
|
||||
group_id=getattr(event, "group_id", None),
|
||||
plugin_name=matcher.plugin_name,
|
||||
create_time=datetime.now(),
|
||||
)
|
||||
module = matcher.plugin_name
|
||||
day_index = _prefix_count_dict["day_index"]
|
||||
|
||||
+28
-20
@@ -1,20 +1,21 @@
|
||||
from nonebot import on_command
|
||||
from PIL import Image, ImageFilter
|
||||
from utils.message_builder import image
|
||||
from configs.path_config import TEMP_PATH, IMAGE_PATH
|
||||
from services.log import logger
|
||||
from nonebot.rule import to_me
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent, Message
|
||||
from nonebot.typing import T_State
|
||||
from utils.utils import get_message_img, is_number
|
||||
from nonebot.params import CommandArg, Arg, ArgStr, Depends
|
||||
from utils.image_utils import BuildImage, pic2b64
|
||||
from configs.config import NICKNAME
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from typing import Union
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message, MessageEvent
|
||||
from nonebot.params import Arg, ArgStr, CommandArg, Depends
|
||||
from nonebot.rule import to_me
|
||||
from nonebot.typing import T_State
|
||||
from PIL import Image, ImageFilter
|
||||
|
||||
from configs.config import NICKNAME
|
||||
from configs.path_config import IMAGE_PATH, TEMP_PATH
|
||||
from services.log import logger
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.image_utils import BuildImage, pic2b64
|
||||
from utils.message_builder import image
|
||||
from utils.utils import get_message_img, is_number
|
||||
|
||||
__zx_plugin_name__ = "各种图片简易操作"
|
||||
__plugin_usage__ = """
|
||||
@@ -88,9 +89,7 @@ update_img_help.save(IMAGE_PATH / "update_img_help.png")
|
||||
|
||||
|
||||
def parse_key(key: str):
|
||||
async def _key_parser(
|
||||
state: T_State, inp: Union[Message, str] = Arg(key)
|
||||
):
|
||||
async def _key_parser(state: T_State, inp: Union[Message, str] = Arg(key)):
|
||||
if key != "img_list" and isinstance(inp, Message):
|
||||
inp = inp.extract_plain_text().strip()
|
||||
if inp in ["取消", "算了"]:
|
||||
@@ -132,6 +131,7 @@ def parse_key(key: str):
|
||||
if not get_message_img(inp):
|
||||
await update_img.reject_arg("img_list", "没图?没图?没图?来图速来!")
|
||||
state[key] = inp
|
||||
|
||||
return _key_parser
|
||||
|
||||
|
||||
@@ -167,10 +167,18 @@ async def _(event: MessageEvent, state: T_State, arg: Message = CommandArg()):
|
||||
state["img_list"] = event.message
|
||||
|
||||
|
||||
@update_img.got("method", prompt=f"要使用图片的什么操作呢?{method_str}", parameterless=[Depends(parse_key("method"))])
|
||||
@update_img.got("x", prompt="[宽度? 比率? 旋转角度? 底色?]", parameterless=[Depends(parse_key("x"))])
|
||||
@update_img.got(
|
||||
"method",
|
||||
prompt=f"要使用图片的什么操作呢?{method_str}",
|
||||
parameterless=[Depends(parse_key("method"))],
|
||||
)
|
||||
@update_img.got(
|
||||
"x", prompt="[宽度? 比率? 旋转角度? 底色?]", parameterless=[Depends(parse_key("x"))]
|
||||
)
|
||||
@update_img.got("y", prompt="[长度? 0 0 底色?]", parameterless=[Depends(parse_key("y"))])
|
||||
@update_img.got("img_list", prompt="图呢图呢图呢图呢?GKD!", parameterless=[Depends(parse_key("img_list"))])
|
||||
@update_img.got(
|
||||
"img_list", prompt="图呢图呢图呢图呢?GKD!", parameterless=[Depends(parse_key("img_list"))]
|
||||
)
|
||||
async def _(
|
||||
event: MessageEvent,
|
||||
state: T_State,
|
||||
@@ -285,7 +293,7 @@ async def _(
|
||||
img[i, j] = color
|
||||
cv2.imwrite(TEMP_PATH / f"{event.user_id}_{k}_ok_update.png", img)
|
||||
for i in range(index):
|
||||
result += image(f"{event.user_id}_{i}_ok_update.png", "temp")
|
||||
result += image(TEMP_PATH / f"{event.user_id}_{i}_ok_update.png")
|
||||
if is_number(method):
|
||||
method = method_list[int(method) - 1]
|
||||
logger.info(
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
from utils.manager import requests_manager
|
||||
from ..auth import token_to_user, Depends, User
|
||||
from utils.utils import get_bot
|
||||
from models.group_info import GroupInfo
|
||||
from utils.manager import requests_manager
|
||||
from utils.utils import get_bot
|
||||
|
||||
from ..auth import Depends, User, token_to_user
|
||||
from ..config import *
|
||||
|
||||
|
||||
@@ -39,18 +40,21 @@ async def _(parma: RequestParma, user: User = Depends(token_to_user)) -> Result:
|
||||
if bot := get_bot():
|
||||
if parma.handle == "approve":
|
||||
if parma.type == "group":
|
||||
rid = requests_manager.get_group_id(parma.id)
|
||||
if await GroupInfo.get_group_info(rid):
|
||||
await GroupInfo.set_group_flag(rid, 1)
|
||||
else:
|
||||
group_info = await bot.get_group_info(group_id=rid)
|
||||
await GroupInfo.add_group_info(
|
||||
rid,
|
||||
group_info["group_name"],
|
||||
group_info["max_member_count"],
|
||||
group_info["member_count"],
|
||||
1,
|
||||
)
|
||||
if rid := requests_manager.get_group_id(parma.id):
|
||||
# await GroupInfo.update_or_create(defaults={"group_flag": 1}, )
|
||||
if group := await GroupInfo.filter(group_id=rid).first():
|
||||
await group.update_or_create(group_flag=1)
|
||||
else:
|
||||
group_info = await bot.get_group_info(group_id=rid)
|
||||
await GroupInfo.update_or_create(
|
||||
group_id=group_info["group_id"],
|
||||
defaults={
|
||||
"group_name": group_info["group_name"],
|
||||
"max_member_count": group_info["max_member_count"],
|
||||
"member_count": group_info["member_count"],
|
||||
"group_flag": 1,
|
||||
},
|
||||
)
|
||||
flag = await requests_manager.approve(bot, parma.id, parma.type)
|
||||
elif parma.handle == "refuse":
|
||||
flag = await requests_manager.refused(bot, parma.id, parma.type)
|
||||
|
||||
+130
-162
@@ -1,47 +1,63 @@
|
||||
import random
|
||||
import re
|
||||
import time
|
||||
from nonebot.internal.adapter.template import MessageTemplate
|
||||
from datetime import datetime
|
||||
from typing import Any, List, Optional, Tuple, Union
|
||||
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
GroupMessageEvent,
|
||||
Message,
|
||||
MessageEvent,
|
||||
GroupMessageEvent,
|
||||
MessageSegment,
|
||||
)
|
||||
from services.db_context import db
|
||||
from typing import Optional, List, Union, Tuple, Any
|
||||
from datetime import datetime
|
||||
from configs.path_config import DATA_PATH
|
||||
import random
|
||||
from ._config import int2type
|
||||
from utils.image_utils import get_img_hash
|
||||
from utils.http_utils import AsyncHttpx
|
||||
import re
|
||||
from nonebot.internal.adapter.template import MessageTemplate
|
||||
from tortoise import Tortoise, fields
|
||||
from tortoise.expressions import Q, RawSQL
|
||||
|
||||
from utils.message_builder import image, face, at
|
||||
from configs.path_config import DATA_PATH
|
||||
from services.db_context import Model
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.image_utils import get_img_hash
|
||||
from utils.message_builder import at, face, image
|
||||
from utils.utils import get_message_img
|
||||
|
||||
from ._config import int2type
|
||||
|
||||
path = DATA_PATH / "word_bank"
|
||||
|
||||
|
||||
class WordBank(db.Model):
|
||||
__tablename__ = "word_bank2"
|
||||
class WordBank(Model):
|
||||
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||
group_id = db.Column(db.Integer())
|
||||
word_scope = db.Column(
|
||||
db.Integer(), nullable=False, default=0
|
||||
) # 生效范围 0: 全局 1: 群聊 2: 私聊
|
||||
word_type = db.Column(
|
||||
db.Integer(), nullable=False, default=0
|
||||
) # 词条类型 0: 完全匹配 1: 模糊 2: 正则 3: 图片
|
||||
status = db.Column(db.Boolean(), nullable=False, default=True) # 词条状态
|
||||
problem = db.Column(db.String(), nullable=False) # 问题,为图片时使用图片hash
|
||||
answer = db.Column(db.String(), nullable=False) # 回答
|
||||
placeholder = db.Column(db.String()) # 占位符
|
||||
image_path = db.Column(db.String()) # 使用图片作为问题时图片存储的路径
|
||||
to_me = db.Column(db.String()) # 使用图片作为问题时图片存储的路径
|
||||
create_time = db.Column(db.DateTime(), nullable=False)
|
||||
update_time = db.Column(db.DateTime(), nullable=False)
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
"""用户id"""
|
||||
group_id = fields.BigIntField(null=True)
|
||||
"""群聊id"""
|
||||
word_scope = fields.IntField(default=0)
|
||||
"""生效范围 0: 全局 1: 群聊 2: 私聊"""
|
||||
word_type = fields.IntField(default=0)
|
||||
"""词条类型 0: 完全匹配 1: 模糊 2: 正则 3: 图片"""
|
||||
status = fields.BooleanField()
|
||||
"""词条状态"""
|
||||
problem = fields.TextField()
|
||||
"""问题,为图片时使用图片hash"""
|
||||
answer = fields.TextField()
|
||||
"""回答"""
|
||||
placeholder = fields.TextField(null=True)
|
||||
"""占位符"""
|
||||
image_path = fields.TextField(null=True)
|
||||
"""使用图片作为问题时图片存储的路径"""
|
||||
to_me = fields.CharField(255, null=True)
|
||||
"""昵称开头时存储的昵称"""
|
||||
create_time = fields.DatetimeField(auto_now=True)
|
||||
"""创建时间"""
|
||||
update_time = fields.DatetimeField(auto_now_add=True)
|
||||
"""更新时间"""
|
||||
|
||||
class Meta:
|
||||
table = "word_bank2"
|
||||
table_description = "词条数据库"
|
||||
|
||||
@classmethod
|
||||
async def exists(
|
||||
@@ -64,18 +80,18 @@ class WordBank(db.Model):
|
||||
:param word_scope: 词条范围
|
||||
:param word_type: 词条类型
|
||||
"""
|
||||
query = cls.query.where(cls.problem == problem)
|
||||
query = cls.filter(problem=problem)
|
||||
if user_id:
|
||||
query = query.where(cls.user_qq == user_id)
|
||||
query = query.filter(user_qq=user_id)
|
||||
if group_id:
|
||||
query = query.where(cls.group_id == group_id)
|
||||
query = query.filter(group_id=group_id)
|
||||
if answer:
|
||||
query = query.where(cls.answer == answer)
|
||||
if word_type:
|
||||
query = query.where(cls.word_type == word_type)
|
||||
if word_scope:
|
||||
query = query.where(cls.word_scope == word_scope)
|
||||
return bool(await query.gino.first())
|
||||
query = query.filter(answer=answer)
|
||||
if word_type is not None:
|
||||
query = query.filter(word_type=word_type)
|
||||
if word_scope is not None:
|
||||
query = query.filter(word_scope=word_scope)
|
||||
return bool(await query.first())
|
||||
|
||||
@classmethod
|
||||
async def add_problem_answer(
|
||||
@@ -86,7 +102,7 @@ class WordBank(db.Model):
|
||||
word_type: int,
|
||||
problem: Union[str, Message],
|
||||
answer: Union[str, Message],
|
||||
to_me_nickname: str = None
|
||||
to_me_nickname: Optional[str] = None,
|
||||
):
|
||||
"""
|
||||
说明:
|
||||
@@ -112,7 +128,9 @@ class WordBank(db.Model):
|
||||
problem = str(get_img_hash(_file))
|
||||
image_path = f"problem/{group_id}/{user_id}_{int(time.time())}.jpg"
|
||||
answer, _list = await cls._answer2format(answer, user_id, group_id)
|
||||
if not await cls.exists(user_id, group_id, problem, answer, word_scope, word_type):
|
||||
if not await cls.exists(
|
||||
user_id, group_id, problem, answer, word_scope, word_type
|
||||
):
|
||||
await cls.create(
|
||||
user_qq=user_id,
|
||||
group_id=group_id,
|
||||
@@ -125,7 +143,7 @@ class WordBank(db.Model):
|
||||
placeholder=",".join(_list),
|
||||
create_time=datetime.now().replace(microsecond=0),
|
||||
update_time=datetime.now().replace(microsecond=0),
|
||||
to_me=to_me_nickname
|
||||
to_me=to_me_nickname,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -152,7 +170,7 @@ class WordBank(db.Model):
|
||||
text += seg.data["text"]
|
||||
elif seg.type == "face":
|
||||
text += f"[face:placeholder_{index}]"
|
||||
_list.append(seg.data['id'])
|
||||
_list.append(seg.data["id"])
|
||||
elif seg.type == "at":
|
||||
text += f"[at:placeholder_{index}]"
|
||||
_list.append(seg.data["qq"])
|
||||
@@ -187,12 +205,12 @@ class WordBank(db.Model):
|
||||
if query:
|
||||
answer = query.answer
|
||||
else:
|
||||
query = await cls.query.where(
|
||||
(cls.problem == problem)
|
||||
& (cls.user_qq == user_id)
|
||||
& (cls.group_id == group_id)
|
||||
& (cls.answer == answer)
|
||||
).gino.first()
|
||||
query = await cls.get_or_none(
|
||||
problem=problem,
|
||||
user_qq=user_id,
|
||||
group_id=group_id,
|
||||
answer=answer,
|
||||
)
|
||||
if query and query.placeholder:
|
||||
type_list = re.findall(rf"\[(.*?):placeholder_.*?]", answer)
|
||||
temp_answer = re.sub(rf"\[(.*?):placeholder_.*?]", "{}", answer)
|
||||
@@ -208,7 +226,7 @@ class WordBank(db.Model):
|
||||
return answer
|
||||
|
||||
@classmethod
|
||||
async def check(
|
||||
async def check_problem(
|
||||
cls,
|
||||
event: MessageEvent,
|
||||
problem: str,
|
||||
@@ -224,60 +242,35 @@ class WordBank(db.Model):
|
||||
:param word_scope: 词条范围
|
||||
:param word_type: 词条类型
|
||||
"""
|
||||
query = cls.query
|
||||
sql_text = "SELECT * FROM public.word_bank2 where 1 = 1"
|
||||
# 救命!!没找到gino的正则表达式方法,暂时使用sql语句
|
||||
query = cls
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
if word_scope:
|
||||
query = query.where(cls.word_scope == word_scope)
|
||||
sql_text += f" and word_scope = {word_scope}"
|
||||
query = query.filter(word_scope=word_scope)
|
||||
else:
|
||||
query = query.where(
|
||||
(cls.group_id == event.group_id) | (cls.word_scope == 0)
|
||||
)
|
||||
sql_text += f" and (group_id = {event.group_id} or word_scope = 0)"
|
||||
query = query.filter(Q(group_id=event.group_id) | Q(word_scope=0))
|
||||
else:
|
||||
query = query.where((cls.word_scope == 2) | (cls.word_scope == 0))
|
||||
sql_text += f" and (word_scope = 2 or word_scope = 0)"
|
||||
query = query.filter(Q(cword_scope=2) | Q(word_scope=0))
|
||||
if word_type:
|
||||
query = query.where(cls.word_scope == word_type)
|
||||
sql_text += f" and word_scope = {word_scope}"
|
||||
query = query.filter(word_scope=word_type)
|
||||
# 完全匹配
|
||||
if await query.where(
|
||||
((cls.word_type == 0) | (cls.word_type == 3)) & (cls.problem == problem)
|
||||
).gino.first():
|
||||
return query.where(
|
||||
((cls.word_type == 0) | (cls.word_type == 3)) & (cls.problem == problem)
|
||||
)
|
||||
if data_list := await query.filter(
|
||||
Q(Q(word_type=0) | Q(word_type=3)), Q(problem=problem)
|
||||
).all():
|
||||
return data_list
|
||||
db = Tortoise.get_connection("default")
|
||||
# 模糊匹配
|
||||
if await db.first(
|
||||
db.text(
|
||||
sql_text
|
||||
+ f" and word_type = 1 and :problem like '%' || problem || '%';"
|
||||
),
|
||||
problem=problem,
|
||||
):
|
||||
return (
|
||||
sql_text
|
||||
+ f" and word_type = 1 and :problem like '%' || problem || '%';"
|
||||
)
|
||||
# 正则匹配
|
||||
if await db.first(
|
||||
db.text(
|
||||
sql_text
|
||||
+ f" and word_type = 2 and word_scope != 999 and :problem ~ problem;"
|
||||
),
|
||||
problem=problem,
|
||||
):
|
||||
return (
|
||||
sql_text
|
||||
+ f" and word_type = 2 and word_scope != 999 and :problem ~ problem;"
|
||||
)
|
||||
# if await db.first(
|
||||
# db.text(sql_text + f" and word_type = 1 and word_scope != 999 and '{problem}' ~ problem;")
|
||||
# ):
|
||||
# return sql_text + f" and word_type = 1 and word_scope != 999 and '{problem}' ~ problem;"
|
||||
# return None
|
||||
sql = query.filter(word_type=1).sql() + " and POSITION(problem in $1) > 0"
|
||||
data_list = await db.execute_query_dict(sql, [problem])
|
||||
if data_list:
|
||||
return [cls(**data) for data in data_list]
|
||||
# 正则
|
||||
sql = (
|
||||
query.filter(word_type=2, word_scope__not=999).sql() + " and $1 ~ problem;"
|
||||
)
|
||||
data_list = await db.execute_query_dict(sql, [problem])
|
||||
if data_list:
|
||||
return [cls(**data) for data in data_list]
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
async def get_answer(
|
||||
@@ -296,26 +289,16 @@ class WordBank(db.Model):
|
||||
:param word_scope: 词条范围
|
||||
:param word_type: 词条类型
|
||||
"""
|
||||
query = await cls.check(event, problem, word_scope, word_type)
|
||||
if query is not None:
|
||||
if isinstance(query, str):
|
||||
answer_list = await db.all(db.text(query), problem=problem)
|
||||
answer = random.choice(answer_list)
|
||||
return (
|
||||
await cls._format2answer(answer[6], answer[7], answer[1], answer[2])
|
||||
if answer.placeholder
|
||||
else answer.answer
|
||||
)
|
||||
else:
|
||||
answer_list = await query.gino.all()
|
||||
answer = random.choice(answer_list)
|
||||
return (
|
||||
await cls._format2answer(
|
||||
problem, answer.answer, answer.user_qq, answer.group_id
|
||||
)
|
||||
if answer.placeholder
|
||||
else answer.answer
|
||||
data_list = await cls.check_problem(event, problem, word_scope, word_type)
|
||||
if data_list:
|
||||
answer = random.choice(data_list)
|
||||
return (
|
||||
await cls._format2answer(
|
||||
problem, answer.answer, answer.user_qq, answer.group_id
|
||||
)
|
||||
if answer.placeholder
|
||||
else answer.answer
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def get_problem_all_answer(
|
||||
@@ -336,22 +319,14 @@ class WordBank(db.Model):
|
||||
"""
|
||||
if index is not None:
|
||||
if group_id:
|
||||
problem = (await cls.query.where(cls.group_id == group_id).gino.all())[
|
||||
index
|
||||
]
|
||||
problem_ = (await cls.filter(group_id=group_id).all())[index]
|
||||
else:
|
||||
problem = (
|
||||
await cls.query.where(
|
||||
cls.word_scope == (word_scope or 0)
|
||||
).gino.all()
|
||||
)[index]
|
||||
problem = problem.problem
|
||||
answer = cls.query.where(cls.problem == problem)
|
||||
problem_ = (await cls.filter(word_scope=(word_scope or 0)).all())[index]
|
||||
problem = problem_.problem
|
||||
answer = cls.filter(problem=problem)
|
||||
if group_id:
|
||||
answer = answer.where(cls.group_id == group_id)
|
||||
return [
|
||||
await cls._format2answer("", "", 0, 0, x) for x in (await answer.gino.all())
|
||||
]
|
||||
answer = answer.filter(group_id=group_id)
|
||||
return [await cls._format2answer("", "", 0, 0, x) for x in (await answer.all())]
|
||||
|
||||
@classmethod
|
||||
async def delete_group_problem(
|
||||
@@ -373,23 +348,17 @@ class WordBank(db.Model):
|
||||
if await cls.exists(None, group_id, problem, None, word_scope):
|
||||
if index is not None:
|
||||
if group_id:
|
||||
query = await cls.query.where(
|
||||
(cls.group_id == group_id) & (cls.problem == problem)
|
||||
).gino.all()
|
||||
query = await cls.filter(group_id=group_id, problem=problem).all()
|
||||
else:
|
||||
query = await cls.query.where(
|
||||
(cls.word_scope == 0) & (cls.problem == problem)
|
||||
).gino.all()
|
||||
query = await cls.filter(word_scope=0, problem=problem).all()
|
||||
await query[index].delete()
|
||||
else:
|
||||
if group_id:
|
||||
await WordBank.delete.where(
|
||||
(cls.group_id == group_id) & (cls.problem == problem)
|
||||
).gino.status()
|
||||
await WordBank.filter(group_id=group_id, problem=problem).delete()
|
||||
else:
|
||||
await WordBank.delete.where(
|
||||
(cls.word_scope == word_scope) & (cls.problem == problem)
|
||||
).gino.status()
|
||||
await WordBank.filter(
|
||||
word_scope=word_scope, problem=problem
|
||||
).delete()
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -414,23 +383,20 @@ class WordBank(db.Model):
|
||||
"""
|
||||
if index is not None:
|
||||
if group_id:
|
||||
query = await cls.query.where(
|
||||
(cls.group_id == group_id) & (cls.problem == problem)
|
||||
).gino.all()
|
||||
query = await cls.filter(group_id=group_id, problem=problem).all()
|
||||
else:
|
||||
query = await cls.query.where(
|
||||
(cls.word_scope == word_scope) & (cls.problem == problem)
|
||||
).gino.all()
|
||||
await query[index].update(problem=replace_str).apply()
|
||||
query = await cls.filter(word_scope=word_scope, problem=problem).all()
|
||||
query[index].problem = replace_str
|
||||
await query[index].save(update_fields=["problem"])
|
||||
else:
|
||||
if group_id:
|
||||
await WordBank.update.values(problem=replace_str).where(
|
||||
(cls.group_id == group_id) & (cls.problem == problem)
|
||||
).gino.status()
|
||||
await cls.filter(group_id=group_id, problem=problem).update(
|
||||
problem=replace_str
|
||||
)
|
||||
else:
|
||||
await WordBank.update.values(problem=replace_str).where(
|
||||
(cls.word_scope == word_scope) & (cls.problem == problem)
|
||||
).gino.status()
|
||||
await cls.filter(word_scope=word_scope, problem=problem).update(
|
||||
problem=replace_str
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def get_group_all_problem(
|
||||
@@ -443,7 +409,7 @@ class WordBank(db.Model):
|
||||
:param group_id: 群号
|
||||
"""
|
||||
return cls._handle_problem(
|
||||
await cls.query.where(cls.group_id == group_id).gino.all()
|
||||
await cls.filter(group_id=group_id).all() # type: ignore
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -455,7 +421,7 @@ class WordBank(db.Model):
|
||||
:param word_scope: 词条范围
|
||||
"""
|
||||
return cls._handle_problem(
|
||||
await cls.query.where(cls.word_scope == word_scope).gino.all()
|
||||
await cls.filter(word_scope=word_scope).all() # type: ignore
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -467,13 +433,13 @@ class WordBank(db.Model):
|
||||
:param word_type: 词条类型
|
||||
"""
|
||||
return cls._handle_problem(
|
||||
await cls.query.where(cls.word_type == word_type).gino.all()
|
||||
await cls.filter(word_type=word_type).all() # type: ignore
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _handle_problem(cls, msg_list: List[Union[str, MessageSegment]]):
|
||||
def _handle_problem(cls, msg_list: List["WordBank"]):
|
||||
"""
|
||||
说明:
|
||||
说明:
|
||||
格式化处理问题
|
||||
参数:
|
||||
:param msg_list: 消息列表
|
||||
@@ -514,7 +480,9 @@ class WordBank(db.Model):
|
||||
word_scope = 0
|
||||
word_type = 0
|
||||
# 对图片做额外处理
|
||||
if not await cls.exists(user_id, group_id, problem, answer, word_scope, word_type):
|
||||
if not await cls.exists(
|
||||
user_id, group_id, problem, answer, word_scope, word_type
|
||||
):
|
||||
await cls.create(
|
||||
user_qq=user_id,
|
||||
group_id=group_id,
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
from services.db_context import db
|
||||
from typing import List
|
||||
|
||||
|
||||
class WordBank(db.Model):
|
||||
__tablename__ = "word_bank"
|
||||
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||
group_id = db.Column(db.Integer())
|
||||
search_type = db.Column(db.Integer(), nullable=False, default=0)
|
||||
problem = db.Column(db.String(), nullable=False)
|
||||
answer = db.Column(db.String(), nullable=False)
|
||||
format = db.Column(db.String())
|
||||
create_time = db.Column(db.DateTime(), nullable=False)
|
||||
update_time = db.Column(db.DateTime(), nullable=False)
|
||||
|
||||
@classmethod
|
||||
async def get_all(cls) -> List['WordBank']:
|
||||
return await cls.query.gino.all()
|
||||
|
||||
+16
-11
@@ -1,14 +1,15 @@
|
||||
import imagehash
|
||||
from PIL import Image
|
||||
from io import BytesIO
|
||||
from services.log import logger
|
||||
|
||||
import imagehash
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, Bot
|
||||
from PIL import Image
|
||||
|
||||
from utils.utils import get_message_text, get_message_img, get_message_at
|
||||
from ._model import WordBank
|
||||
from services.log import logger
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.utils import get_message_at, get_message_img, get_message_text
|
||||
|
||||
from ._model import WordBank
|
||||
|
||||
|
||||
async def check(bot: Bot, event: MessageEvent, state: T_State) -> bool:
|
||||
@@ -23,11 +24,11 @@ async def check(bot: Bot, event: MessageEvent, state: T_State) -> bool:
|
||||
except Exception as e:
|
||||
logger.warning(f"word_bank rule 获取图片失败 {type(e)}:{e}")
|
||||
if at:
|
||||
temp = ''
|
||||
temp = ""
|
||||
for seg in event.message:
|
||||
if seg.type == 'at':
|
||||
if seg.type == "at":
|
||||
temp += f"[at:{seg.data['qq']}]"
|
||||
elif seg.type == 'text':
|
||||
elif seg.type == "text":
|
||||
temp += seg.data["text"]
|
||||
problem = temp
|
||||
if event.to_me and bot.config.nickname:
|
||||
@@ -35,9 +36,13 @@ async def check(bot: Bot, event: MessageEvent, state: T_State) -> bool:
|
||||
problem = f"[at:{bot.self_id}]" + problem
|
||||
else:
|
||||
if problem and bot.config.nickname:
|
||||
nickname = [nk for nk in bot.config.nickname if str(event.original_message).startswith(nk)]
|
||||
nickname = [
|
||||
nk
|
||||
for nk in bot.config.nickname
|
||||
if str(event.original_message).startswith(nk)
|
||||
]
|
||||
problem = nickname[0] + problem if nickname else problem
|
||||
if problem and (await WordBank.check(event, problem) is not None):
|
||||
if problem and (await WordBank.check_problem(event, problem) is not None):
|
||||
state["problem"] = problem
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -1,21 +1,29 @@
|
||||
import re
|
||||
from typing import Tuple, Any, Optional
|
||||
from typing import Any, Optional, Tuple
|
||||
|
||||
from nonebot import on_command, on_regex
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
Bot,
|
||||
GroupMessageEvent,
|
||||
Message,
|
||||
MessageEvent,
|
||||
PrivateMessageEvent,
|
||||
unescape,
|
||||
)
|
||||
from nonebot.exception import FinishedException
|
||||
from nonebot.internal.params import Arg, ArgStr
|
||||
from nonebot.params import Command, CommandArg, RegexGroup
|
||||
from nonebot.typing import T_State
|
||||
|
||||
from utils.utils import get_message_at, is_number, get_message_img
|
||||
from nonebot.params import CommandArg, RegexGroup, Command
|
||||
from nonebot.exception import FinishedException
|
||||
from services.log import logger
|
||||
from configs.path_config import DATA_PATH
|
||||
from utils.message_builder import custom_forward_msg
|
||||
from ._model import WordBank
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message, MessageEvent, PrivateMessageEvent, unescape
|
||||
from nonebot import on_command, on_regex
|
||||
from configs.config import Config
|
||||
from ._data_source import delete_word, update_word, show_word
|
||||
from configs.path_config import DATA_PATH
|
||||
from services.log import logger
|
||||
from utils.message_builder import custom_forward_msg
|
||||
from utils.utils import get_message_at, get_message_img, is_number
|
||||
|
||||
from ._config import scope2int, type2int
|
||||
from ._data_source import delete_word, show_word, update_word
|
||||
from ._model import WordBank
|
||||
|
||||
__zx_plugin_name__ = "词库问答 [Admin]"
|
||||
__plugin_usage__ = r"""
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
import asyncio
|
||||
import os
|
||||
import random
|
||||
import jieba.analyse
|
||||
import re
|
||||
from typing import List
|
||||
from PIL import Image as IMG
|
||||
import jieba
|
||||
from emoji import replace_emoji # type: ignore
|
||||
from wordcloud import WordCloud, ImageColorGenerator
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from io import BytesIO
|
||||
from configs.path_config import IMAGE_PATH, FONT_PATH
|
||||
from typing import List
|
||||
|
||||
import jieba
|
||||
import jieba.analyse
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from emoji import replace_emoji # type: ignore
|
||||
from PIL import Image as IMG
|
||||
from wordcloud import ImageColorGenerator, WordCloud
|
||||
|
||||
from configs.config import Config
|
||||
from configs.path_config import FONT_PATH, IMAGE_PATH
|
||||
from models.chat_history import ChatHistory
|
||||
from services import logger
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from models.chat_history import ChatHistory
|
||||
from configs.config import Config
|
||||
|
||||
|
||||
async def pre_precess(msg: List[str], config) -> str:
|
||||
@@ -117,10 +119,8 @@ async def draw_word_cloud(messages, config):
|
||||
|
||||
|
||||
async def get_list_msg(user_id, group_id, days):
|
||||
messages_list = (
|
||||
await ChatHistory()
|
||||
._get_msg(uid=user_id, gid=group_id, type_="group", days=days)
|
||||
.gino.all()
|
||||
messages_list = await ChatHistory().get_message(
|
||||
uid=user_id, gid=group_id, type_="group", days=days
|
||||
)
|
||||
if messages_list:
|
||||
messages = [i.text for i in messages_list]
|
||||
|
||||
Reference in New Issue
Block a user