Обновление зависимостей, устранение хардкода, оплата через Telegram
Библиотеки: - миграция с aiogram 2.25.2 (EOL) на aiogram 3.31: aiohttp обновился с 3.8.6 до 3.14.3, так как aiogram 2 жёстко требовал aiohttp<3.9 - самодельный словарь состояний заменён на FSM aiogram (MemoryStorage); это убирает падение на user_state.startswith(), когда состояния нет - из requirements убраны неиспользуемые пакеты (Babel 2.9.1, humanize, aiofiles, yookassa, YooMoney); оставлены только прямые зависимости Хардкод: - пути вычисляются от расположения файлов бота (awg/config.py), больше нет привязки к /root/amnezia-bot и к запуску из конкретного каталога - вместо 'python3.11' используется sys.executable; awg-decode.py переименован в awg_decode.py и импортируется напрямую вместо запуска через subprocess - newclient.sh и removeclient.sh определяют каталог по своему расположению, а не по cwd - install.sh: каталог, репозиторий, ветка и Python настраиваются переменными окружения, зависимости ставятся из requirements.txt - секреты можно задавать переменными окружения вместо config.json Оплата (встроенные платежи Telegram, провайдер ЮKassa): - счёт, pre_checkout_query и successful_payment; публичный HTTPS-адрес и вебхук не нужны - обработчик платежей вынесен в отдельный роутер и подключён первым: successful_payment приходит без текста и иначе перехватывался бы обработчиком, ожидающим ввода в FSM - выдача ключа идемпотентна по id платежа, повторная доставка апдейта не создаёт второй ключ - если после оплаты ключ создать не удалось, уведомляются администраторы - промокоды разделены на validate/consume: использование засчитывается только после фактической выдачи ключа, а не при проверке кода - поддержаны скидочные промокоды, уменьшающие сумму счёта - опциональные чеки по 54-ФЗ через provider_data Исправленные ошибки: - db.root_add и db.deactive_user_db передавали скриптам 2 аргумента вместо 4, из-за чего создание и удаление клиентов всегда падало; публичный ключ для удаления теперь вычисляется из конфига клиента - в create_backup не был импортирован zipfile (NameError при бэкапе) - планировщик запускался без задач, подписки никогда не истекали; добавлена ежечасная проверка с отключением доступа и уведомлением - callback_data вида renew_period_<имя>_<период> разбирался неверно для имён с подчёркиваниями; разделителем стало двоеточие - статус клиента брался из status.json, который никто не создавал; теперь используется wg show latest-handshakes - продление подписки сбрасывало остаток, теперь период добавляется к нему - Markdown-разметка ломалась на именах с подчёркиваниями; используется HTML с экранированием - vpn:// ключ уходит отдельным сообщением, а не в подписи к файлу, где мог не поместиться в лимит 1024 символа - блокирующие вызовы docker и скриптов вынесены в отдельные потоки - при удалении клиента связь с Telegram ID удаляется, а не пишется None Удалён мёртвый код: awg/wg.py (нигде не импортировался, содержал подсеть 10.0.0.0/24 вместо используемой 10.8.1.0/24) и handlers/add_client.py (импортировал несуществующий модуль loader).
Этот коммит содержится в:
+56
-30
@@ -1,10 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Конфигурация
|
||||
SERVICE_NAME="awg_bot"
|
||||
REPO_URL="https://github.com/stevefoxru/amnezia-bot.git"
|
||||
REPO_API="https://api.github.com/repos/stevefoxru/amnezia-bot"
|
||||
LOCAL_VERSION_FILE="/root/amnezia-bot/.version"
|
||||
# Конфигурация. Любое значение можно переопределить переменной окружения.
|
||||
SERVICE_NAME="${AWG_SERVICE_NAME:-awg_bot}"
|
||||
|
||||
# Каталог установки бота (по умолчанию — как в прежних версиях).
|
||||
BASE_DIR="${AWG_BOT_HOME:-/root/amnezia-bot}"
|
||||
PARENT_DIR="$(dirname "$BASE_DIR")"
|
||||
BOT_DIRNAME="$(basename "$BASE_DIR")"
|
||||
|
||||
# Репозиторий: берём origin уже установленной копии, иначе значение по умолчанию.
|
||||
DEFAULT_REPO_URL="https://github.com/viktor138irk/amnezia-bot.git"
|
||||
if [[ -z "$AWG_REPO_URL" && -d "$BASE_DIR/.git" ]]; then
|
||||
AWG_REPO_URL="$(git -C "$BASE_DIR" remote get-url origin 2>/dev/null)"
|
||||
fi
|
||||
REPO_URL="${AWG_REPO_URL:-$DEFAULT_REPO_URL}"
|
||||
REPO_BRANCH="${AWG_REPO_BRANCH:-main}"
|
||||
# https://github.com/<owner>/<repo>.git -> https://api.github.com/repos/<owner>/<repo>
|
||||
REPO_API="https://api.github.com/repos/$(echo "$REPO_URL" | sed -E 's#^.*github\.com[:/]##; s#\.git$##')"
|
||||
LOCAL_VERSION_FILE="$BASE_DIR/.version"
|
||||
|
||||
# Python: нужен 3.10+, конкретная минорная версия не важна.
|
||||
PYTHON_BIN="${AWG_PYTHON_BIN:-}"
|
||||
if [[ -z "$PYTHON_BIN" ]]; then
|
||||
for candidate in python3.13 python3.12 python3.11 python3.10 python3; do
|
||||
if command -v "$candidate" &>/dev/null; then PYTHON_BIN="$candidate"; break; fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Цвета для вывода
|
||||
GREEN=$'\033[0;32m'
|
||||
@@ -53,10 +74,10 @@ run_with_spinner() {
|
||||
# Функция проверки обновлений на GitHub
|
||||
check_github_updates() {
|
||||
local current_sha local_sha latest_sha auto_mode="$1"
|
||||
cd /root/amnezia-bot || { echo -e "${RED}Каталог amnezia-bot не найден${NC}"; return 1; }
|
||||
cd "$BASE_DIR" || { echo -e "${RED}Каталог $BASE_DIR не найден${NC}"; return 1; }
|
||||
|
||||
echo -e "${YELLOW}Текущая директория: $(pwd)${NC}"
|
||||
echo -e "${YELLOW}Содержимое /root/amnezia-bot:${NC}"
|
||||
echo -e "${YELLOW}Содержимое $BASE_DIR:${NC}"
|
||||
ls -la
|
||||
|
||||
# Получение текущего SHA коммита
|
||||
@@ -64,7 +85,7 @@ check_github_updates() {
|
||||
|
||||
# Получение последнего коммита через GitHub API
|
||||
if command -v curl &>/dev/null; then
|
||||
latest_sha=$(curl -s "$REPO_API/commits/main" | jq -r '.sha' 2>/dev/null)
|
||||
latest_sha=$(curl -s "$REPO_API/commits/$REPO_BRANCH" | jq -r '.sha' 2>/dev/null)
|
||||
[[ -z "$latest_sha" ]] && { echo -e "${RED}Не удалось получить данные с GitHub${NC}"; cd ..; return 1; }
|
||||
else
|
||||
echo -e "${RED}curl не установлен${NC}"; cd ..; return 1
|
||||
@@ -83,14 +104,14 @@ check_github_updates() {
|
||||
echo -e "${YELLOW}Обнаружены локальные изменения. Сбрасываем их...${NC}"
|
||||
run_with_spinner "Сброс локальных изменений" "git reset --hard && git clean -fd"
|
||||
fi
|
||||
run_with_spinner "Обновление репозитория" "git pull"
|
||||
run_with_spinner "Обновление репозитория" "git pull origin $REPO_BRANCH"
|
||||
echo "$latest_sha" > "$LOCAL_VERSION_FILE"
|
||||
check_script_update
|
||||
# Проверка и создание виртуального окружения, если отсутствует
|
||||
if [[ ! -d "myenv" ]]; then
|
||||
run_with_spinner "Создание виртуального окружения" "python3.11 -m venv myenv"
|
||||
run_with_spinner "Создание виртуального окружения" "$PYTHON_BIN -m venv myenv"
|
||||
fi
|
||||
run_with_spinner "Обновление Python-зависимостей" "source myenv/bin/activate && pip install --upgrade pip && pip install aiogram==2.25.1 aiohttp==3.8.6 apscheduler==3.10.4 humanize==4.9.0 pytz==2023.3.post1 && deactivate"
|
||||
run_with_spinner "Обновление Python-зависимостей" "source myenv/bin/activate && pip install --upgrade pip && pip install -r requirements.txt && deactivate"
|
||||
run_with_spinner "Перезапуск службы" "systemctl restart $SERVICE_NAME"
|
||||
else
|
||||
echo -ne "${BLUE}1) Установить 2) Отменить: ${NC}"; read choice
|
||||
@@ -99,14 +120,14 @@ check_github_updates() {
|
||||
echo -e "${YELLOW}Обнаружены локальные изменения. Сбрасываем их...${NC}"
|
||||
run_with_spinner "Сброс локальных изменений" "git reset --hard && git clean -fd"
|
||||
fi
|
||||
run_with_spinner "Обновление репозитория" "git pull"
|
||||
run_with_spinner "Обновление репозитория" "git pull origin $REPO_BRANCH"
|
||||
echo "$latest_sha" > "$LOCAL_VERSION_FILE"
|
||||
check_script_update
|
||||
# Проверка и создание виртуального окружения, если отсутствует
|
||||
if [[ ! -d "myenv" ]]; then
|
||||
run_with_spinner "Создание виртуального окружения" "python3.11 -m venv myenv"
|
||||
run_with_spinner "Создание виртуального окружения" "$PYTHON_BIN -m venv myenv"
|
||||
fi
|
||||
run_with_spinner "Обновление Python-зависимостей" "source myenv/bin/activate && pip install --upgrade pip && pip install aiogram==2.25.1 aiohttp==3.8.6 apscheduler==3.10.4 humanize==4.9.0 pytz==2023.3.post1 && deactivate"
|
||||
run_with_spinner "Обновление Python-зависимостей" "source myenv/bin/activate && pip install --upgrade pip && pip install -r requirements.txt && deactivate"
|
||||
run_with_spinner "Перезапуск службы" "systemctl restart $SERVICE_NAME"
|
||||
else
|
||||
echo -e "${YELLOW}Обновление отменено${NC}"
|
||||
@@ -118,8 +139,8 @@ check_github_updates() {
|
||||
# Проверка обновления самого скрипта
|
||||
check_script_update() {
|
||||
local temp_script=$(mktemp)
|
||||
if [[ -f "/root/amnezia-bot/install.sh" ]]; then
|
||||
cp "/root/amnezia-bot/install.sh" "$temp_script"
|
||||
if [[ -f "$BASE_DIR/install.sh" ]]; then
|
||||
cp "$BASE_DIR/install.sh" "$temp_script"
|
||||
if ! cmp -s "$SCRIPT_PATH" "$temp_script"; then
|
||||
echo -e "${YELLOW}Обнаружено обновление скрипта install.sh${NC}"
|
||||
run_with_spinner "Обновление скрипта" "mv $temp_script $SCRIPT_PATH && chmod +x $SCRIPT_PATH"
|
||||
@@ -130,8 +151,8 @@ check_script_update() {
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}Скрипт install.sh не найден в репозитории, копируем локальную версию${NC}"
|
||||
cp "$SCRIPT_PATH" "/root/amnezia-bot/install.sh"
|
||||
chmod +x "/root/amnezia-bot/install.sh"
|
||||
cp "$SCRIPT_PATH" "$BASE_DIR/install.sh"
|
||||
chmod +x "$BASE_DIR/install.sh"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -147,7 +168,11 @@ check_updates() {
|
||||
fi
|
||||
|
||||
# Проверка остальных зависимостей
|
||||
for cmd in git curl python3.11; do
|
||||
if [[ -z "$PYTHON_BIN" ]]; then
|
||||
echo -e "${RED}Python 3 не найден. Установите python3 (3.10 или новее).${NC}"
|
||||
exit 1
|
||||
fi
|
||||
for cmd in git curl "$PYTHON_BIN"; do
|
||||
if ! command -v "$cmd" &>/dev/null; then
|
||||
echo -e "${RED}$cmd не установлен. Установите $cmd для продолжения.${NC}"
|
||||
exit 1
|
||||
@@ -161,22 +186,23 @@ check_updates() {
|
||||
fi
|
||||
|
||||
# Проверка и клонирование репозитория, если он отсутствует
|
||||
if [[ ! -d "/root/amnezia-bot/.git" ]]; then
|
||||
echo -e "${YELLOW}Репозиторий не найден. Проверяем /root/amnezia-bot...${NC}"
|
||||
echo -e "${YELLOW}Содержимое /root:${NC}"
|
||||
ls -la /root
|
||||
if [[ -d "/root/amnezia-bot" ]]; then
|
||||
echo -e "${YELLOW}Директория /root/amnezia-bot существует, но не является git-репозиторием. Удаляем её...${NC}"
|
||||
rm -rf /root/amnezia-bot || error_exit "Не удалось удалить поврежденную директорию /root/amnezia-bot"
|
||||
if [[ ! -d "$BASE_DIR/.git" ]]; then
|
||||
echo -e "${YELLOW}Репозиторий не найден. Проверяем $BASE_DIR...${NC}"
|
||||
echo -e "${YELLOW}Содержимое $PARENT_DIR:${NC}"
|
||||
ls -la "$PARENT_DIR"
|
||||
if [[ -d "$BASE_DIR" ]]; then
|
||||
echo -e "${YELLOW}Директория $BASE_DIR существует, но не является git-репозиторием. Удаляем её...${NC}"
|
||||
rm -rf $BASE_DIR || error_exit "Не удалось удалить поврежденную директорию $BASE_DIR"
|
||||
fi
|
||||
echo -e "${YELLOW}Клонируем репозиторий...${NC}"
|
||||
cd /root || error_exit "Не удалось перейти в /root"
|
||||
run_with_spinner "Клонирование репозитория" "git clone $REPO_URL"
|
||||
cd amnezia-bot || error_exit "Не удалось перейти в каталог amnezia-bot"
|
||||
mkdir -p "$PARENT_DIR" || error_exit "Не удалось создать $PARENT_DIR"
|
||||
cd "$PARENT_DIR" || error_exit "Не удалось перейти в $PARENT_DIR"
|
||||
run_with_spinner "Клонирование репозитория" "git clone -b $REPO_BRANCH $REPO_URL $BOT_DIRNAME"
|
||||
cd "$BOT_DIRNAME" || error_exit "Не удалось перейти в каталог $BOT_DIRNAME"
|
||||
if [[ ! -d ".git" ]]; then
|
||||
error_exit "Клонирование репозитория не удалось. Проверьте доступ к $REPO_URL"
|
||||
fi
|
||||
echo -e "${YELLOW}Содержимое /root/amnezia-bot после клонирования:${NC}"
|
||||
echo -e "${YELLOW}Содержимое $BASE_DIR после клонирования:${NC}"
|
||||
ls -la
|
||||
fi
|
||||
check_github_updates "$1"
|
||||
|
||||
Ссылка в новой задаче
Block a user