Skip to content

Commit 7cfdacc

Browse files
committed
✨ more convenient way to write i18n templates
1 parent 97645da commit 7cfdacc

File tree

4 files changed

+31
-7
lines changed

4 files changed

+31
-7
lines changed

src/nonebot_plugin_alconna/uniseg/message.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1296,7 +1296,7 @@ def _handle_i18n(self, extra: dict, *args, **kwargs):
12961296
if not isinstance(seg, I18n):
12971297
self.append(seg)
12981298
else:
1299-
msg = seg.tp().format(*args, *seg.args, **kwargs, **seg.kwargs, **extra)
1299+
msg = self.template(str(seg)).format(*args, *seg.args, **kwargs, **seg.kwargs, **extra)
13001300
if msg.has(I18n):
13011301
msg._handle_i18n(extra, *seg.args, **seg.kwargs)
13021302
self.extend(msg) # type: ignore

src/nonebot_plugin_alconna/uniseg/segment.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -985,10 +985,8 @@ def __init__(
985985
self.kwargs = mapping or {}
986986
self.kwargs.update(kwargs)
987987

988-
def tp(self):
989-
from .message import UniMessage
990-
991-
return UniMessage.template(lang.require(self.item.scope, self.item.type))
988+
def __str__(self):
989+
return lang.require(self.item.scope, self.item.type)
992990

993991
def dump(self, **kwargs):
994992
return {

src/nonebot_plugin_alconna/uniseg/template.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from collections.abc import Mapping, Sequence
66
from typing import TYPE_CHECKING, Any, Union, TypeVar, Callable, Optional, cast
77

8+
from tarina import lang
89
import _string # type: ignore
910
from tarina.tools import gen_subclass
1011

@@ -18,6 +19,7 @@
1819

1920
_MAPPING = {cls.__name__: cls for cls in gen_subclass(Segment)}
2021
_PATTERN = re.compile("(" + "|".join(_MAPPING.keys()) + r")\((.*)\)$")
22+
_I18N_PATTERN = re.compile(r"[^@]+\s*@\s*[^@]+")
2123

2224

2325
def _eval(route: str, obj: Any):
@@ -150,6 +152,27 @@ def _vformat(
150152

151153
# if there's a field, output it
152154
if field_name is not None:
155+
if mat := _I18N_PATTERN.match(field_name):
156+
scope, key = mat[0].split("@")
157+
ans = lang.require(scope.strip(), key.strip())
158+
if format_spec:
159+
_kwargs = {}
160+
for part in format_spec.split(","):
161+
if re.match(".+=.+", part):
162+
k, v = part.split("=")
163+
if v in kwargs:
164+
_kwargs[k] = kwargs[v]
165+
used_args.add(v)
166+
elif v.startswith("$") and (key := v.split(".")[0]) in kwargs:
167+
_kwargs[k] = _eval(v[1:], kwargs[key])
168+
else:
169+
_kwargs[k] = v
170+
elif part in kwargs:
171+
_kwargs[part] = kwargs[part]
172+
if _kwargs:
173+
ans = ans.format_map(_kwargs)
174+
results.append(ans)
175+
continue
153176
if field_name == "" and format_spec and (mat := _PATTERN.match(format_spec)):
154177
cls, parts = _MAPPING[mat[1]], mat[2].split(",")
155178
_args = []

tests/test_i18n.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
@pytest.mark.asyncio()
1111
async def test_send(app: App):
12-
from nonebot_plugin_alconna import lang, on_alconna
12+
from nonebot_plugin_alconna import UniMessage, lang, on_alconna
1313
from nonebot_plugin_alconna.uniseg.segment import I18n
1414

1515
cmd = on_alconna(Alconna("test", Args["name", str]))
@@ -32,7 +32,7 @@ async def test_send(app: App):
3232
"command.test.1": "test!",
3333
"command.test.2": "{:At(user, $event.get_user_id())} hello!",
3434
"command.test.3": "This is {abcd} test!",
35-
"command.test.4": "This is nested: {:I18n(test-i18n, command.test.1)}",
35+
"command.test.4": "This is nested: {test-i18n@command.test.1}",
3636
}
3737
},
3838
)
@@ -42,6 +42,7 @@ async def _():
4242
await cmd.send(I18n("test-i18n", "command.test.1"))
4343
await cmd.send(I18n("test-i18n", "command.test.2"))
4444
await cmd.send(cmd.i18n("test-i18n", "command.test.3", abcd="test"))
45+
await cmd.send(UniMessage.template("{test-i18n @ command.test.3:abcd=test1}"))
4546
await cmd.finish(cmd.i18n("test-i18n", "command.test.4"))
4647

4748
lang.select("zh-CN")
@@ -53,6 +54,7 @@ async def _():
5354
ctx.should_call_send(event, Message("测试!"))
5455
ctx.should_call_send(event, MessageSegment.mention_user("5678") + " 你好!")
5556
ctx.should_call_send(event, Message("这是 test 测试!"))
57+
ctx.should_call_send(event, Message("这是 test1 测试!"))
5658
ctx.should_call_send(event, Message("这是嵌套: 测试!"))
5759
ctx.should_finished()
5860

@@ -65,6 +67,7 @@ async def _():
6567
ctx.should_call_send(event, Message("test!"))
6668
ctx.should_call_send(event, MessageSegment.mention_user("5678") + " hello!")
6769
ctx.should_call_send(event, Message("This is test test!"))
70+
ctx.should_call_send(event, Message("This is test1 test!"))
6871
ctx.should_call_send(event, Message("This is nested: test!"))
6972
ctx.should_finished()
7073

0 commit comments

Comments
 (0)