Files
AstrBot/astrbot/cli/commands/cmd_init.py
2026-03-18 00:35:29 +08:00

126 lines
4.0 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/.astrbot
ExecStart=/usr/bin/astrbot run --backend-only
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, backend_only: 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 not backend_only and (
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")
@click.option("--backend-only", is_flag=True, help="Only initialize the backend")
def init(yes: bool, backend_only: 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, backend_only=backend_only)
)
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}")