from typing import Optional import pytz from nonebot import require from liteyuki.utils.data import LiteModel from liteyuki.utils.data_manager import User, user_db from liteyuki.utils.language import Language, get_all_lang, get_user_lang from liteyuki.utils.ly_typing import T_Bot, T_MessageEvent from liteyuki.utils.message import Markdown as md from .const import representative_timezones_list require("nonebot_plugin_alconna") from nonebot_plugin_alconna import Alconna, Args, Arparma, Subcommand, on_alconna profile_alc = on_alconna( Alconna( "profile", Subcommand( "set", Args["key", str]["value", str, None], alias=["s", "设置"], ), Subcommand( "get", Args["key", str], alias=["g", "查询"], ), ), aliases={"用户信息"} ) # json储存 class Profile(LiteModel): lang: str = "zh-CN" nickname: str = "" timezone: str = "Asia/Shanghai" location: str = "" @profile_alc.handle() async def _(result: Arparma, event: T_MessageEvent, bot: T_Bot): user: User = user_db.first(User(), "user_id = ?", event.user_id, default=User(user_id=str(event.user_id))) ulang = get_user_lang(str(event.user_id)) if result.subcommands.get("set"): if result.subcommands["set"].args.get("value"): # 对合法性进行校验后设置 r = set_profile(result.args["key"], result.args["value"]) if r: user.profile[result.args["key"]] = result.args["value"] user_db.upsert(user) # 数据库保存 await profile_alc.finish( ulang.get( "user.profile.set_success", ATTR=ulang.get(f"user.profile.{result.args['key']}"), VALUE=result.args["value"] ) ) else: await profile_alc.finish(ulang.get("user.profile.set_failed", ATTR=ulang.get(f"user.profile.{result.args['key']}"))) else: # 未输入值,尝试呼出菜单 menu = get_profile_menu(result.args["key"], ulang) if menu: await md.send_md(menu, bot, event=event) else: await profile_alc.finish(ulang.get("user.profile.input_value", ATTR=ulang.get(f"user.profile.{result.args['key']}"))) user.profile[result.args["key"]] = result.args["value"] elif result.subcommands.get("get"): if result.args["key"] in user.profile: await profile_alc.finish(user.profile[result.args["key"]]) else: await profile_alc.finish("无此键值") else: profile = Profile(**user.profile) for k, v in user.profile.items(): profile.__setattr__(k, v) reply = f"# {ulang.get('user.profile.info')}\n***\n" hidden_attr = ["id", "TABLE_NAME"] enter_attr = ["lang", "timezone"] for key in sorted(profile.dict().keys()): if key in hidden_attr: continue val = profile.dict()[key] key_text = ulang.get(f"user.profile.{key}") btn_set = md.button(ulang.get("user.profile.edit"), f"profile set {key}", enter=True if key in enter_attr else False) reply += (f"\n**{key_text}** **{val}**\n" f"\n> {ulang.get(f'user.profile.{key}.desc')}" f"\n> {btn_set} \n\n***\n") await md.send_md(reply, bot, event=event) def get_profile_menu(key: str, ulang: Language) -> Optional[str]: """获取属性的markdown菜单 Args: ulang: 用户语言 key: 属性键 Returns: """ setting_name = ulang.get(f"user.profile.{key}") no_menu = ["id", "nickname", "location"] if key in no_menu: return None reply = f"**{setting_name} {ulang.get('user.profile.settings')}**\n***\n" if key == "lang": for lang_code, lang_name in get_all_lang().items(): btn_set = md.button(ulang.get("user.profile.set"), f"profile set {key} {lang_code}") reply += f"\n{btn_set} | **{lang_name}** - {lang_code}\n***\n" elif key == "timezone": for tz in representative_timezones_list: btn_set_tz = md.button(tz, f"profile set {key} {tz}") reply += f"{btn_set_tz}\n" return reply def set_profile(key: str, value: str) -> bool: """设置属性,使用if分支对每一个合法性进行检查 Args: key: value: Returns: 是否成功设置,输入合法性不通过返回False """ if key == "lang": if value in get_all_lang(): return True elif key == "timezone": if value in pytz.all_timezones: return True elif key == "nickname": return True