diff --git a/modules/apihelper/gacha_log.py b/modules/apihelper/gacha_log.py index 3b3df4e..ae63f4e 100644 --- a/modules/apihelper/gacha_log.py +++ b/modules/apihelper/gacha_log.py @@ -160,7 +160,7 @@ class GachaLog: """ data, state = await GachaLog.load_history_info(user_id, uid) if not state: - return False, f'UID{uid} 还没有导入任何抽卡记录数据。', None + return False, f'派蒙还没有找到你导入的任何抽卡记录哦,快试试导入吧~', None save_path = GACHA_LOG_PATH / f'{user_id}-{uid}-uigf.json' uigf_dict = { 'info': { @@ -456,12 +456,12 @@ class GachaLog: """ gacha_log, status = await GachaLog.load_history_info(str(user_id), str(client.uid)) if not status: - return "获取数据失败,未找到抽卡记录" + return "派蒙没有找到你的抽卡记录,快来私聊派蒙导入吧~" pool_name = GACHA_TYPE_LIST[pool] data = gacha_log.item_list[pool_name] total = len(data) if total == 0: - return "获取数据失败,未找到抽卡记录" + return "派蒙没有找到这个卡池的抽卡记录,快来私聊派蒙导入吧~" all_five, no_five_star = await GachaLog.get_all_5_star_items(data, assets, pool_name) all_four, no_four_star = await GachaLog.get_all_4_star_items(data, assets) summon_data = None @@ -498,12 +498,12 @@ class GachaLog: """ gacha_log, status = await GachaLog.load_history_info(str(user_id), str(client.uid)) if not status: - return "获取数据失败,未找到抽卡记录" + return "派蒙没有找到你的抽卡记录,快来私聊派蒙导入吧~" pool_name = GACHA_TYPE_LIST[pool] data = gacha_log.item_list[pool_name] total = len(data) if total == 0: - return "获取数据失败,未找到抽卡记录" + return "派蒙没有找到这个卡池的抽卡记录,快来私聊派蒙导入吧~" all_five, _ = await GachaLog.get_all_5_star_items(data, assets, pool_name) all_four, _ = await GachaLog.get_all_4_star_items(data, assets) pool_data = [] diff --git a/plugins/genshin/gacha/gacha_log.py b/plugins/genshin/gacha/gacha_log.py index 152ce90..0432b43 100644 --- a/plugins/genshin/gacha/gacha_log.py +++ b/plugins/genshin/gacha/gacha_log.py @@ -1,10 +1,9 @@ import json -import os -from io import BytesIO +from io import BytesIO from genshin.models import BannerType -from pyppeteer import launch -from telegram import Update, User + +from telegram import Update, User, Message, Document from telegram.constants import ChatAction from telegram.ext import CallbackContext, CommandHandler, MessageHandler, filters, ConversationHandler @@ -13,6 +12,7 @@ from core.baseplugin import BasePlugin from core.cookies.error import CookiesNotFoundError from core.plugin import Plugin, handler, conversation from core.template import TemplateService +from core.user import UserService from core.user.error import UserNotFoundError from modules.apihelper.gacha_log import GachaLog as GachaLogService from utils.bot import get_all_args @@ -27,13 +27,10 @@ INPUT_URL, INPUT_FILE = 10100, 10101 class GachaLog(Plugin.Conversation, BasePlugin.Conversation): """ 抽卡记录导入/导出/分析""" - def __init__(self, template_service: TemplateService = None, assets: AssetsService = None): + def __init__(self, template_service: TemplateService = None, user_service: UserService = None, + assets: AssetsService = None): self.template_service = template_service - self.browser: launch = None - self.current_dir = os.getcwd() - self.resources_dir = os.path.join(self.current_dir, "resources") - self.character_gacha_card = {} - self.user_time = {} + self.user_service = user_service self.assets_service = assets @staticmethod @@ -57,66 +54,22 @@ class GachaLog(Plugin.Conversation, BasePlugin.Conversation): """ try: logger.debug("尝试获取已绑定的原神账号") - client = await get_genshin_client(user.id) + client = await get_genshin_client(user.id, need_cookie=False) if authkey: return await GachaLogService.get_gacha_log_data(user.id, client, authkey) if data: return await GachaLogService.import_gacha_log_data(user.id, data) - except (UserNotFoundError, CookiesNotFoundError): + except UserNotFoundError: logger.info(f"未查询到用户({user.full_name} {user.id}) 所绑定的账号信息") - return "未查询到您所绑定的账号信息,请先私聊派蒙绑定账号" + return "派蒙没有找到您所绑定的账号信息,请先私聊派蒙绑定账号" - @conversation.entry_point - @handler(CommandHandler, command="gacha_log_refresh", filters=filters.ChatType.PRIVATE, block=True) - @handler(MessageHandler, filters=filters.Regex("^更新抽卡记录(.*)") & filters.ChatType.PRIVATE, block=True) - @restricts() - @error_callable - async def command_start(self, update: Update, context: CallbackContext) -> int: - message = update.effective_message - user = update.effective_user - args = get_all_args(context) - if not args: - await message.reply_text("请发送从游戏中获取到的抽卡记录链接\n\n" - "获取抽卡记录链接教程:https://paimon.moe/wish/import") - return INPUT_URL - authkey = self.from_url_get_authkey(args[0]) - data = await self._refresh_user_data(user, authkey=authkey) - await message.reply_text(data) - - @conversation.state(state=INPUT_URL) - @handler.message(filters=filters.TEXT & ~filters.COMMAND, - block=True) - @restricts() - @error_callable - async def import_data_from_url(self, update: Update, _: CallbackContext) -> int: - message = update.effective_message - user = update.effective_user - authkey = self.from_url_get_authkey(message.text) - reply = await message.reply_text("正在从米哈游服务器获取数据,请稍后") - text = await self._refresh_user_data(user, authkey=authkey) - await reply.edit_text(text) - return ConversationHandler.END - - @handler(CommandHandler, command="gacha_log_import", filters=filters.ChatType.PRIVATE, block=True) - @handler(MessageHandler, filters=filters.Regex("^导入抽卡记录(.*)") & filters.ChatType.PRIVATE, block=True) - @restricts() - @error_callable - async def command_start_import(self, update: Update, _: CallbackContext) -> None: - message = update.effective_message - user = update.effective_user - if message.reply_to_message: - document = message.reply_to_message.document - else: - document = message.document + async def import_from_file(self, user: User, message: Message, document: Document = None) -> None: if not document: - await message.reply_text("请回复符合 UIGF 标准的抽卡记录文件") - return + document = message.document if not document.file_name.endswith(".json"): await message.reply_text("文件格式错误,请发送符合 UIGF 标准的抽卡记录文件") - return if document.file_size > 50 * 1024 * 1024: await message.reply_text("文件过大,请发送小于 50MB 的文件") - return try: data = BytesIO() await (await document.get_file()).download(out=data) @@ -127,37 +80,80 @@ class GachaLog(Plugin.Conversation, BasePlugin.Conversation): logger.error(f"文件解析失败:{repr(exc)}") await message.reply_text("文件解析失败,请检查文件是否符合 UIGF 标准") return + await message.reply_chat_action(ChatAction.TYPING) reply = await message.reply_text("文件解析成功,正在导入数据") try: text = await self._refresh_user_data(user, data=data) except Exception as exc: logger.error(f"文件解析失败:{repr(exc)}") - await reply.edit_text("文件解析失败,请检查文件是否符合 UIGF 标准") - return + text = "文件解析失败,请检查文件是否符合 UIGF 标准" await reply.edit_text(text) - return - @handler(CommandHandler, command="gacha_log_export", filters=filters.ChatType.PRIVATE, block=True) - @handler(MessageHandler, filters=filters.Regex("^导出抽卡记录(.*)") & filters.ChatType.PRIVATE, block=True) + @conversation.entry_point + @handler(CommandHandler, command="gacha_log_import", filters=filters.ChatType.PRIVATE, block=False) + @handler(MessageHandler, filters=filters.Regex("^导入抽卡记录(.*)") & filters.ChatType.PRIVATE, block=False) + @restricts() + @error_callable + async def command_start(self, update: Update, context: CallbackContext) -> int: + message = update.effective_message + user = update.effective_user + args = get_all_args(context) + logger.info(f"用户 {user.full_name}[{user.id}] 导入抽卡记录命令请求") + if not args: + if message.document: + await self.import_from_file(user, message) + return ConversationHandler.END + elif message.reply_to_message and message.reply_to_message.document: + await self.import_from_file(user, message, document=message.reply_to_message.document) + return ConversationHandler.END + await message.reply_text("导入祈愿历史记录\n\n" + "请直接向派蒙发送从游戏中获取到的抽卡记录链接\n\n" + "获取抽卡记录链接可以参考:https://paimon.moe/wish/import", + parse_mode="html") + return INPUT_URL + authkey = self.from_url_get_authkey(args[0]) + data = await self._refresh_user_data(user, authkey=authkey) + await message.reply_text(data) + + @conversation.state(state=INPUT_URL) + @handler.message(filters=~filters.COMMAND, block=False) + @restricts() + @error_callable + async def import_data_from_message(self, update: Update, _: CallbackContext) -> int: + message = update.effective_message + user = update.effective_user + if message.document: + await self.import_from_file(user, message) + return ConversationHandler.END + authkey = self.from_url_get_authkey(message.text) + reply = await message.reply_text("小派蒙正在从米哈游服务器获取数据,请稍后") + text = await self._refresh_user_data(user, authkey=authkey) + await reply.edit_text(text) + return ConversationHandler.END + + @handler(CommandHandler, command="gacha_log_export", filters=filters.ChatType.PRIVATE, block=False) + @handler(MessageHandler, filters=filters.Regex("^导出抽卡记录(.*)") & filters.ChatType.PRIVATE, block=False) @restricts() @error_callable async def command_start_export(self, update: Update, _: CallbackContext) -> None: message = update.effective_message user = update.effective_user + logger.info(f"用户 {user.full_name}[{user.id}] 导出抽卡记录命令请求") try: - client = await get_genshin_client(user.id) + client = await get_genshin_client(user.id, need_cookie=False) + await message.reply_chat_action(ChatAction.TYPING) state, text, path = await GachaLogService.gacha_log_to_uigf(str(user.id), str(client.uid)) if state: + await message.reply_chat_action(ChatAction.UPLOAD_DOCUMENT) await message.reply_document(document=open(path, "rb+"), caption="抽卡记录导出文件") else: await message.reply_text(text) - except (UserNotFoundError, CookiesNotFoundError): + except UserNotFoundError: logger.info(f"未查询到用户({user.full_name} {user.id}) 所绑定的账号信息") await message.reply_text("未查询到您所绑定的账号信息,请先私聊派蒙绑定账号") - return - @handler(CommandHandler, command="gacha_log", block=True) - @handler(MessageHandler, filters=filters.Regex("^抽卡记录(.*)"), block=True) + @handler(CommandHandler, command="gacha_log", block=False) + @handler(MessageHandler, filters=filters.Regex("^抽卡记录(.*)"), block=False) @restricts() @error_callable async def command_start_analysis(self, update: Update, context: CallbackContext) -> None: @@ -171,22 +167,22 @@ class GachaLog(Plugin.Conversation, BasePlugin.Conversation): pool_type = BannerType.STANDARD logger.info(f"用户 {user.full_name}[{user.id}] 抽卡记录命令请求 || 参数 {pool_type.name}") try: - client = await get_genshin_client(user.id) + client = await get_genshin_client(user.id, need_cookie=False) + await message.reply_chat_action(ChatAction.TYPING) data = await GachaLogService.get_analysis(user.id, client, pool_type, self.assets_service) if isinstance(data, str): reply_message = await message.reply_text(data) + if filters.ChatType.GROUPS.filter(message): + self._add_delete_message_job(context, reply_message.chat_id, reply_message.message_id, 300) + self._add_delete_message_job(context, message.chat_id, message.message_id, 300) else: await message.reply_chat_action(ChatAction.UPLOAD_PHOTO) png_data = await self.template_service.render('genshin/gacha_log', "gacha_log.html", data, full_page=True, query_selector=".body_box") - reply_message = await message.reply_photo(png_data) - if filters.ChatType.GROUPS.filter(message): - self._add_delete_message_job(context, reply_message.chat_id, reply_message.message_id, 300) - self._add_delete_message_job(context, message.chat_id, message.message_id, 300) - except (UserNotFoundError, CookiesNotFoundError): + await message.reply_photo(png_data) + except UserNotFoundError: logger.info(f"未查询到用户({user.full_name} {user.id}) 所绑定的账号信息") await message.reply_text("未查询到您所绑定的账号信息,请先私聊派蒙绑定账号") - return @handler(CommandHandler, command="gacha_count", block=True) @handler(MessageHandler, filters=filters.Regex("^抽卡统计(.*)"), block=True) @@ -203,13 +199,16 @@ class GachaLog(Plugin.Conversation, BasePlugin.Conversation): pool_type = BannerType.STANDARD logger.info(f"用户 {user.full_name}[{user.id}] 抽卡统计命令请求 || 参数 {pool_type.name}") try: - client = await get_genshin_client(user.id) + client = await get_genshin_client(user.id, need_cookie=False) group = filters.ChatType.GROUPS.filter(message) + await message.reply_chat_action(ChatAction.TYPING) data = await GachaLogService.get_pool_analysis(user.id, client, pool_type, self.assets_service, group) if isinstance(data, str): reply_message = await message.reply_text(data) + if filters.ChatType.GROUPS.filter(message): + self._add_delete_message_job(context, reply_message.chat_id, reply_message.message_id, 300) + self._add_delete_message_job(context, message.chat_id, message.message_id, 300) else: - await message.reply_chat_action(ChatAction.UPLOAD_PHOTO) document = False if data["hasMore"] and not group: document = True @@ -217,13 +216,11 @@ class GachaLog(Plugin.Conversation, BasePlugin.Conversation): png_data = await self.template_service.render('genshin/gacha_count', "gacha_count.html", data, full_page=True, query_selector=".body_box") if document: - reply_message = await message.reply_document(png_data, filename="抽卡统计.png") + await message.reply_chat_action(ChatAction.UPLOAD_DOCUMENT) + await message.reply_document(png_data, filename="抽卡统计.png") else: - reply_message = await message.reply_photo(png_data) - if filters.ChatType.GROUPS.filter(message): - self._add_delete_message_job(context, reply_message.chat_id, reply_message.message_id, 300) - self._add_delete_message_job(context, message.chat_id, message.message_id, 300) + await message.reply_chat_action(ChatAction.UPLOAD_PHOTO) + await message.reply_photo(png_data) except (UserNotFoundError, CookiesNotFoundError): logger.info(f"未查询到用户({user.full_name} {user.id}) 所绑定的账号信息") await message.reply_text("未查询到您所绑定的账号信息,请先私聊派蒙绑定账号") - return diff --git a/plugins/system/get_chat.py b/plugins/system/get_chat.py index fb3744e..3cfe57f 100644 --- a/plugins/system/get_chat.py +++ b/plugins/system/get_chat.py @@ -9,8 +9,10 @@ from core.cookies.error import CookiesNotFoundError from core.plugin import Plugin, handler from core.user import UserService from core.user.error import UserNotFoundError +from modules.apihelper.gacha_log import GachaLog from utils.bot import get_all_args from utils.decorators.admins import bot_admins_rights_check +from utils.helpers import get_genshin_client from utils.log import logger from utils.models.base import RegionEnum @@ -46,8 +48,9 @@ class GetChat(Plugin): return text async def parse_private_chat(self, chat: Chat) -> str: - text = f"用户 ID:{chat.id}\n" \ - f"用户名称:{chat.full_name}\n" + text = f"MENTION\n" \ + f"用户 ID:{chat.id}\n" \ + f"用户名称:{chat.full_name}\n" if chat.username: text += f"用户名:@{chat.username}\n" try: @@ -58,11 +61,19 @@ class GetChat(Plugin): text += "米游社绑定:" if user_info.region == RegionEnum.HYPERION else "HOYOLAB 绑定:" temp = "Cookie 绑定" try: - await self.cookies_service.get_cookies(chat.id, user_info.region) + await get_genshin_client(chat.id) except CookiesNotFoundError: temp = "UID 绑定" + uid = user_info.genshin_uid or user_info.yuanshen_uid text += f"{temp}\n" \ - f"游戏 ID:{user_info.genshin_uid or user_info.yuanshen_uid}" + f"游戏 ID:{uid}" + gacha_log, status = await GachaLog.load_history_info(str(chat.id), str(uid)) + if status: + text += f"\n抽卡记录:" + for key, value in gacha_log.item_list.items(): + text += f"\n - {key}:{len(value)} 条" + else: + text += f"\n抽卡记录:未导入" return text @handler(CommandHandler, command="get_chat", block=False) diff --git a/utils/helpers.py b/utils/helpers.py index 45c9106..f7ef9db 100644 --- a/utils/helpers.py +++ b/utils/helpers.py @@ -84,7 +84,7 @@ async def url_to_file(url: str, return_path: bool = False) -> str: return Path(file_dir).as_uri() -async def get_genshin_client(user_id: int, region: Optional[RegionEnum] = None) -> Client: +async def get_genshin_client(user_id: int, region: Optional[RegionEnum] = None, need_cookie: bool = True) -> Client: if user_service is None: raise ServiceNotFoundError(UserService) if cookies_service is None: @@ -92,13 +92,16 @@ async def get_genshin_client(user_id: int, region: Optional[RegionEnum] = None) user = await user_service.get_user_by_id(user_id) if region is None: region = user.region - cookies = await cookies_service.get_cookies(user_id, region) + cookies = None + if need_cookie: + cookies = await cookies_service.get_cookies(user_id, region) + cookies = cookies.cookies if region == RegionEnum.HYPERION: uid = user.yuanshen_uid - client = genshin.Client(cookies=cookies.cookies, game=types.Game.GENSHIN, region=types.Region.CHINESE, uid=uid) + client = genshin.Client(cookies=cookies, game=types.Game.GENSHIN, region=types.Region.CHINESE, uid=uid) elif region == RegionEnum.HOYOLAB: uid = user.genshin_uid - client = genshin.Client(cookies=cookies.cookies, + client = genshin.Client(cookies=cookies, game=types.Game.GENSHIN, region=types.Region.OVERSEAS, lang="zh-cn", uid=uid) else: raise TypeError("region is not RegionEnum.NULL")