From 28a02aec0f2fae787aad7661e96debaef41c9acf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=B5=E5=91=B5=E3=81=A7=E3=81=99?= <51957264+shoucandanghehe@users.noreply.github.com> Date: Tue, 27 Jan 2026 05:20:41 +0800 Subject: [PATCH] :sparkles: migrate user-facing text to i18n (#581) --- nonebot_plugin_tetris_stats/games/__init__.py | 4 +- .../games/tetrio/bind.py | 3 +- .../games/tetrio/config.py | 3 +- .../games/tetrio/query/__init__.py | 12 +++- .../games/tetrio/record/blitz.py | 4 +- .../games/tetrio/record/sprint.py | 4 +- .../games/tetrio/unbind.py | 7 +- .../games/tetrio/verify.py | 11 ++-- nonebot_plugin_tetris_stats/games/top/bind.py | 3 +- .../games/top/query.py | 31 +++++---- .../games/top/unbind.py | 7 +- nonebot_plugin_tetris_stats/games/tos/bind.py | 3 +- .../games/tos/query.py | 33 ++++++---- .../i18n/.template.json | 54 +++++++++++++++- nonebot_plugin_tetris_stats/i18n/en-US.json | 50 +++++++++++++++ nonebot_plugin_tetris_stats/i18n/model.py | 64 +++++++++++++++++++ nonebot_plugin_tetris_stats/i18n/zh-CN.json | 50 +++++++++++++++ nonebot_plugin_tetris_stats/utils/lang.py | 2 +- nonebot_plugin_tetris_stats/utils/retry.py | 4 +- .../utils/templates.py | 7 +- 20 files changed, 302 insertions(+), 54 deletions(-) diff --git a/nonebot_plugin_tetris_stats/games/__init__.py b/nonebot_plugin_tetris_stats/games/__init__.py index 7f5ed9b..b3fce87 100644 --- a/nonebot_plugin_tetris_stats/games/__init__.py +++ b/nonebot_plugin_tetris_stats/games/__init__.py @@ -7,7 +7,7 @@ from nonebot.typing import T_Handler from nonebot_plugin_alconna import AlcMatches, Alconna, At, CommandMeta, on_alconna from .. import ns -from ..i18n.model import Lang +from ..i18n import Lang from ..utils.exception import MessageFormatError, NeedCatchError command: Alconna = Alconna( @@ -47,7 +47,7 @@ async def _(matcher: Matcher, matches: AlcMatches): if (matches.head_matched and matches.options != {}) or matches.main_args == {}: await matcher.finish( (f'{matches.error_info!r}\n' if matches.error_info is not None else '') - + f'输入"{matches.header_result} --help"查看帮助' + + Lang.help.usage(command=matches.header_result) ) diff --git a/nonebot_plugin_tetris_stats/games/tetrio/bind.py b/nonebot_plugin_tetris_stats/games/tetrio/bind.py index 7eb104d..6747f1f 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/bind.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/bind.py @@ -14,6 +14,7 @@ from yarl import URL from ...config.config import global_config from ...db import BindStatus, create_or_update_bind, trigger +from ...i18n import Lang from ...utils.host import get_self_netloc from ...utils.image import get_avatar from ...utils.lang import get_lang @@ -137,7 +138,7 @@ async def make_bind_image( ), name=bot_user.nick or bot_user.name or choice(list(global_config.nickname) or ['bot']), ), - prompt='io查我', + prompt=Lang.prompt.io_check(), lang=get_lang(), ), ) diff --git a/nonebot_plugin_tetris_stats/games/tetrio/config.py b/nonebot_plugin_tetris_stats/games/tetrio/config.py index 0843486..f5de700 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/config.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/config.py @@ -8,6 +8,7 @@ from nonebot_plugin_user import User from sqlalchemy import select from ...db import trigger +from ...i18n import Lang from . import alc, command from .constant import GAME_TYPE from .models import TETRIOUserConfig @@ -48,4 +49,4 @@ async def _(user: User, session: async_scoped_session, event_session: Uninfo, te else: config.query_template = template await session.commit() - await UniMessage('配置成功').finish() + await UniMessage(Lang.bind.config_success()).finish() diff --git a/nonebot_plugin_tetris_stats/games/tetrio/query/__init__.py b/nonebot_plugin_tetris_stats/games/tetrio/query/__init__.py index dbb0320..1e93e7c 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/query/__init__.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/query/__init__.py @@ -5,7 +5,7 @@ from nonebot import get_driver from nonebot.adapters import Event from nonebot.matcher import Matcher from nonebot_plugin_alconna import Args, At, Option, Subcommand -from nonebot_plugin_alconna.uniseg import UniMessage +from nonebot_plugin_alconna.uniseg import Image, UniMessage from nonebot_plugin_orm import get_session from nonebot_plugin_uninfo import Uninfo from nonebot_plugin_uninfo.orm import get_session_persist_id @@ -112,10 +112,16 @@ async def _( # noqa: PLR0913 select(TETRIOUserConfig.query_template).where(TETRIOUserConfig.id == user.id) ) if bind is None: - await matcher.finish('未查询到绑定信息') + await matcher.finish(Lang.bind.not_found()) player = Player(user_id=bind.game_account, trust=True) await ( - UniMessage.i18n(Lang.interaction.warning.unverified) + await make_query_result(player, template or 'v1') + UniMessage.i18n(Lang.interaction.warning.unverified) + + ( + UniMessage('\n') + if not (result := await make_query_result(player, template or 'v1')).has(Image) + else UniMessage() + ) + + result ).finish() diff --git a/nonebot_plugin_tetris_stats/games/tetrio/record/blitz.py b/nonebot_plugin_tetris_stats/games/tetrio/record/blitz.py index 30f74a5..76740a4 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/record/blitz.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/record/blitz.py @@ -59,7 +59,7 @@ async def _( game_platform=GAME_TYPE, ) if bind is None: - await matcher.finish('未查询到绑定信息') + await matcher.finish(Lang.bind.not_found()) player = Player(user_id=bind.game_account, trust=True) await ( UniMessage.i18n(Lang.interaction.warning.unverified) + UniMessage.image(raw=await make_blitz_image(player)) @@ -80,7 +80,7 @@ async def _(account: Player, event_session: Uninfo): async def make_blitz_image(player: Player) -> bytes: user, blitz = await gather(player.user, player.blitz) if blitz.data.record is None: - msg = f'未找到用户 {user.name.upper()} 的 Blitz 记录' + msg = Lang.record.not_found(username=user.name.upper(), mode=Lang.record.blitz()) raise RecordNotFoundError(msg) stats = blitz.data.record.results.stats clears = stats.clears diff --git a/nonebot_plugin_tetris_stats/games/tetrio/record/sprint.py b/nonebot_plugin_tetris_stats/games/tetrio/record/sprint.py index a3a20d2..76778c0 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/record/sprint.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/record/sprint.py @@ -59,7 +59,7 @@ async def _( game_platform=GAME_TYPE, ) if bind is None: - await matcher.finish('未查询到绑定信息') + await matcher.finish(Lang.bind.not_found()) player = Player(user_id=bind.game_account, trust=True) await ( UniMessage.i18n(Lang.interaction.warning.unverified) + UniMessage.image(raw=await make_sprint_image(player)) @@ -80,7 +80,7 @@ async def _(account: Player, event_session: Uninfo): async def make_sprint_image(player: Player) -> bytes: user, sprint = await gather(player.user, player.sprint) if sprint.data.record is None: - msg = f'未找到用户 {user.name.upper()} 的 40L 记录' + msg = Lang.record.not_found(username=user.name.upper(), mode=Lang.record.sprint()) raise RecordNotFoundError(msg) stats = sprint.data.record.results.stats clears = stats.clears diff --git a/nonebot_plugin_tetris_stats/games/tetrio/unbind.py b/nonebot_plugin_tetris_stats/games/tetrio/unbind.py index 96493b4..f84424b 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/unbind.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/unbind.py @@ -13,6 +13,7 @@ from yarl import URL from ...config.config import global_config from ...db import query_bind_info, remove_bind, trigger +from ...i18n import Lang from ...utils.host import get_self_netloc from ...utils.image import get_avatar from ...utils.lang import get_lang @@ -44,8 +45,8 @@ async def _(nb_user: User, event_session: Uninfo, interface: QryItrface): get_session() as session, ): if (bind := await query_bind_info(session=session, user=nb_user, game_platform=GAME_TYPE)) is None: - await UniMessage('您还未绑定 TETR.IO 账号').finish() - resp = await suggest('您确定要解绑吗?', ['是', '否']) + await UniMessage(Lang.bind.no_account(game='TETR.IO')).finish() + resp = await suggest(Lang.bind.confirm_unbind(), ['是', '否']) if resp is None or resp.extract_plain_text() == '否': return player = Player(user_id=bind.game_account, trust=True) @@ -76,7 +77,7 @@ async def _(nb_user: User, event_session: Uninfo, interface: QryItrface): ), name=bot_user.nick or bot_user.name or choice(list(global_config.nickname) or ['bot']), ), - prompt='io绑定{游戏ID}', + prompt=Lang.prompt.io_bind(), lang=get_lang(), ), ) diff --git a/nonebot_plugin_tetris_stats/games/tetrio/verify.py b/nonebot_plugin_tetris_stats/games/tetrio/verify.py index 4bf5cac..269df92 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/verify.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/verify.py @@ -13,6 +13,7 @@ from yarl import URL from ...config.config import global_config from ...db import create_or_update_bind, query_bind_info, trigger +from ...i18n import Lang from ...utils.host import get_self_netloc from ...utils.image import get_avatar from ...utils.lang import get_lang @@ -46,9 +47,9 @@ try: get_session() as session, ): if (bind := await query_bind_info(session=session, user=nb_user, game_platform=GAME_TYPE)) is None: - await UniMessage('您还未绑定 TETR.IO 账号').finish() + await UniMessage(Lang.bind.no_account(game='TETR.IO')).finish() if bind.verify is True: - await UniMessage('您已经完成了验证.').finish() + await UniMessage(Lang.bind.verify_already()).finish() player = Player(user_id=bind.game_account, trust=True) user_info = await player.get_info() verify = ( @@ -56,7 +57,7 @@ try: and user_info.data.connections.discord.id == event_session.user.id ) if verify is False: - await UniMessage('您未通过验证, 请确认目标 TETR.IO 账号绑定了当前 Discord 账号').finish() + await UniMessage(Lang.bind.verify_failed(game='TETR.IO')).finish() await create_or_update_bind( session=session, user=nb_user, @@ -90,7 +91,7 @@ try: ), name=bot_user.nick or bot_user.name or choice(list(global_config.nickname) or ['bot']), ), - prompt='io查我', + prompt=Lang.prompt.io_check(), lang=get_lang(), ), ) @@ -107,4 +108,4 @@ async def _(event_session: Uninfo): command_type='verify', command_args=[], ): - await UniMessage('目前仅支持 Discord 账号验证').finish() + await UniMessage(Lang.bind.only_discord()).finish() diff --git a/nonebot_plugin_tetris_stats/games/top/bind.py b/nonebot_plugin_tetris_stats/games/top/bind.py index da5bdae..b25e6a8 100644 --- a/nonebot_plugin_tetris_stats/games/top/bind.py +++ b/nonebot_plugin_tetris_stats/games/top/bind.py @@ -9,6 +9,7 @@ from nonebot_plugin_user import User from ...config.config import global_config from ...db import BindStatus, create_or_update_bind, trigger +from ...i18n import Lang from ...utils.image import get_avatar from ...utils.lang import get_lang from ...utils.render import render_image @@ -60,7 +61,7 @@ async def _(nb_user: User, account: Player, event_session: Uninfo, interface: Qr ), name=bot_user.nick or bot_user.name or choice(list(global_config.nickname) or ['bot']), ), - prompt='top查我', + prompt=Lang.prompt.top_check(), lang=get_lang(), ), ) diff --git a/nonebot_plugin_tetris_stats/games/top/query.py b/nonebot_plugin_tetris_stats/games/top/query.py index 06de649..fc855ed 100644 --- a/nonebot_plugin_tetris_stats/games/top/query.py +++ b/nonebot_plugin_tetris_stats/games/top/query.py @@ -1,7 +1,7 @@ from nonebot.adapters import Event from nonebot.matcher import Matcher from nonebot_plugin_alconna import At -from nonebot_plugin_alconna.uniseg import UniMessage +from nonebot_plugin_alconna.uniseg import Image, UniMessage from nonebot_plugin_orm import get_session from nonebot_plugin_uninfo import Uninfo from nonebot_plugin_uninfo.orm import get_session_persist_id @@ -41,10 +41,19 @@ async def _(event: Event, matcher: Matcher, target: At | Me, event_session: Unin game_platform=GAME_TYPE, ) if bind is None: - await matcher.finish('未查询到绑定信息') + await matcher.finish(Lang.bind.not_found()) await ( UniMessage.i18n(Lang.interaction.warning.unverified) - + await make_query_result(await Player(user_name=bind.game_account, trust=True).get_profile()) + + ( + UniMessage('\n') + if not ( + result := await make_query_result( + await Player(user_name=bind.game_account, trust=True).get_profile() + ) + ).has(Image) + else UniMessage() + ) + + result ).finish() @@ -101,18 +110,18 @@ def make_query_text(profile: UserProfile) -> UniMessage: message = '' if profile.today is not None: today = get_metrics(lpm=profile.today.lpm, apm=profile.today.apm) - message += f'用户 {profile.user_name} 24小时内统计数据为: ' - message += f"\nL'PM: {today.lpm} ( {today.pps} pps )" - message += f'\nAPM: {today.apm} ( x{today.apl} )' + message += Lang.stats.daily_stats(name=profile.user_name) + message += Lang.stats.lpm(lpm=today.lpm, pps=today.pps) + message += Lang.stats.apm(apm=today.apm, apl=today.apl) else: - message += f'用户 {profile.user_name} 暂无24小时内统计数据' + message += Lang.stats.no_daily(name=profile.user_name) if profile.total is not None: total = get_avg_metrics(profile.total) - message += '\n历史统计数据为: ' - message += f"\nL'PM: {total.lpm} ( {total.pps} pps )" - message += f'\nAPM: {total.apm} ( x{total.apl} )' + message += Lang.stats.history_stats() + message += Lang.stats.lpm(lpm=total.lpm, pps=total.pps) + message += Lang.stats.apm(apm=total.apm, apl=total.apl) else: - message += '\n暂无历史统计数据' + message += Lang.stats.no_history() return UniMessage(message) diff --git a/nonebot_plugin_tetris_stats/games/top/unbind.py b/nonebot_plugin_tetris_stats/games/top/unbind.py index 377a6eb..eeb10d0 100644 --- a/nonebot_plugin_tetris_stats/games/top/unbind.py +++ b/nonebot_plugin_tetris_stats/games/top/unbind.py @@ -10,6 +10,7 @@ from nonebot_plugin_waiter import suggest # type: ignore[import-untyped] from ...config.config import global_config from ...db import query_bind_info, remove_bind, trigger +from ...i18n import Lang from ...utils.image import get_avatar from ...utils.lang import get_lang from ...utils.render import render_image @@ -36,8 +37,8 @@ async def _( get_session() as session, ): if (bind := await query_bind_info(session=session, user=nb_user, game_platform=GAME_TYPE)) is None: - await UniMessage('您还未绑定 TOP 账号').finish() - resp = await suggest('您确定要解绑吗?', ['是', '否']) + await UniMessage(Lang.bind.no_account(game='TOP')).finish() + resp = await suggest(Lang.bind.confirm_unbind(), ['是', '否']) if resp is None or resp.extract_plain_text() == '否': return player = Player(user_name=bind.game_account, trust=True) @@ -66,7 +67,7 @@ async def _( ), name=bot_user.nick or bot_user.name or choice(list(global_config.nickname) or ['bot']), ), - prompt='top绑定{游戏ID}', + prompt=Lang.prompt.top_bind(), lang=get_lang(), ), ) diff --git a/nonebot_plugin_tetris_stats/games/tos/bind.py b/nonebot_plugin_tetris_stats/games/tos/bind.py index 23dbeab..33ee70b 100644 --- a/nonebot_plugin_tetris_stats/games/tos/bind.py +++ b/nonebot_plugin_tetris_stats/games/tos/bind.py @@ -9,6 +9,7 @@ from nonebot_plugin_user import User from ...config.config import global_config from ...db import BindStatus, create_or_update_bind, trigger +from ...i18n import Lang from ...utils.image import get_avatar from ...utils.lang import get_lang from ...utils.render import render_image @@ -66,7 +67,7 @@ async def _( ), name=bot_user.nick or bot_user.name or choice(list(global_config.nickname) or ['bot']), ), - prompt='茶服查我', + prompt=Lang.prompt.tos_check(), lang=get_lang(), ), ) diff --git a/nonebot_plugin_tetris_stats/games/tos/query.py b/nonebot_plugin_tetris_stats/games/tos/query.py index c9c87bf..0f679f7 100644 --- a/nonebot_plugin_tetris_stats/games/tos/query.py +++ b/nonebot_plugin_tetris_stats/games/tos/query.py @@ -127,7 +127,7 @@ async def _( game_platform=GAME_TYPE, ) if bind is None: - await matcher.finish('未查询到绑定信息') + await matcher.finish(Lang.bind.not_found()) message = UniMessage.i18n(Lang.interaction.warning.unverified) player = Player(teaid=bind.game_account, trust=True) user_info, game_data = await gather(player.get_info(), get_game_data(player)) @@ -142,7 +142,7 @@ async def _( ) ) ).finish() - await (message + make_query_text(user_info, game_data)).finish() + await (message + UniMessage('\n') + make_query_text(user_info, game_data)).finish() @alc.assign('TOS.query') @@ -308,19 +308,26 @@ async def make_query_image(user_info: UserInfoSuccess, game_data: GameData, even def make_query_text(user_info: UserInfoSuccess, game_data: GameData | None) -> UniMessage: user_data = user_info.data - message = f'用户 {user_data.name} ({user_data.teaid}) ' + message = Lang.stats.user_info(name=user_data.name, id=user_data.teaid) if user_data.ranked_games == '0': - message += '暂无段位统计数据' + message += Lang.stats.no_rank() else: - message += f', 段位分 {round(float(user_data.rating_now), 2)}±{round(float(user_data.rd_now), 2)} ({round(float(user_data.vol_now), 2)}) ' + message += Lang.stats.rank_info( + rating=round(float(user_data.rating_now), 2), + rd=round(float(user_data.rd_now), 2), + vol=round(float(user_data.vol_now), 2), + ) if game_data is None: - message += ', 暂无游戏数据' + message += Lang.stats.no_game() else: - message += f', 最近 {game_data.game_num} 局数据' - message += f"\nL'PM: {game_data.metrics.lpm} ( {game_data.metrics.pps} pps )" - message += f'\nAPM: {game_data.metrics.apm} ( x{game_data.metrics.apl} )' - message += f'\nADPM: {game_data.metrics.adpm} ( x{game_data.metrics.adpl} ) ( {game_data.metrics.vs}vs )' - message += f'\n40L: {float(user_data.pb_sprint) / 1000:.2f}s' if user_data.pb_sprint != '2147483647' else '' - message += f'\nMarathon: {user_data.pb_marathon}' if user_data.pb_marathon != '0' else '' - message += f'\nChallenge: {user_data.pb_challenge}' if user_data.pb_challenge != '0' else '' + message += Lang.stats.recent_games(count=game_data.game_num) + message += Lang.stats.lpm(lpm=game_data.metrics.lpm, pps=game_data.metrics.pps) + message += Lang.stats.apm(apm=game_data.metrics.apm, apl=game_data.metrics.apl) + message += Lang.stats.adpm(adpm=game_data.metrics.adpm, adpl=game_data.metrics.adpl, vs=game_data.metrics.vs) + if user_data.pb_sprint != '2147483647': + message += Lang.stats.sprint_pb(time=f'{float(user_data.pb_sprint) / 1000:.2f}') + if user_data.pb_marathon != '0': + message += Lang.stats.marathon_pb(score=user_data.pb_marathon) + if user_data.pb_challenge != '0': + message += Lang.stats.challenge_pb(score=user_data.pb_challenge) return UniMessage(message) diff --git a/nonebot_plugin_tetris_stats/i18n/.template.json b/nonebot_plugin_tetris_stats/i18n/.template.json index 29d96d4..9493165 100644 --- a/nonebot_plugin_tetris_stats/i18n/.template.json +++ b/nonebot_plugin_tetris_stats/i18n/.template.json @@ -12,6 +12,58 @@ "scope": "error", "types": [{ "subtype": "MessageFormatError", "types": ["TETR.IO", "TOS", "TOP"] }] }, - { "scope": "template", "types": ["template_language"] } + { "scope": "template", "types": ["template_language"] }, + { + "scope": "bind", + "types": [ + "not_found", + "no_account", + "confirm_unbind", + "config_success", + "verify_already", + "verify_failed", + "only_discord" + ] + }, + { + "scope": "record", + "types": ["not_found", "blitz", "sprint"] + }, + { + "scope": "stats", + "types": [ + "user_info", + "no_rank", + "rank_info", + "no_game", + "recent_games", + "daily_stats", + "no_daily", + "history_stats", + "no_history", + "lpm", + "apm", + "adpm", + "sprint_pb", + "marathon_pb", + "challenge_pb" + ] + }, + { + "scope": "template_ui", + "types": ["invalid_tag", "update_success", "update_failed"] + }, + { + "scope": "help", + "types": ["usage"] + }, + { + "scope": "prompt", + "types": ["io_check", "io_bind", "top_check", "top_bind", "tos_check", "tos_bind"] + }, + { + "scope": "retry", + "types": ["message"] + } ] } diff --git a/nonebot_plugin_tetris_stats/i18n/en-US.json b/nonebot_plugin_tetris_stats/i18n/en-US.json index ee79967..8f37126 100644 --- a/nonebot_plugin_tetris_stats/i18n/en-US.json +++ b/nonebot_plugin_tetris_stats/i18n/en-US.json @@ -15,5 +15,55 @@ }, "template": { "template_language": "en-US" + }, + "bind": { + "not_found": "No binding information found", + "no_account": "You haven't bound a {game} account yet", + "confirm_unbind": "Are you sure you want to unbind?", + "config_success": "Configuration successful", + "verify_already": "You have already completed verification.", + "verify_failed": "Verification failed. Please confirm the target {game} account is linked to your current Discord account.", + "only_discord": "Currently only Discord account verification is supported" + }, + "record": { + "not_found": "No {mode} record found for user {username}", + "blitz": "Blitz", + "sprint": "40L" + }, + "stats": { + "user_info": "User {name} ({id})", + "no_rank": "No rank statistics available", + "rank_info": ", Rating {rating}±{rd} ({vol})", + "no_game": ", No game data available", + "recent_games": ", Recent {count} games data", + "daily_stats": "User {name} 24h statistics: ", + "no_daily": "User {name} has no 24h statistics available", + "history_stats": "\nHistorical statistics: ", + "no_history": "\nNo historical statistics available", + "lpm": "\nL'PM: {lpm} ( {pps} pps )", + "apm": "\nAPM: {apm} ( x{apl} )", + "adpm": "\nADPM: {adpm} ( x{adpl} ) ( {vs}vs )", + "sprint_pb": "\n40L: {time}s", + "marathon_pb": "\nMarathon: {score}", + "challenge_pb": "\nChallenge: {score}" + }, + "template_ui": { + "invalid_tag": "{revision} is not a valid tag in the template repository", + "update_success": "Template updated successfully", + "update_failed": "Template update failed" + }, + "help": { + "usage": "Type \"{command} --help\" for help" + }, + "prompt": { + "io_check": "io check me", + "io_bind": "io bind {{gameID}}", + "top_check": "top check me", + "top_bind": "top bind {{gameID}}", + "tos_check": "tos check me", + "tos_bind": "tos bind {{gameID}}" + }, + "retry": { + "message": "Retrying: {func} ({i}/{max_attempts})" } } diff --git a/nonebot_plugin_tetris_stats/i18n/model.py b/nonebot_plugin_tetris_stats/i18n/model.py index 449efdb..d499e2e 100644 --- a/nonebot_plugin_tetris_stats/i18n/model.py +++ b/nonebot_plugin_tetris_stats/i18n/model.py @@ -31,7 +31,71 @@ class Template: template_language: LangItem = LangItem('template', 'template_language') +class Bind: + not_found: LangItem = LangItem('bind', 'not_found') + no_account: LangItem = LangItem('bind', 'no_account') + confirm_unbind: LangItem = LangItem('bind', 'confirm_unbind') + config_success: LangItem = LangItem('bind', 'config_success') + verify_already: LangItem = LangItem('bind', 'verify_already') + verify_failed: LangItem = LangItem('bind', 'verify_failed') + only_discord: LangItem = LangItem('bind', 'only_discord') + + +class Record: + not_found: LangItem = LangItem('record', 'not_found') + blitz: LangItem = LangItem('record', 'blitz') + sprint: LangItem = LangItem('record', 'sprint') + + +class Stats: + user_info: LangItem = LangItem('stats', 'user_info') + no_rank: LangItem = LangItem('stats', 'no_rank') + rank_info: LangItem = LangItem('stats', 'rank_info') + no_game: LangItem = LangItem('stats', 'no_game') + recent_games: LangItem = LangItem('stats', 'recent_games') + daily_stats: LangItem = LangItem('stats', 'daily_stats') + no_daily: LangItem = LangItem('stats', 'no_daily') + history_stats: LangItem = LangItem('stats', 'history_stats') + no_history: LangItem = LangItem('stats', 'no_history') + lpm: LangItem = LangItem('stats', 'lpm') + apm: LangItem = LangItem('stats', 'apm') + adpm: LangItem = LangItem('stats', 'adpm') + sprint_pb: LangItem = LangItem('stats', 'sprint_pb') + marathon_pb: LangItem = LangItem('stats', 'marathon_pb') + challenge_pb: LangItem = LangItem('stats', 'challenge_pb') + + +class TemplateUi: + invalid_tag: LangItem = LangItem('template_ui', 'invalid_tag') + update_success: LangItem = LangItem('template_ui', 'update_success') + update_failed: LangItem = LangItem('template_ui', 'update_failed') + + +class Help: + usage: LangItem = LangItem('help', 'usage') + + +class Prompt: + io_check: LangItem = LangItem('prompt', 'io_check') + io_bind: LangItem = LangItem('prompt', 'io_bind') + top_check: LangItem = LangItem('prompt', 'top_check') + top_bind: LangItem = LangItem('prompt', 'top_bind') + tos_check: LangItem = LangItem('prompt', 'tos_check') + tos_bind: LangItem = LangItem('prompt', 'tos_bind') + + +class Retry: + message: LangItem = LangItem('retry', 'message') + + class Lang(LangModel): interaction = Interaction error = Error template = Template + bind = Bind + record = Record + stats = Stats + template_ui = TemplateUi + help = Help + prompt = Prompt + retry = Retry diff --git a/nonebot_plugin_tetris_stats/i18n/zh-CN.json b/nonebot_plugin_tetris_stats/i18n/zh-CN.json index 45c3165..4f4f3d0 100644 --- a/nonebot_plugin_tetris_stats/i18n/zh-CN.json +++ b/nonebot_plugin_tetris_stats/i18n/zh-CN.json @@ -13,5 +13,55 @@ }, "template": { "template_language": "zh-CN" + }, + "bind": { + "not_found": "未查询到绑定信息", + "no_account": "您还未绑定 {game} 账号", + "confirm_unbind": "您确定要解绑吗?", + "config_success": "配置成功", + "verify_already": "您已经完成了验证.", + "verify_failed": "您未通过验证, 请确认目标 {game} 账号绑定了当前 Discord 账号", + "only_discord": "目前仅支持 Discord 账号验证" + }, + "record": { + "not_found": "未找到用户 {username} 的 {mode} 记录", + "blitz": "Blitz", + "sprint": "40L" + }, + "stats": { + "user_info": "用户 {name} ({id})", + "no_rank": "暂无段位统计数据", + "rank_info": ", 段位分 {rating}±{rd} ({vol})", + "no_game": ", 暂无游戏数据", + "recent_games": ", 最近 {count} 局数据", + "daily_stats": "用户 {name} 24小时内统计数据为: ", + "no_daily": "用户 {name} 暂无24小时内统计数据", + "history_stats": "\n历史统计数据为: ", + "no_history": "\n暂无历史统计数据", + "lpm": "\nL'PM: {lpm} ( {pps} pps )", + "apm": "\nAPM: {apm} ( x{apl} )", + "adpm": "\nADPM: {adpm} ( x{adpl} ) ( {vs}vs )", + "sprint_pb": "\n40L: {time}s", + "marathon_pb": "\nMarathon: {score}", + "challenge_pb": "\nChallenge: {score}" + }, + "template_ui": { + "invalid_tag": "{revision} 不是模板仓库中的有效标签", + "update_success": "更新模板成功", + "update_failed": "更新模板失败" + }, + "help": { + "usage": "输入\"{command} --help\"查看帮助" + }, + "prompt": { + "io_check": "io查我", + "io_bind": "io绑定{{游戏ID}}", + "top_check": "top查我", + "top_bind": "top绑定{{游戏ID}}", + "tos_check": "茶服查我", + "tos_bind": "茶服绑定{{游戏ID}}" + }, + "retry": { + "message": "Retrying: {func} ({i}/{max_attempts})" } } diff --git a/nonebot_plugin_tetris_stats/utils/lang.py b/nonebot_plugin_tetris_stats/utils/lang.py index 3f2640d..ebfc28e 100644 --- a/nonebot_plugin_tetris_stats/utils/lang.py +++ b/nonebot_plugin_tetris_stats/utils/lang.py @@ -1,6 +1,6 @@ from typing import cast -from ..i18n.model import Lang +from ..i18n import Lang from .typedefs import Lang as LangType diff --git a/nonebot_plugin_tetris_stats/utils/retry.py b/nonebot_plugin_tetris_stats/utils/retry.py index 66f5aad..b0ce046 100644 --- a/nonebot_plugin_tetris_stats/utils/retry.py +++ b/nonebot_plugin_tetris_stats/utils/retry.py @@ -8,6 +8,8 @@ from typing import Any, ParamSpec, TypeVar from nonebot.log import logger from nonebot_plugin_alconna.uniseg import SerializeFailed, UniMessage +from ..i18n import Lang + T = TypeVar('T') P = ParamSpec('P') @@ -23,7 +25,7 @@ def retry( async def wrapper(*args: P.args, **kwargs: P.kwargs) -> T: for i in range(max_attempts + 1): if i > 0: - message = f'Retrying: {func.__name__} ({i}/{max_attempts})' + message = Lang.retry.message(func=func.__name__, i=i, max_attempts=max_attempts) logger.debug(message) with suppress(SerializeFailed): await UniMessage(reply or message).send() diff --git a/nonebot_plugin_tetris_stats/utils/templates.py b/nonebot_plugin_tetris_stats/utils/templates.py index c2610a5..8d5e4cc 100644 --- a/nonebot_plugin_tetris_stats/utils/templates.py +++ b/nonebot_plugin_tetris_stats/utils/templates.py @@ -14,6 +14,7 @@ from nonebot_plugin_alconna import Alconna, Args, Option, on_alconna from rich.progress import Progress from ..config.config import CACHE_PATH, DATA_PATH, config +from ..i18n import Lang driver = get_driver() @@ -115,11 +116,11 @@ async def check_tag(tag: str) -> bool: @alc.handle() async def _(revision: str | None = None): if revision is not None and not await check_tag(revision): - await alc.finish(f'{revision} 不是模板仓库中的有效标签') + await alc.finish(Lang.template_ui.invalid_tag(revision=revision)) logger.info('开始更新模板') if await init_templates(revision or 'latest'): - await alc.finish('更新模板成功') - await alc.finish('更新模板失败') + await alc.finish(Lang.template_ui.update_success()) + await alc.finish(Lang.template_ui.update_failed()) if config.tetris.dev.enable_template_check: