cli-interface
This commit is contained in:
@@ -19,7 +19,7 @@ bot = Bot(token=API_TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTM
|
||||
storage = MemoryStorage()
|
||||
dp = Dispatcher(bot=bot, storage=storage)
|
||||
|
||||
version = "4.1-beta(02)"
|
||||
version = "4.1-preRelease"
|
||||
|
||||
register_middleware(dp)
|
||||
|
||||
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import requests
|
||||
from rich.console import Console
|
||||
from rich.prompt import Prompt, Confirm
|
||||
from rich.table import Table
|
||||
from rich.text import Text
|
||||
|
||||
from config import SERVICE_NAME
|
||||
|
||||
try:
|
||||
sys.stdin.reconfigure(encoding='utf-8')
|
||||
sys.stdout.reconfigure(encoding='utf-8')
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if not os.environ.get("LC_ALL", "").endswith("UTF-8"):
|
||||
os.environ["LC_ALL"] = "en_US.UTF-8"
|
||||
os.environ["LANG"] = "en_US.UTF-8"
|
||||
|
||||
BACK_DIR = os.path.expanduser("~/.solobot_backup")
|
||||
TEMP_DIR = os.path.expanduser("~/.solobot_tmp")
|
||||
PROJECT_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
GITHUB_REPO = "https://github.com/Vladless/Solo_bot"
|
||||
|
||||
console = Console()
|
||||
|
||||
|
||||
def print_logo():
|
||||
logo = Text("""
|
||||
███████╗ ██████╗ ██╗ ██████╗ ██████╗ ██████╗ ████████╗
|
||||
██╔════╝██╔═══██╗██║ ██╔═══██╗██╔══██╗██╔═══██╗╚══██╔══╝
|
||||
███████╗██║ ██║██║ ██║ ██║██████╔╝██║ ██║ ██║
|
||||
╚════██║██║ ██║██║ ██║ ██║██╔══██╗██║ ██║ ██║
|
||||
███████║╚██████╔╝███████╗╚██████╔╝██████╔╝╚██████╔╝ ██║
|
||||
╚══════╝ ╚═════╝ ╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝
|
||||
""", style="bold cyan")
|
||||
console.print(logo)
|
||||
|
||||
|
||||
def backup_project():
|
||||
console.print("[yellow]Создаётся резервная копия проекта...[/yellow]")
|
||||
subprocess.run(["rm", "-rf", BACK_DIR])
|
||||
subprocess.run(["cp", "-r", PROJECT_DIR, BACK_DIR])
|
||||
console.print(f"[green]✅ Бэкап сохранён в: {BACK_DIR}[/green]")
|
||||
|
||||
|
||||
def install_git_if_needed():
|
||||
if subprocess.run(["which", "git"], capture_output=True).returncode != 0:
|
||||
console.print("[blue]Установка Git...[/blue]")
|
||||
os.system("sudo apt update && sudo apt install -y git")
|
||||
|
||||
|
||||
def install_dependencies():
|
||||
console.print("[blue]🔧 Установка зависимостей...[/blue]")
|
||||
os.system("source venv/bin/activate && pip install -r requirements.txt")
|
||||
|
||||
|
||||
def restart_service():
|
||||
console.print("[blue]🚀 Перезапуск службы...[/blue]")
|
||||
os.system(f"sudo systemctl restart {SERVICE_NAME}")
|
||||
|
||||
|
||||
def update_from_beta():
|
||||
if not Confirm.ask("[yellow]🔁 Подтвердите обновление Solobot с ветки BETA[/yellow]"):
|
||||
return
|
||||
|
||||
backup_project()
|
||||
install_git_if_needed()
|
||||
|
||||
os.chdir(PROJECT_DIR)
|
||||
git_dir = os.path.join(PROJECT_DIR, ".git")
|
||||
|
||||
if os.path.isdir(git_dir):
|
||||
console.print("[cyan]🔄 Найден .git. Выполняется git pull...[/cyan]")
|
||||
os.system("git reset --hard")
|
||||
os.system("git pull")
|
||||
else:
|
||||
console.print("[cyan]📥 .git не найден. Клонируем репозиторий заново...[/cyan]")
|
||||
subprocess.run(["rm", "-rf", TEMP_DIR])
|
||||
if os.system(f"git clone {GITHUB_REPO} {TEMP_DIR}") != 0:
|
||||
console.print("[red]❌ Ошибка при клонировании. Обновление отменено.[/red]")
|
||||
return
|
||||
subprocess.run(["cp", "-r", f"{TEMP_DIR}/.", PROJECT_DIR])
|
||||
subprocess.run(["rm", "-rf", TEMP_DIR])
|
||||
|
||||
install_dependencies()
|
||||
restart_service()
|
||||
console.print("[green]✅ Обновление с ветки BETA завершено.[/green]")
|
||||
|
||||
|
||||
def update_from_release():
|
||||
if not Confirm.ask("[yellow]🔁 Подтвердите обновление Solobot до последнего релиза[/yellow]"):
|
||||
return
|
||||
|
||||
backup_project()
|
||||
install_git_if_needed()
|
||||
|
||||
try:
|
||||
response = requests.get(
|
||||
"https://api.github.com/repos/Vladless/Solo_bot/releases/latest", timeout=10
|
||||
)
|
||||
tag_name = response.json().get("tag_name")
|
||||
|
||||
if not tag_name:
|
||||
raise ValueError("Не удалось получить тег релиза")
|
||||
|
||||
console.print(f"[cyan]📥 Клонируем релиз {tag_name} во временную папку...[/cyan]")
|
||||
subprocess.run(["rm", "-rf", TEMP_DIR])
|
||||
if os.system(f"git clone --depth 1 --branch {tag_name} {GITHUB_REPO} {TEMP_DIR}") != 0:
|
||||
console.print("[red]❌ Ошибка при клонировании релиза. Обновление отменено.[/red]")
|
||||
return
|
||||
|
||||
subprocess.run(["cp", "-r", f"{TEMP_DIR}/.", PROJECT_DIR])
|
||||
subprocess.run(["rm", "-rf", TEMP_DIR])
|
||||
|
||||
install_dependencies()
|
||||
restart_service()
|
||||
console.print(f"[green]✅ Обновление до релиза {tag_name} завершено.[/green]")
|
||||
|
||||
except Exception as e:
|
||||
console.print(f"[red]❌ Ошибка при обновлении: {e}[/red]")
|
||||
|
||||
|
||||
def show_update_menu():
|
||||
table = Table(title="Выберите способ обновления", title_style="bold green")
|
||||
table.add_column("№", justify="center", style="cyan", no_wrap=True)
|
||||
table.add_column("Источник", style="white")
|
||||
table.add_row("1", "Обновить с BETA (git pull или clone)")
|
||||
table.add_row("2", "Обновить с последнего релиза (GitHub Release)")
|
||||
table.add_row("3", "Назад в меню")
|
||||
|
||||
console.print(table)
|
||||
choice = Prompt.ask("[bold blue]Введите номер[/bold blue]", choices=["1", "2", "3"])
|
||||
|
||||
if choice == "1":
|
||||
update_from_beta()
|
||||
elif choice == "2":
|
||||
update_from_release()
|
||||
|
||||
|
||||
def show_menu():
|
||||
table = Table(title="Solobot CLI", title_style="bold magenta", header_style="bold blue")
|
||||
|
||||
table.add_column("№", justify="center", style="cyan", no_wrap=True)
|
||||
table.add_column("Операция", style="white")
|
||||
|
||||
table.add_row("1", "Запустить бота (systemd)")
|
||||
table.add_row("2", "Запустить напрямую: venv/bin/python main.py")
|
||||
table.add_row("3", "Перезапустить бота (systemd)")
|
||||
table.add_row("4", "Остановить бота (systemd)")
|
||||
table.add_row("5", "Показать логи (50 строк)")
|
||||
table.add_row("6", "Показать статус")
|
||||
table.add_row("7", "Обновить Solobot")
|
||||
table.add_row("8", "Выход")
|
||||
|
||||
console.print(table)
|
||||
|
||||
|
||||
def main():
|
||||
if os.geteuid() != 0:
|
||||
console.print("[bold red]⛔ Требуется запуск от имени root или через sudo.[/bold red]")
|
||||
sys.exit(1)
|
||||
|
||||
os.chdir(PROJECT_DIR)
|
||||
|
||||
print_logo()
|
||||
|
||||
while True:
|
||||
show_menu()
|
||||
choice = Prompt.ask("[bold blue]Введите номер действия[/bold blue]", choices=[str(i) for i in range(1, 9)])
|
||||
|
||||
if choice == "1":
|
||||
os.system(f"sudo systemctl start {SERVICE_NAME}")
|
||||
elif choice == "2":
|
||||
if Confirm.ask("[green]Вы действительно хотите запустить main.py вручную?[/green]"):
|
||||
os.system("sudo venv/bin/python main.py")
|
||||
elif choice == "3":
|
||||
if Confirm.ask("[yellow]Вы действительно хотите перезапустить бота?[/yellow]"):
|
||||
os.system(f"sudo systemctl restart {SERVICE_NAME}")
|
||||
elif choice == "4":
|
||||
if Confirm.ask("[red]Вы уверены, что хотите остановить бота?[/red]"):
|
||||
os.system(f"sudo systemctl stop {SERVICE_NAME}")
|
||||
elif choice == "5":
|
||||
os.system(f"sudo journalctl -u {SERVICE_NAME} -n 50 --no-pager")
|
||||
elif choice == "6":
|
||||
os.system(f"sudo systemctl status {SERVICE_NAME}")
|
||||
elif choice == "7":
|
||||
show_update_menu()
|
||||
elif choice == "8":
|
||||
console.print("[bold cyan]👋 Выход из CLI. Удачного дня![/bold cyan]")
|
||||
break
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
File diff suppressed because it is too large
Load Diff
Executable → Regular
BIN
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Executable → Regular
BIN
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Executable → Regular
BIN
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Executable → Regular
BIN
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Executable → Regular
BIN
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Executable → Regular
BIN
Binary file not shown.
@@ -45,3 +45,4 @@ yookassa==3.3.0
|
||||
httpx
|
||||
qrcode
|
||||
pillow
|
||||
rich
|
||||
Reference in New Issue
Block a user