diff --git a/cli_launcher.py b/cli_launcher.py
index 1a921053..0ec76e9c 100755
--- a/cli_launcher.py
+++ b/cli_launcher.py
@@ -101,6 +101,7 @@ def clean_project_dir_safe(update_buttons=False, update_img=False):
preserved_paths = {
os.path.join(PROJECT_DIR, "config.py"),
os.path.join(PROJECT_DIR, "handlers", "texts.py"),
+ os.path.join(PROJECT_DIR, ".git"),
}
if not update_buttons:
@@ -205,9 +206,7 @@ def update_from_beta():
f"[cyan]🔢 Локальная версия: {local_version} | Последняя в dev: {remote_version}[/cyan]"
)
if local_version == remote_version:
- if not Confirm.ask(
- "[yellow]❗ Версия актуальна. Обновить всё равно?[/yellow]"
- ):
+ if not Confirm.ask("[yellow]❗ Версия актуальна. Обновить всё равно?[/yellow]"):
return
else:
console.print("[red]⚠️ Не удалось определить версии.[/red]")
@@ -243,6 +242,10 @@ def update_from_beta():
exclude_options += "--exclude=handlers/buttons.py "
subprocess.run(f"rsync -a {exclude_options} {TEMP_DIR}/ {PROJECT_DIR}/", shell=True)
+
+ if os.path.exists(os.path.join(TEMP_DIR, ".git")):
+ subprocess.run(["cp", "-r", os.path.join(TEMP_DIR, ".git"), PROJECT_DIR])
+
subprocess.run(["rm", "-rf", TEMP_DIR])
fix_permissions()
@@ -314,6 +317,10 @@ def update_from_release():
exclude_options += "--exclude=handlers/buttons.py "
subprocess.run(f"rsync -a {exclude_options} {TEMP_DIR}/ {PROJECT_DIR}/", shell=True)
+
+ if os.path.exists(os.path.join(TEMP_DIR, ".git")):
+ subprocess.run(["cp", "-r", os.path.join(TEMP_DIR, ".git"), PROJECT_DIR])
+
subprocess.run(["rm", "-rf", TEMP_DIR])
fix_permissions()
@@ -351,7 +358,7 @@ def show_update_menu():
def show_menu():
table = Table(
- title="Solobot CLI v0.1.8", title_style="bold magenta", header_style="bold blue"
+ title="Solobot CLI v0.1.9", title_style="bold magenta", header_style="bold blue"
)
table.add_column("№", justify="center", style="cyan", no_wrap=True)
table.add_column("Операция", style="white")
diff --git a/servers.py b/servers.py
index 589fa3cc..e49df5f1 100644
--- a/servers.py
+++ b/servers.py
@@ -1,6 +1,7 @@
import asyncio
import re
from datetime import datetime, timedelta
+import ssl
from aiogram.types import InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
@@ -32,16 +33,31 @@ async def ping_server(server_ip: str) -> bool:
async def check_tcp_connection(host: str, port: int) -> bool:
- """Проверяет доступность сервера через TCP (порт 443)."""
+ """Проверяет доступность сервера через TCP с попыткой SSL-соединения."""
try:
- _reader, writer = await asyncio.open_connection(host, port)
+ ssl_context = ssl.create_default_context()
+ reader, writer = await asyncio.open_connection(host, port, ssl=ssl_context)
writer.close()
await writer.wait_closed()
return True
+ except ssl.SSLError as e:
+ logger.warning(f"[SSL Error] Сертификат сервера {host} вызвал ошибку: {e}")
+ await notify_ssl_error(host, str(e))
+ return False
except Exception:
return False
+async def notify_ssl_error(server_host: str, error_text: str):
+ message = (
+ f"⚠️ Ошибка SSL на сервере {server_host}\n\n"
+ f"Описание: {error_text}\n"
+ "Проверьте корректность сертификата или конфигурации HTTPS."
+ )
+ for admin_id in ADMIN_ID:
+ await bot.send_message(admin_id, message)
+
+
async def notify_admin(server_name: str, status: str, down_duration: timedelta = None):
"""Отправляет уведомление администратору."""
builder = InlineKeyboardBuilder()