Files
AstrBot/astrbot/cli/commands/cmd_init.py
LIghtJUNction 976398d1f2 feat(cli): enhance backup capabilities and refactor path management
- Introduce 'astrbot bk' command with GPG signing, encryption, and digest support
- Add import/export functionality using core backup modules
- Refactor path management to use 'AstrbotPaths' singleton across CLI commands
- Replace blocking subprocess calls with asyncio.create_subprocess_exec in backup command
- Add comprehensive tests for uninstall and backup commands
- Improve module resource handling for bundled dashboard assets
2026-03-17 18:32:32 +08:00

117 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import asyncio
import platform
import shutil
import subprocess
from pathlib import Path
import click
from filelock import FileLock, Timeout
from astrbot.core.utils.astrbot_path import astrbot_paths
from ..utils import check_dashboard
SYSTEMD_SERVICE = r"""
# user service
[Unit]
Description=AstrBot Service
Documentation=https://github.com/AstrBotDevs/AstrBot
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
WorkingDirectory=%h/.local/share/astrbot
ExecStart=/usr/bin/sh -c '/usr/bin/astrbot run || { /usr/bin/astrbot init && /usr/bin/astrbot run; }'
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=astrbot-%u
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=default.target
"""
async def initialize_astrbot(astrbot_root: Path, *, yes: bool) -> None:
"""Execute AstrBot initialization logic"""
dot_astrbot = astrbot_root / ".astrbot"
if not dot_astrbot.exists():
if yes or click.confirm(
f"Install AstrBot to this directory? {astrbot_root}",
default=True,
abort=True,
):
dot_astrbot.touch()
click.echo(f"Created {dot_astrbot}")
paths = {
"data": astrbot_root / "data",
"config": astrbot_root / "data" / "config",
"plugins": astrbot_root / "data" / "plugins",
"temp": astrbot_root / "data" / "temp",
}
for name, path in paths.items():
path.mkdir(parents=True, exist_ok=True)
click.echo(
f"{'Created' if not path.exists() else f'{name} Directory exists'}: {path}"
)
if yes or click.confirm(
"是否需要集成式 WebUI个人电脑推荐服务器不推荐",
default=True,
):
await check_dashboard(astrbot_root)
else:
click.echo("你可以使用在线面版v4.14.4+),填写后端地址的方式来控制。")
@click.command()
@click.option("--yes", "-y", is_flag=True, help="Skip confirmation prompts")
def init(yes: bool) -> None:
"""Initialize AstrBot"""
click.echo("Initializing AstrBot...")
# 检查当前系统是否为 Linux 且存在 systemd
if platform.system() == "Linux" and shutil.which("systemctl"):
if yes or click.confirm(
"Detected Linux with systemd. Install AstrBot user service?", default=True
):
user_config_dir = Path.home() / ".config" / "systemd" / "user"
user_config_dir.mkdir(parents=True, exist_ok=True)
service_path = user_config_dir / "astrbot.service"
service_path.write_text(SYSTEMD_SERVICE)
click.echo(f"Created service file at {service_path}")
try:
subprocess.run(["systemctl", "--user", "daemon-reload"], check=True)
click.echo("Systemd daemon reloaded.")
click.echo("Management commands:")
click.echo(" Start: systemctl --user start astrbot")
click.echo(" Stop: systemctl --user stop astrbot")
click.echo(" Enable: systemctl --user enable astrbot")
click.echo(" Log: journalctl --user -u astrbot -f")
except subprocess.CalledProcessError as e:
click.echo(f"Failed to reload systemd daemon: {e}", err=True)
astrbot_root = astrbot_paths.root
lock_file = astrbot_root / "astrbot.lock"
lock = FileLock(lock_file, timeout=5)
try:
with lock.acquire():
asyncio.run(initialize_astrbot(astrbot_root, yes=yes))
click.echo("Done! You can now run 'astrbot run' to start AstrBot")
except Timeout:
raise click.ClickException(
"Cannot acquire lock file. Please check if another instance is running"
)
except Exception as e:
raise click.ClickException(f"Initialization failed: {e!s}")