mirror of
https://oauth2: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@github.com/m1ngsama/TNT.git
synced 2026-06-26 05:34:39 +08:00
i18n: localize exec guidance text
This commit is contained in:
parent
81c3f45864
commit
fd6cdbf627
6 changed files with 133 additions and 21 deletions
|
|
@ -33,6 +33,9 @@
|
|||
use the shared i18n table instead of inline command-flow conditionals.
|
||||
- Interactive and exec support guide copy now lives in a dedicated
|
||||
`support_text` module, with focused language-selection unit coverage.
|
||||
- Exec-mode help, usage errors, unknown-command feedback, and post validation
|
||||
messages now follow `TNT_LANG` while preserving stable machine-readable
|
||||
command output.
|
||||
|
||||
### Changed
|
||||
- NORMAL mode now opens at the latest visible messages instead of the oldest
|
||||
|
|
|
|||
|
|
@ -51,6 +51,14 @@ typedef enum {
|
|||
I18N_UNKNOWN_COMMAND_FORMAT,
|
||||
I18N_DID_YOU_MEAN_FORMAT,
|
||||
I18N_UNKNOWN_GUIDANCE,
|
||||
I18N_EXEC_HELP,
|
||||
I18N_EXEC_USERS_USAGE,
|
||||
I18N_EXEC_STATS_USAGE,
|
||||
I18N_EXEC_TAIL_USAGE,
|
||||
I18N_EXEC_POST_USAGE,
|
||||
I18N_EXEC_POST_EMPTY,
|
||||
I18N_EXEC_POST_INVALID_UTF8,
|
||||
I18N_EXEC_UNKNOWN_COMMAND_FORMAT,
|
||||
I18N_CONTINUE_PROMPT
|
||||
} i18n_text_id_t;
|
||||
|
||||
|
|
|
|||
43
src/exec.c
43
src/exec.c
|
|
@ -2,6 +2,7 @@
|
|||
#include "chat_room.h"
|
||||
#include "client.h"
|
||||
#include "common.h"
|
||||
#include "i18n.h"
|
||||
#include "input.h"
|
||||
#include "message.h"
|
||||
#include "ratelimit.h"
|
||||
|
|
@ -116,21 +117,9 @@ static void resolve_exec_username(const client_t *client, char *buffer,
|
|||
}
|
||||
|
||||
static int exec_command_help(client_t *client) {
|
||||
static const char help_text[] =
|
||||
"TNT exec interface\n"
|
||||
"Commands:\n"
|
||||
" help Show this help\n"
|
||||
" health Print service health\n"
|
||||
" users [--json] List online users\n"
|
||||
" stats [--json] Print room statistics\n"
|
||||
" tail [N] Print recent messages\n"
|
||||
" tail -n N Print recent messages\n"
|
||||
" post MESSAGE Post a message non-interactively\n"
|
||||
" post \"/me act\" Post an action message\n"
|
||||
" support Show quick support guide\n"
|
||||
" exit Exit successfully\n";
|
||||
const char *help_text = i18n_text(client->help_lang, I18N_EXEC_HELP);
|
||||
|
||||
return client_send(client, help_text, sizeof(help_text) - 1) == 0 ? 0 : 1;
|
||||
return client_send(client, help_text, strlen(help_text)) == 0 ? 0 : 1;
|
||||
}
|
||||
|
||||
static int exec_command_support(client_t *client) {
|
||||
|
|
@ -304,7 +293,8 @@ static int exec_command_tail(client_t *client, const char *args) {
|
|||
int rc;
|
||||
|
||||
if (parse_tail_count(args, &requested) < 0) {
|
||||
client_printf(client, "tail: usage: tail [N] | tail -n N\n");
|
||||
client_printf(client, "%s",
|
||||
i18n_text(client->help_lang, I18N_EXEC_TAIL_USAGE));
|
||||
return 64;
|
||||
}
|
||||
|
||||
|
|
@ -357,7 +347,8 @@ static int exec_command_post(client_t *client, const char *args) {
|
|||
};
|
||||
|
||||
if (!args || args[0] == '\0') {
|
||||
client_printf(client, "post: usage: post MESSAGE\n");
|
||||
client_printf(client, "%s",
|
||||
i18n_text(client->help_lang, I18N_EXEC_POST_USAGE));
|
||||
return 64;
|
||||
}
|
||||
|
||||
|
|
@ -366,12 +357,15 @@ static int exec_command_post(client_t *client, const char *args) {
|
|||
trim_ascii_whitespace(content);
|
||||
|
||||
if (content[0] == '\0') {
|
||||
client_printf(client, "post: message cannot be empty\n");
|
||||
client_printf(client, "%s",
|
||||
i18n_text(client->help_lang, I18N_EXEC_POST_EMPTY));
|
||||
return 64;
|
||||
}
|
||||
|
||||
if (!utf8_is_valid_string(content)) {
|
||||
client_printf(client, "post: invalid UTF-8 input\n");
|
||||
client_printf(client, "%s",
|
||||
i18n_text(client->help_lang,
|
||||
I18N_EXEC_POST_INVALID_UTF8));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -443,14 +437,18 @@ int exec_dispatch(client_t *client) {
|
|||
}
|
||||
if (strcmp(cmd, "users") == 0) {
|
||||
if (args && strcmp(args, "--json") != 0) {
|
||||
client_printf(client, "users: usage: users [--json]\n");
|
||||
client_printf(client, "%s",
|
||||
i18n_text(client->help_lang,
|
||||
I18N_EXEC_USERS_USAGE));
|
||||
return 64;
|
||||
}
|
||||
return exec_command_users(client, args != NULL);
|
||||
}
|
||||
if (strcmp(cmd, "stats") == 0) {
|
||||
if (args && strcmp(args, "--json") != 0) {
|
||||
client_printf(client, "stats: usage: stats [--json]\n");
|
||||
client_printf(client, "%s",
|
||||
i18n_text(client->help_lang,
|
||||
I18N_EXEC_STATS_USAGE));
|
||||
return 64;
|
||||
}
|
||||
return exec_command_stats(client, args != NULL);
|
||||
|
|
@ -465,6 +463,9 @@ int exec_dispatch(client_t *client) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
client_printf(client, "Unknown command: %s\n", cmd);
|
||||
client_printf(client,
|
||||
i18n_text(client->help_lang,
|
||||
I18N_EXEC_UNKNOWN_COMMAND_FORMAT),
|
||||
cmd);
|
||||
return 64;
|
||||
}
|
||||
|
|
|
|||
54
src/i18n.c
54
src/i18n.c
|
|
@ -168,6 +168,33 @@ const char *i18n_text(help_lang_t lang, i18n_text_id_t id) {
|
|||
return "你是想输入 :%s 吗?\n";
|
||||
case I18N_UNKNOWN_GUIDANCE:
|
||||
return "输入 :support 查看引导,或 :help 查看命令\n";
|
||||
case I18N_EXEC_HELP:
|
||||
return "TNT exec 接口\n"
|
||||
"命令:\n"
|
||||
" help 显示此帮助\n"
|
||||
" health 输出服务健康状态\n"
|
||||
" users [--json] 列出在线用户\n"
|
||||
" stats [--json] 输出房间统计\n"
|
||||
" tail [N] 输出最近消息\n"
|
||||
" tail -n N 输出最近消息\n"
|
||||
" post MESSAGE 非交互发送消息\n"
|
||||
" post \"/me act\" 发送动作消息\n"
|
||||
" support 显示快速支持指南\n"
|
||||
" exit 成功退出\n";
|
||||
case I18N_EXEC_USERS_USAGE:
|
||||
return "users: 用法: users [--json]\n";
|
||||
case I18N_EXEC_STATS_USAGE:
|
||||
return "stats: 用法: stats [--json]\n";
|
||||
case I18N_EXEC_TAIL_USAGE:
|
||||
return "tail: 用法: tail [N] | tail -n N\n";
|
||||
case I18N_EXEC_POST_USAGE:
|
||||
return "post: 用法: post MESSAGE\n";
|
||||
case I18N_EXEC_POST_EMPTY:
|
||||
return "post: 消息不能为空\n";
|
||||
case I18N_EXEC_POST_INVALID_UTF8:
|
||||
return "post: 输入不是有效 UTF-8\n";
|
||||
case I18N_EXEC_UNKNOWN_COMMAND_FORMAT:
|
||||
return "未知命令: %s\n";
|
||||
case I18N_CONTINUE_PROMPT:
|
||||
return "\n按任意键继续...";
|
||||
}
|
||||
|
|
@ -271,6 +298,33 @@ const char *i18n_text(help_lang_t lang, i18n_text_id_t id) {
|
|||
return "Did you mean :%s?\n";
|
||||
case I18N_UNKNOWN_GUIDANCE:
|
||||
return "Type :support for guidance or :help for commands\n";
|
||||
case I18N_EXEC_HELP:
|
||||
return "TNT exec interface\n"
|
||||
"Commands:\n"
|
||||
" help Show this help\n"
|
||||
" health Print service health\n"
|
||||
" users [--json] List online users\n"
|
||||
" stats [--json] Print room statistics\n"
|
||||
" tail [N] Print recent messages\n"
|
||||
" tail -n N Print recent messages\n"
|
||||
" post MESSAGE Post a message non-interactively\n"
|
||||
" post \"/me act\" Post an action message\n"
|
||||
" support Show quick support guide\n"
|
||||
" exit Exit successfully\n";
|
||||
case I18N_EXEC_USERS_USAGE:
|
||||
return "users: usage: users [--json]\n";
|
||||
case I18N_EXEC_STATS_USAGE:
|
||||
return "stats: usage: stats [--json]\n";
|
||||
case I18N_EXEC_TAIL_USAGE:
|
||||
return "tail: usage: tail [N] | tail -n N\n";
|
||||
case I18N_EXEC_POST_USAGE:
|
||||
return "post: usage: post MESSAGE\n";
|
||||
case I18N_EXEC_POST_EMPTY:
|
||||
return "post: message cannot be empty\n";
|
||||
case I18N_EXEC_POST_INVALID_UTF8:
|
||||
return "post: invalid UTF-8 input\n";
|
||||
case I18N_EXEC_UNKNOWN_COMMAND_FORMAT:
|
||||
return "Unknown command: %s\n";
|
||||
case I18N_CONTINUE_PROMPT:
|
||||
return "\nPress any key to continue...";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,40 @@ else
|
|||
FAIL=$((FAIL + 1))
|
||||
fi
|
||||
|
||||
HELP_OUTPUT=$(ssh $SSH_OPTS localhost help 2>/dev/null || true)
|
||||
printf '%s\n' "$HELP_OUTPUT" | grep -q '^TNT exec 接口$' &&
|
||||
printf '%s\n' "$HELP_OUTPUT" | grep -q '^命令:$'
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ help follows TNT_LANG"
|
||||
PASS=$((PASS + 1))
|
||||
else
|
||||
echo "✗ help output unexpected"
|
||||
printf '%s\n' "$HELP_OUTPUT"
|
||||
FAIL=$((FAIL + 1))
|
||||
fi
|
||||
|
||||
UNKNOWN_OUTPUT=$(ssh $SSH_OPTS localhost nope 2>/dev/null || true)
|
||||
printf '%s\n' "$UNKNOWN_OUTPUT" | grep -q '^未知命令: nope$'
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ unknown command follows TNT_LANG"
|
||||
PASS=$((PASS + 1))
|
||||
else
|
||||
echo "✗ unknown command output unexpected"
|
||||
printf '%s\n' "$UNKNOWN_OUTPUT"
|
||||
FAIL=$((FAIL + 1))
|
||||
fi
|
||||
|
||||
POST_USAGE=$(ssh $SSH_OPTS localhost post 2>/dev/null || true)
|
||||
printf '%s\n' "$POST_USAGE" | grep -q '^post: 用法: post MESSAGE$'
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ post usage follows TNT_LANG"
|
||||
PASS=$((PASS + 1))
|
||||
else
|
||||
echo "✗ post usage output unexpected"
|
||||
printf '%s\n' "$POST_USAGE"
|
||||
FAIL=$((FAIL + 1))
|
||||
fi
|
||||
|
||||
POST_OUTPUT=$(ssh $SSH_OPTS execposter@localhost post "hello from exec" 2>/dev/null || true)
|
||||
if [ "$POST_OUTPUT" = "posted" ]; then
|
||||
echo "✓ post publishes a message"
|
||||
|
|
|
|||
|
|
@ -98,6 +98,18 @@ TEST(text_lookup_matches_language) {
|
|||
"Unknown command") != NULL);
|
||||
assert(strstr(i18n_text(LANG_ZH, I18N_UNKNOWN_COMMAND_FORMAT),
|
||||
"未知命令") != NULL);
|
||||
assert(strstr(i18n_text(LANG_EN, I18N_EXEC_HELP),
|
||||
"TNT exec interface") != NULL);
|
||||
assert(strstr(i18n_text(LANG_ZH, I18N_EXEC_HELP),
|
||||
"TNT exec 接口") != NULL);
|
||||
assert(strstr(i18n_text(LANG_EN, I18N_EXEC_POST_EMPTY),
|
||||
"message cannot be empty") != NULL);
|
||||
assert(strstr(i18n_text(LANG_ZH, I18N_EXEC_POST_EMPTY),
|
||||
"消息不能为空") != NULL);
|
||||
assert(strstr(i18n_text(LANG_EN, I18N_EXEC_UNKNOWN_COMMAND_FORMAT),
|
||||
"Unknown command") != NULL);
|
||||
assert(strstr(i18n_text(LANG_ZH, I18N_EXEC_UNKNOWN_COMMAND_FORMAT),
|
||||
"未知命令") != NULL);
|
||||
assert(strcmp(i18n_lang_code(LANG_EN), "en") == 0);
|
||||
assert(strcmp(i18n_lang_code(LANG_ZH), "zh") == 0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue