Skip to content

Commit 6b642d7

Browse files
authored
refactor: bundled webui static files into wheel and replace astrbot cli log with English (#5665)
* refactor: bundled webui static files into wheel and replace astrbot cli log with English - Translated and standardized log messages in cmd_conf.py for better clarity. - Updated initialization logic in cmd_init.py to provide clearer user prompts and error handling. - Improved plugin management commands in cmd_plug.py with consistent language and error messages. - Enhanced run command in cmd_run.py with clearer status messages and error handling. - Updated utility functions in basic.py and plugin.py to improve readability and maintainability. - Added version comparison logic in version_comparator.py with clearer comments. - Enhanced logging configuration in log.py to suppress noisy loggers. - Updated the updater logic in updator.py to provide clearer error messages for users. - Improved IO utility functions in io.py to handle dashboard versioning more effectively. - Enhanced dashboard server logic in server.py to prioritize bundled assets and improve user feedback. - Updated pyproject.toml to include bundled dashboard assets and custom build hooks. - Added a custom build script (hatch_build.py) to automate dashboard builds during package creation. * refactor: improve exception messages and formatting in CLI command validation * perf: change npm install to npm ci for consistent dependency installation * fix
1 parent 0711ec3 commit 6b642d7

File tree

15 files changed

+310
-187
lines changed

15 files changed

+310
-187
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ dashboard/dist/
3636
package-lock.json
3737
yarn.lock
3838

39+
# Bundled dashboard dist (generated by hatch_build.py during pip wheel build)
40+
astrbot/dashboard/dist/
41+
3942
# Operating System
4043
**/.DS_Store
4144
.DS_Store

astrbot/cli/__main__.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""AstrBot CLI入口"""
1+
"""AstrBot CLI entry point"""
22

33
import sys
44

@@ -29,23 +29,23 @@ def cli() -> None:
2929
@click.command()
3030
@click.argument("command_name", required=False, type=str)
3131
def help(command_name: str | None) -> None:
32-
"""显示命令的帮助信息
32+
"""Display help information for commands
3333
34-
如果提供了 COMMAND_NAME,则显示该命令的详细帮助信息。
35-
否则,显示通用帮助信息。
34+
If COMMAND_NAME is provided, display detailed help for that command.
35+
Otherwise, display general help information.
3636
"""
3737
ctx = click.get_current_context()
3838
if command_name:
39-
# 查找指定命令
39+
# Find the specified command
4040
command = cli.get_command(ctx, command_name)
4141
if command:
42-
# 显示特定命令的帮助信息
42+
# Display help for the specific command
4343
click.echo(command.get_help(ctx))
4444
else:
4545
click.echo(f"Unknown command: {command_name}")
4646
sys.exit(1)
4747
else:
48-
# 显示通用帮助信息
48+
# Display general help information
4949
click.echo(cli.get_help(ctx))
5050

5151

astrbot/cli/commands/cmd_conf.py

Lines changed: 47 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,57 +10,61 @@
1010

1111

1212
def _validate_log_level(value: str) -> str:
13-
"""验证日志级别"""
13+
"""Validate log level"""
1414
value = value.upper()
1515
if value not in ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]:
1616
raise click.ClickException(
17-
"日志级别必须是 DEBUG/INFO/WARNING/ERROR/CRITICAL 之一",
17+
"Log level must be one of DEBUG/INFO/WARNING/ERROR/CRITICAL",
1818
)
1919
return value
2020

2121

2222
def _validate_dashboard_port(value: str) -> int:
23-
"""验证 Dashboard 端口"""
23+
"""Validate Dashboard port"""
2424
try:
2525
port = int(value)
2626
if port < 1 or port > 65535:
27-
raise click.ClickException("端口必须在 1-65535 范围内")
27+
raise click.ClickException("Port must be in range 1-65535")
2828
return port
2929
except ValueError:
30-
raise click.ClickException("端口必须是数字")
30+
raise click.ClickException("Port must be a number")
3131

3232

3333
def _validate_dashboard_username(value: str) -> str:
34-
"""验证 Dashboard 用户名"""
34+
"""Validate Dashboard username"""
3535
if not value:
36-
raise click.ClickException("用户名不能为空")
36+
raise click.ClickException("Username cannot be empty")
3737
return value
3838

3939

4040
def _validate_dashboard_password(value: str) -> str:
41-
"""验证 Dashboard 密码"""
41+
"""Validate Dashboard password"""
4242
if not value:
43-
raise click.ClickException("密码不能为空")
43+
raise click.ClickException("Password cannot be empty")
4444
return hashlib.md5(value.encode()).hexdigest()
4545

4646

4747
def _validate_timezone(value: str) -> str:
48-
"""验证时区"""
48+
"""Validate timezone"""
4949
try:
5050
zoneinfo.ZoneInfo(value)
5151
except Exception:
52-
raise click.ClickException(f"无效的时区: {value},请使用有效的IANA时区名称")
52+
raise click.ClickException(
53+
f"Invalid timezone: {value}. Please use a valid IANA timezone name"
54+
)
5355
return value
5456

5557

5658
def _validate_callback_api_base(value: str) -> str:
57-
"""验证回调接口基址"""
59+
"""Validate callback API base URL"""
5860
if not value.startswith("http://") and not value.startswith("https://"):
59-
raise click.ClickException("回调接口基址必须以 http:// 或 https:// 开头")
61+
raise click.ClickException(
62+
"Callback API base must start with http:// or https://"
63+
)
6064
return value
6165

6266

63-
# 可通过CLI设置的配置项,配置键到验证器函数的映射
67+
# Configuration items settable via CLI, mapping config keys to validator functions
6468
CONFIG_VALIDATORS: dict[str, Callable[[str], Any]] = {
6569
"timezone": _validate_timezone,
6670
"log_level": _validate_log_level,
@@ -72,11 +76,11 @@ def _validate_callback_api_base(value: str) -> str:
7276

7377

7478
def _load_config() -> dict[str, Any]:
75-
"""加载或初始化配置文件"""
79+
"""Load or initialize config file"""
7680
root = get_astrbot_root()
7781
if not check_astrbot_root(root):
7882
raise click.ClickException(
79-
f"{root}不是有效的 AstrBot 根目录,如需初始化请使用 astrbot init",
83+
f"{root} is not a valid AstrBot root directory. Use 'astrbot init' to initialize",
8084
)
8185

8286
config_path = root / "data" / "cmd_config.json"
@@ -91,11 +95,11 @@ def _load_config() -> dict[str, Any]:
9195
try:
9296
return json.loads(config_path.read_text(encoding="utf-8-sig"))
9397
except json.JSONDecodeError as e:
94-
raise click.ClickException(f"配置文件解析失败: {e!s}")
98+
raise click.ClickException(f"Failed to parse config file: {e!s}")
9599

96100

97101
def _save_config(config: dict[str, Any]) -> None:
98-
"""保存配置文件"""
102+
"""Save config file"""
99103
config_path = get_astrbot_root() / "data" / "cmd_config.json"
100104

101105
config_path.write_text(
@@ -105,21 +109,21 @@ def _save_config(config: dict[str, Any]) -> None:
105109

106110

107111
def _set_nested_item(obj: dict[str, Any], path: str, value: Any) -> None:
108-
"""设置嵌套字典中的值"""
112+
"""Set a value in a nested dictionary"""
109113
parts = path.split(".")
110114
for part in parts[:-1]:
111115
if part not in obj:
112116
obj[part] = {}
113117
elif not isinstance(obj[part], dict):
114118
raise click.ClickException(
115-
f"配置路径冲突: {'.'.join(parts[: parts.index(part) + 1])} 不是字典",
119+
f"Config path conflict: {'.'.join(parts[: parts.index(part) + 1])} is not a dict",
116120
)
117121
obj = obj[part]
118122
obj[parts[-1]] = value
119123

120124

121125
def _get_nested_item(obj: dict[str, Any], path: str) -> Any:
122-
"""获取嵌套字典中的值"""
126+
"""Get a value from a nested dictionary"""
123127
parts = path.split(".")
124128
for part in parts:
125129
obj = obj[part]
@@ -128,31 +132,31 @@ def _get_nested_item(obj: dict[str, Any], path: str) -> Any:
128132

129133
@click.group(name="conf")
130134
def conf() -> None:
131-
"""配置管理命令
135+
"""Configuration management commands
132136
133-
支持的配置项:
137+
Supported config keys:
134138
135-
- timezone: 时区设置 (例如: Asia/Shanghai)
139+
- timezone: Timezone setting (e.g. Asia/Shanghai)
136140
137-
- log_level: 日志级别 (DEBUG/INFO/WARNING/ERROR/CRITICAL)
141+
- log_level: Log level (DEBUG/INFO/WARNING/ERROR/CRITICAL)
138142
139-
- dashboard.port: Dashboard 端口
143+
- dashboard.port: Dashboard port
140144
141-
- dashboard.username: Dashboard 用户名
145+
- dashboard.username: Dashboard username
142146
143-
- dashboard.password: Dashboard 密码
147+
- dashboard.password: Dashboard password
144148
145-
- callback_api_base: 回调接口基址
149+
- callback_api_base: Callback API base URL
146150
"""
147151

148152

149153
@conf.command(name="set")
150154
@click.argument("key")
151155
@click.argument("value")
152156
def set_config(key: str, value: str) -> None:
153-
"""设置配置项的值"""
157+
"""Set the value of a config item"""
154158
if key not in CONFIG_VALIDATORS:
155-
raise click.ClickException(f"不支持的配置项: {key}")
159+
raise click.ClickException(f"Unsupported config key: {key}")
156160

157161
config = _load_config()
158162

@@ -162,41 +166,41 @@ def set_config(key: str, value: str) -> None:
162166
_set_nested_item(config, key, validated_value)
163167
_save_config(config)
164168

165-
click.echo(f"配置已更新: {key}")
169+
click.echo(f"Config updated: {key}")
166170
if key == "dashboard.password":
167-
click.echo(" 原值: ********")
168-
click.echo(" 新值: ********")
171+
click.echo(" Old value: ********")
172+
click.echo(" New value: ********")
169173
else:
170-
click.echo(f" 原值: {old_value}")
171-
click.echo(f" 新值: {validated_value}")
174+
click.echo(f" Old value: {old_value}")
175+
click.echo(f" New value: {validated_value}")
172176

173177
except KeyError:
174-
raise click.ClickException(f"未知的配置项: {key}")
178+
raise click.ClickException(f"Unknown config key: {key}")
175179
except Exception as e:
176-
raise click.UsageError(f"设置配置失败: {e!s}")
180+
raise click.UsageError(f"Failed to set config: {e!s}")
177181

178182

179183
@conf.command(name="get")
180184
@click.argument("key", required=False)
181185
def get_config(key: str | None = None) -> None:
182-
"""获取配置项的值,不提供key则显示所有可配置项"""
186+
"""Get the value of a config item. If no key is provided, show all configurable items"""
183187
config = _load_config()
184188

185189
if key:
186190
if key not in CONFIG_VALIDATORS:
187-
raise click.ClickException(f"不支持的配置项: {key}")
191+
raise click.ClickException(f"Unsupported config key: {key}")
188192

189193
try:
190194
value = _get_nested_item(config, key)
191195
if key == "dashboard.password":
192196
value = "********"
193197
click.echo(f"{key}: {value}")
194198
except KeyError:
195-
raise click.ClickException(f"未知的配置项: {key}")
199+
raise click.ClickException(f"Unknown config key: {key}")
196200
except Exception as e:
197-
raise click.UsageError(f"获取配置失败: {e!s}")
201+
raise click.UsageError(f"Failed to get config: {e!s}")
198202
else:
199-
click.echo("当前配置:")
203+
click.echo("Current config:")
200204
for key in CONFIG_VALIDATORS:
201205
try:
202206
value = (

astrbot/cli/commands/cmd_init.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,12 @@
88

99

1010
async def initialize_astrbot(astrbot_root: Path) -> None:
11-
"""执行 AstrBot 初始化逻辑"""
11+
"""Execute AstrBot initialization logic"""
1212
dot_astrbot = astrbot_root / ".astrbot"
1313

1414
if not dot_astrbot.exists():
15-
click.echo(f"Current Directory: {astrbot_root}")
16-
click.echo(
17-
"如果你确认这是 Astrbot root directory, 你需要在当前目录下创建一个 .astrbot 文件标记该目录为 AstrBot 的数据目录。",
18-
)
1915
if click.confirm(
20-
f"请检查当前目录是否正确,确认正确请回车: {astrbot_root}",
16+
f"Install AstrBot to this directory? {astrbot_root}",
2117
default=True,
2218
abort=True,
2319
):
@@ -40,7 +36,7 @@ async def initialize_astrbot(astrbot_root: Path) -> None:
4036

4137
@click.command()
4238
def init() -> None:
43-
"""初始化 AstrBot"""
39+
"""Initialize AstrBot"""
4440
click.echo("Initializing AstrBot...")
4541
astrbot_root = get_astrbot_root()
4642
lock_file = astrbot_root / "astrbot.lock"
@@ -49,8 +45,11 @@ def init() -> None:
4945
try:
5046
with lock.acquire():
5147
asyncio.run(initialize_astrbot(astrbot_root))
48+
click.echo("Done! You can now run 'astrbot run' to start AstrBot")
5249
except Timeout:
53-
raise click.ClickException("无法获取锁文件,请检查是否有其他实例正在运行")
50+
raise click.ClickException(
51+
"Cannot acquire lock file. Please check if another instance is running"
52+
)
5453

5554
except Exception as e:
56-
raise click.ClickException(f"初始化失败: {e!s}")
55+
raise click.ClickException(f"Initialization failed: {e!s}")

0 commit comments

Comments
 (0)