Compare commits
7 Commits
feature/ch
...
1551b8b29f
| Author | SHA1 | Date | |
|---|---|---|---|
| 1551b8b29f | |||
| 0eabb1bc75 | |||
| 87b6b4480c | |||
| 53dd982e38 | |||
| 27065b0b03 | |||
| 8ec8d942ea | |||
| 438a5b5b05 |
@@ -4,12 +4,17 @@
|
||||
# Telegram Bot Token
|
||||
BOT_TOKEN=8300330445:AAFyxAqtmWsgtSPa_nb-lH3Q4ovmn9Ei6rA
|
||||
|
||||
# PostgreSQL настройки
|
||||
# PostgreSQL настройки для внешней БД
|
||||
# Замените на данные вашего внешнего PostgreSQL сервера
|
||||
POSTGRES_HOST=localhost
|
||||
POSTGRES_PORT=5432
|
||||
POSTGRES_DB=bot_db
|
||||
POSTGRES_USER=trevor
|
||||
POSTGRES_PASSWORD=Cl0ud_1985!
|
||||
|
||||
# Database URL для бота (используется внутри контейнера)
|
||||
# Database URL для бота
|
||||
# Формат: postgresql+asyncpg://user:password@host:port/database
|
||||
# Для внешнего сервера укажите его IP или домен вместо localhost
|
||||
DATABASE_URL=postgresql+asyncpg://trevor:Cl0ud_1985!@localhost:5432/bot_db
|
||||
|
||||
# ID администраторов (через запятую)
|
||||
|
||||
94
Makefile
94
Makefile
@@ -1,5 +1,8 @@
|
||||
# Makefile для телеграм-бота розыгрышей
|
||||
|
||||
# Определяем команду $(DOCKER_COMPOSE) (v2) или docker-compose (v1)
|
||||
DOCKER_COMPOSE := $(shell command -v $(DOCKER_COMPOSE) 2> /dev/null || command -v docker-compose 2> /dev/null)
|
||||
|
||||
.PHONY: help install setup setup-postgres init-db run test clean
|
||||
|
||||
# По умолчанию показываем справку
|
||||
@@ -213,10 +216,27 @@ docker-setup:
|
||||
@mkdir -p logs backups
|
||||
@echo "✅ Настройка завершена!"
|
||||
|
||||
# Проверка Docker и Docker Compose
|
||||
docker-check:
|
||||
@echo "<22> Проверка Docker окружения..."
|
||||
@command -v docker >/dev/null 2>&1 || { echo "❌ Docker не установлен! См. DOCKER_INSTALL.md"; exit 1; }
|
||||
@echo "✅ Docker: $$(docker --version)"
|
||||
@if [ -z "$(DOCKER_COMPOSE)" ]; then \
|
||||
echo "❌ Docker Compose не найден!"; \
|
||||
echo " Установите: sudo apt install docker-compose-plugin"; \
|
||||
echo " Или см. DOCKER_INSTALL.md"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@echo "✅ Docker Compose: $$($(DOCKER_COMPOSE) version)"
|
||||
@docker ps >/dev/null 2>&1 || { echo "❌ Docker daemon не запущен!"; echo " Запустите: sudo systemctl start docker"; exit 1; }
|
||||
@echo "✅ Docker daemon работает"
|
||||
@echo ""
|
||||
@echo "🎉 Все проверки пройдены!"
|
||||
|
||||
# Сборка Docker образа
|
||||
docker-build:
|
||||
docker-build: docker-check
|
||||
@echo "🔨 Сборка Docker образа..."
|
||||
docker-compose build --no-cache
|
||||
$(DOCKER_COMPOSE) build --no-cache
|
||||
|
||||
# Запуск контейнеров в фоновом режиме
|
||||
docker-up:
|
||||
@@ -225,7 +245,7 @@ docker-up:
|
||||
echo "❌ Файл .env.prod не найден! Запустите 'make docker-setup'"; \
|
||||
exit 1; \
|
||||
fi
|
||||
docker-compose --env-file .env.prod up -d
|
||||
$(DOCKER_COMPOSE) --env-file .env.prod up -d
|
||||
@echo "✅ Контейнеры запущены!"
|
||||
@echo "📊 Проверьте статус: make docker-status"
|
||||
@echo "📋 Просмотр логов: make docker-logs"
|
||||
@@ -237,39 +257,39 @@ docker-up-fg:
|
||||
echo "❌ Файл .env.prod не найден! Запустите 'make docker-setup'"; \
|
||||
exit 1; \
|
||||
fi
|
||||
docker-compose --env-file .env.prod up
|
||||
$(DOCKER_COMPOSE) --env-file .env.prod up
|
||||
|
||||
# Остановка контейнеров
|
||||
docker-down:
|
||||
@echo "🛑 Остановка контейнеров..."
|
||||
docker-compose down
|
||||
$(DOCKER_COMPOSE) down
|
||||
@echo "✅ Контейнеры остановлены!"
|
||||
|
||||
# Перезапуск контейнеров
|
||||
docker-restart:
|
||||
@echo "🔄 Перезапуск контейнеров..."
|
||||
docker-compose restart
|
||||
$(DOCKER_COMPOSE) restart
|
||||
@echo "✅ Контейнеры перезапущены!"
|
||||
|
||||
# Просмотр логов бота
|
||||
docker-logs:
|
||||
@echo "📋 Логи бота..."
|
||||
docker-compose logs -f bot
|
||||
$(DOCKER_COMPOSE) logs -f bot
|
||||
|
||||
# Просмотр логов базы данных
|
||||
docker-logs-db:
|
||||
@echo "📋 Логи базы данных..."
|
||||
docker-compose logs -f db
|
||||
$(DOCKER_COMPOSE) logs -f db
|
||||
|
||||
# Просмотр всех логов
|
||||
docker-logs-all:
|
||||
@echo "📋 Все логи..."
|
||||
docker-compose logs -f
|
||||
$(DOCKER_COMPOSE) logs -f
|
||||
|
||||
# Статус контейнеров
|
||||
docker-status:
|
||||
@echo "📊 Статус контейнеров..."
|
||||
@docker-compose ps
|
||||
@$(DOCKER_COMPOSE) ps
|
||||
@echo ""
|
||||
@echo "💾 Использование volumes:"
|
||||
@docker volume ls | grep lottery || echo "Нет volumes"
|
||||
@@ -281,20 +301,20 @@ docker-ps:
|
||||
# Применение миграций в контейнере
|
||||
docker-db-migrate:
|
||||
@echo "⬆️ Применение миграций в контейнере..."
|
||||
docker-compose exec bot alembic upgrade head
|
||||
$(DOCKER_COMPOSE) exec bot alembic upgrade head
|
||||
@echo "✅ Миграции применены!"
|
||||
|
||||
# Подключение к PostgreSQL в контейнере
|
||||
docker-db-shell:
|
||||
@echo "🐘 Подключение к PostgreSQL..."
|
||||
@docker-compose exec db psql -U $${POSTGRES_USER:-lottery_user} -d $${POSTGRES_DB:-lottery_bot_db}
|
||||
@$(DOCKER_COMPOSE) exec db psql -U $${POSTGRES_USER:-lottery_user} -d $${POSTGRES_DB:-lottery_bot_db}
|
||||
|
||||
# Создание бэкапа базы данных
|
||||
docker-db-backup:
|
||||
@echo "💾 Создание бэкапа базы данных..."
|
||||
@mkdir -p backups
|
||||
@BACKUP_FILE=backups/backup_$$(date +%Y%m%d_%H%M%S).sql; \
|
||||
docker-compose exec -T db pg_dump -U $${POSTGRES_USER:-lottery_user} $${POSTGRES_DB:-lottery_bot_db} > $$BACKUP_FILE && \
|
||||
$(DOCKER_COMPOSE) exec -T db pg_dump -U $${POSTGRES_USER:-lottery_user} $${POSTGRES_DB:-lottery_bot_db} > $$BACKUP_FILE && \
|
||||
echo "✅ Бэкап создан: $$BACKUP_FILE"
|
||||
|
||||
# Восстановление из бэкапа
|
||||
@@ -307,7 +327,7 @@ docker-db-restore:
|
||||
@echo "Восстановление из: $(BACKUP)"
|
||||
@read -p "Это удалит текущие данные! Продолжить? [y/N] " confirm; \
|
||||
if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \
|
||||
cat $(BACKUP) | docker-compose exec -T db psql -U $${POSTGRES_USER:-lottery_user} $${POSTGRES_DB:-lottery_bot_db}; \
|
||||
cat $(BACKUP) | $(DOCKER_COMPOSE) exec -T db psql -U $${POSTGRES_USER:-lottery_user} $${POSTGRES_DB:-lottery_bot_db}; \
|
||||
echo "✅ База данных восстановлена!"; \
|
||||
else \
|
||||
echo "❌ Отменено"; \
|
||||
@@ -316,12 +336,12 @@ docker-db-restore:
|
||||
# Открыть shell в контейнере бота
|
||||
docker-shell:
|
||||
@echo "🐚 Открытие shell в контейнере бота..."
|
||||
docker-compose exec bot /bin/bash
|
||||
$(DOCKER_COMPOSE) exec bot /bin/bash
|
||||
|
||||
# Остановка и удаление контейнеров
|
||||
docker-clean:
|
||||
@echo "🧹 Очистка контейнеров..."
|
||||
docker-compose down --remove-orphans
|
||||
$(DOCKER_COMPOSE) down --remove-orphans
|
||||
@echo "✅ Контейнеры удалены!"
|
||||
|
||||
# Полная очистка (включая volumes)
|
||||
@@ -330,7 +350,7 @@ docker-prune:
|
||||
@read -p "Продолжить? [y/N] " confirm; \
|
||||
if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \
|
||||
echo "🗑️ Полная очистка..."; \
|
||||
docker-compose down -v --remove-orphans; \
|
||||
$(DOCKER_COMPOSE) down -v --remove-orphans; \
|
||||
docker system prune -f; \
|
||||
echo "✅ Очистка завершена!"; \
|
||||
else \
|
||||
@@ -340,18 +360,21 @@ docker-prune:
|
||||
# Пересборка и перезапуск
|
||||
docker-rebuild:
|
||||
@echo "🔄 Пересборка и перезапуск..."
|
||||
docker-compose down
|
||||
docker-compose build --no-cache
|
||||
docker-compose --env-file .env.prod up -d
|
||||
$(DOCKER_COMPOSE) down
|
||||
$(DOCKER_COMPOSE) build --no-cache
|
||||
$(DOCKER_COMPOSE) --env-file .env.prod up -d
|
||||
@echo "✅ Готово!"
|
||||
@make docker-logs
|
||||
|
||||
# Быстрое развертывание с нуля
|
||||
docker-deploy:
|
||||
@echo "🚀 Полное развертывание в продакшн..."
|
||||
@echo "🚀 Полное развертывание в продакшн с внешней БД..."
|
||||
@make docker-setup
|
||||
@echo ""
|
||||
@echo "⚠️ Перед продолжением убедитесь, что отредактировали .env.prod!"
|
||||
@echo "⚠️ Перед продолжением:"
|
||||
@echo " 1. Настройте внешний PostgreSQL (см. EXTERNAL_DB_SETUP.md)"
|
||||
@echo " 2. Отредактируйте .env.prod с параметрами внешней БД"
|
||||
@echo ""
|
||||
@read -p "Продолжить развертывание? [y/N] " confirm; \
|
||||
if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \
|
||||
make docker-build; \
|
||||
@@ -364,4 +387,29 @@ docker-deploy:
|
||||
make docker-status; \
|
||||
else \
|
||||
echo "❌ Отменено"; \
|
||||
fi
|
||||
fi
|
||||
|
||||
# Проверка подключения к внешней БД
|
||||
docker-test-db:
|
||||
@echo "🔍 Проверка подключения к БД..."
|
||||
@docker exec -it lottery_bot python -c "\
|
||||
from src.core.database import engine; \
|
||||
import asyncio; \
|
||||
print('✅ Подключение успешно!'); \
|
||||
asyncio.run(engine.dispose())" || echo "❌ Ошибка подключения!"
|
||||
|
||||
# Информация о настройке внешней БД
|
||||
docker-external-db-help:
|
||||
@echo "📖 Настройка внешнего PostgreSQL"
|
||||
@echo "=================================="
|
||||
@echo ""
|
||||
@echo "Полная документация: EXTERNAL_DB_SETUP.md"
|
||||
@echo ""
|
||||
@echo "Быстрый старт:"
|
||||
@echo " 1. Создайте БД на внешнем сервере"
|
||||
@echo " 2. Отредактируйте .env.prod:"
|
||||
@echo " DATABASE_URL=postgresql+asyncpg://user:pass@host:5432/db"
|
||||
@echo " 3. make docker-deploy"
|
||||
@echo ""
|
||||
@echo "Проверить подключение:"
|
||||
@echo " make docker-test-db"
|
||||
@@ -1,46 +0,0 @@
|
||||
╔════════════════════════════════════════════════════════════════╗
|
||||
║ 🤖 УПРАВЛЕНИЕ БОТОМ - ШПАРГАЛКА ║
|
||||
╚════════════════════════════════════════════════════════════════╝
|
||||
|
||||
⚡ БЫСТРЫЕ КОМАНДЫ:
|
||||
|
||||
make bot-start → Запустить бота
|
||||
make bot-stop → Остановить бота
|
||||
make bot-restart → Перезапустить бота
|
||||
make bot-status → Проверить состояние
|
||||
make bot-logs → Смотреть логи (Ctrl+C для выхода)
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
⚠️ ПРОБЛЕМА: Бот не реагирует на команды?
|
||||
|
||||
ПРИЧИНА: Запущено несколько экземпляров бота одновременно
|
||||
|
||||
РЕШЕНИЕ:
|
||||
1. make bot-restart (перезапустит правильно)
|
||||
2. make bot-status (проверит что запущен только один)
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
🔍 ДИАГНОСТИКА:
|
||||
|
||||
Проверить процессы:
|
||||
ps aux | grep "python main.py" | grep -v grep
|
||||
|
||||
(Должна быть ОДНА строка!)
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
📁 ФАЙЛЫ:
|
||||
|
||||
Логи: /tmp/bot_single.log
|
||||
PID: .bot.pid
|
||||
Скрипт: ./bot_control.sh
|
||||
Документ: BOT_MANAGEMENT.md
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
❌ НИКОГДА НЕ ИСПОЛЬЗУЙ: make run (для продакшена)
|
||||
✅ ВСЕГДА ИСПОЛЬЗУЙ: make bot-start
|
||||
|
||||
╚════════════════════════════════════════════════════════════════╝
|
||||
29
README.md
29
README.md
@@ -283,7 +283,34 @@ alembic downgrade -1
|
||||
### Локальное развертывание
|
||||
Следуйте инструкциям по установке выше.
|
||||
|
||||
### Docker (опционально)
|
||||
### Docker с внешним PostgreSQL
|
||||
|
||||
Бот настроен для работы с внешним PostgreSQL сервером.
|
||||
|
||||
**Быстрый старт:**
|
||||
|
||||
1. Настройте внешнюю PostgreSQL БД (см. [EXTERNAL_DB_SETUP.md](./EXTERNAL_DB_SETUP.md))
|
||||
|
||||
2. Отредактируйте `.env.prod`:
|
||||
```env
|
||||
DATABASE_URL=postgresql+asyncpg://user:password@your_db_host:5432/lottery_bot
|
||||
BOT_TOKEN=your_bot_token
|
||||
ADMIN_IDS=123456789,987654321
|
||||
```
|
||||
|
||||
3. Запустите бота:
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
4. Примените миграции:
|
||||
```bash
|
||||
docker exec -it lottery_bot alembic upgrade head
|
||||
```
|
||||
|
||||
**Подробная документация:** [EXTERNAL_DB_SETUP.md](./EXTERNAL_DB_SETUP.md)
|
||||
|
||||
### Docker (старая версия с локальной БД)
|
||||
```dockerfile
|
||||
FROM python:3.11-slim
|
||||
WORKDIR /app
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Проверка схемы базы данных
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
|
||||
from src.core.database import engine
|
||||
from sqlalchemy import text
|
||||
|
||||
async def check_database_schema():
|
||||
"""Проверка схемы базы данных"""
|
||||
print("🔍 Проверяем схему базы данных...")
|
||||
|
||||
async with engine.begin() as conn:
|
||||
# Проверяем колонки таблицы users
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name, data_type, is_nullable "
|
||||
"FROM information_schema.columns "
|
||||
"WHERE table_name = 'users' AND table_schema = 'public' "
|
||||
"ORDER BY column_name;"
|
||||
))
|
||||
|
||||
print("\n📊 Колонки в таблице 'users':")
|
||||
print("-" * 50)
|
||||
|
||||
columns = result.fetchall()
|
||||
for column_name, data_type, is_nullable in columns:
|
||||
nullable = "NULL" if is_nullable == "YES" else "NOT NULL"
|
||||
print(f" {column_name:<20} {data_type:<15} {nullable}")
|
||||
|
||||
# Проверяем, есть ли поле phone
|
||||
phone_exists = any(col[0] == 'phone' for col in columns)
|
||||
if phone_exists:
|
||||
print("\n✅ Поле 'phone' найдено в базе данных")
|
||||
else:
|
||||
print("\n❌ Поле 'phone' НЕ найдено в базе данных")
|
||||
|
||||
# Проверяем, есть ли поле verification_code
|
||||
verification_code_exists = any(col[0] == 'verification_code' for col in columns)
|
||||
if verification_code_exists:
|
||||
print("✅ Поле 'verification_code' найдено в базе данных")
|
||||
else:
|
||||
print("❌ Поле 'verification_code' НЕ найдено в базе данных")
|
||||
|
||||
async def main():
|
||||
"""Основная функция"""
|
||||
try:
|
||||
await check_database_schema()
|
||||
except Exception as e:
|
||||
print(f"❌ Ошибка при проверке базы данных: {e}")
|
||||
finally:
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -1,100 +0,0 @@
|
||||
85-84-87-41-83-41-63
|
||||
03-15-35-94-83-22-40
|
||||
36-60-34-92-81-48-41
|
||||
97-66-15-47-35-85-59
|
||||
16-76-88-84-05-81-72
|
||||
51-94-46-57-13-01-50
|
||||
50-73-96-63-73-74-24
|
||||
94-13-13-89-83-22-75
|
||||
39-85-17-28-30-43-83
|
||||
60-72-58-00-79-48-54
|
||||
29-43-78-41-85-88-89
|
||||
12-95-36-23-38-10-06
|
||||
48-64-41-80-09-73-05
|
||||
23-24-48-78-27-46-23
|
||||
75-26-85-70-08-44-54
|
||||
48-06-69-72-17-18-85
|
||||
90-86-19-06-42-12-59
|
||||
25-69-98-23-66-87-30
|
||||
07-42-11-95-24-00-89
|
||||
01-36-94-83-70-99-72
|
||||
03-73-60-40-05-98-20
|
||||
49-09-08-82-43-55-34
|
||||
42-99-12-21-99-08-03
|
||||
23-46-32-24-11-78-27
|
||||
23-03-83-99-03-22-33
|
||||
48-06-78-22-76-02-51
|
||||
62-44-30-46-41-65-49
|
||||
19-29-95-47-06-40-14
|
||||
15-25-76-63-12-04-30
|
||||
62-44-62-85-26-11-28
|
||||
01-52-72-62-41-69-09
|
||||
15-13-82-39-71-48-08
|
||||
62-34-87-77-30-28-16
|
||||
81-21-09-65-26-16-72
|
||||
50-21-82-08-57-81-17
|
||||
29-23-02-52-28-27-51
|
||||
13-88-88-89-68-44-08
|
||||
29-23-68-44-73-98-87
|
||||
32-45-19-09-32-21-07
|
||||
00-07-34-21-79-82-21
|
||||
71-48-00-71-76-37-60
|
||||
58-83-40-36-55-92-79
|
||||
79-21-14-76-38-94-49
|
||||
80-68-03-20-28-36-87
|
||||
61-06-20-44-19-50-27
|
||||
02-71-09-46-02-77-01
|
||||
97-02-89-39-51-57-45
|
||||
90-90-25-70-96-57-78
|
||||
12-31-23-39-22-19-49
|
||||
05-32-23-84-24-00-09
|
||||
53-78-44-05-69-82-19
|
||||
29-77-88-44-31-29-36
|
||||
34-73-69-69-53-59-25
|
||||
71-66-51-35-53-29-95
|
||||
16-95-52-71-19-23-20
|
||||
38-16-67-97-47-29-82
|
||||
87-08-91-20-38-46-32
|
||||
58-74-83-45-82-59-19
|
||||
48-41-67-61-01-96-92
|
||||
76-95-03-63-10-18-39
|
||||
29-32-93-82-25-29-56
|
||||
39-32-31-37-91-78-45
|
||||
00-84-92-88-61-09-66
|
||||
02-61-52-90-79-96-34
|
||||
52-97-20-79-38-86-51
|
||||
76-48-21-82-43-43-80
|
||||
73-21-43-93-39-36-74
|
||||
16-87-26-27-94-22-46
|
||||
64-74-00-76-70-33-26
|
||||
67-41-92-18-56-05-09
|
||||
13-55-02-86-61-16-95
|
||||
68-67-72-43-39-48-71
|
||||
02-20-42-68-50-30-24
|
||||
81-59-13-84-17-42-96
|
||||
93-94-95-35-23-68-02
|
||||
46-88-55-91-39-85-98
|
||||
34-41-63-45-30-75-63
|
||||
73-43-03-86-25-51-40
|
||||
30-76-97-41-02-58-36
|
||||
27-37-86-88-71-97-99
|
||||
07-44-36-19-40-72-04
|
||||
91-55-25-24-73-65-16
|
||||
74-54-91-40-64-42-94
|
||||
36-30-21-26-23-48-68
|
||||
79-83-86-59-11-18-74
|
||||
25-99-97-49-02-63-90
|
||||
56-13-47-96-62-62-16
|
||||
28-52-83-51-16-13-03
|
||||
14-80-79-79-62-70-67
|
||||
54-63-36-53-55-69-20
|
||||
47-84-33-35-58-35-36
|
||||
68-35-65-98-15-89-52
|
||||
01-38-28-66-99-84-39
|
||||
55-97-59-20-47-69-18
|
||||
99-88-32-71-12-42-94
|
||||
33-06-14-42-79-98-95
|
||||
31-19-17-66-90-50-92
|
||||
77-00-02-95-76-47-68
|
||||
88-75-41-20-73-22-22
|
||||
23-18-39-53-89-39-91
|
||||
101
deploy.sh
101
deploy.sh
@@ -1,101 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Скрипт быстрого развертывания бота в продакшн через Docker
|
||||
|
||||
set -e # Остановка при ошибке
|
||||
|
||||
echo "🚀 Быстрое развертывание lottery bot в продакшн"
|
||||
echo "================================================"
|
||||
echo ""
|
||||
|
||||
# Проверка наличия Docker
|
||||
if ! command -v docker &> /dev/null; then
|
||||
echo "❌ Docker не установлен!"
|
||||
echo "Установите Docker: https://docs.docker.com/get-docker/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Проверка наличия Docker Compose
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
echo "❌ Docker Compose не установлен!"
|
||||
echo "Установите Docker Compose: https://docs.docker.com/compose/install/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Docker и Docker Compose установлены"
|
||||
echo ""
|
||||
|
||||
# Проверка .env.prod
|
||||
if [ ! -f .env.prod ]; then
|
||||
echo "⚠️ Файл .env.prod не найден"
|
||||
|
||||
if [ -f .env.prod.example ]; then
|
||||
echo "📄 Создаю .env.prod из примера..."
|
||||
cp .env.prod.example .env.prod
|
||||
echo ""
|
||||
echo "⚠️ ВНИМАНИЕ!"
|
||||
echo "Отредактируйте файл .env.prod и укажите:"
|
||||
echo " - BOT_TOKEN (токен от @BotFather)"
|
||||
echo " - POSTGRES_PASSWORD (надежный пароль для БД)"
|
||||
echo " - DATABASE_URL (обновите пароль в строке подключения)"
|
||||
echo " - ADMIN_IDS (ваш Telegram ID)"
|
||||
echo ""
|
||||
read -p "Нажмите Enter после редактирования .env.prod..."
|
||||
else
|
||||
echo "❌ Файл .env.prod.example не найден!"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "✅ Конфигурация найдена"
|
||||
echo ""
|
||||
|
||||
# Создание необходимых директорий
|
||||
echo "📁 Создание директорий..."
|
||||
mkdir -p logs backups data
|
||||
echo "✅ Директории созданы"
|
||||
echo ""
|
||||
|
||||
# Сборка образа
|
||||
echo "🔨 Сборка Docker образа..."
|
||||
docker-compose build --no-cache
|
||||
echo "✅ Образ собран"
|
||||
echo ""
|
||||
|
||||
# Запуск контейнеров
|
||||
echo "🚀 Запуск контейнеров..."
|
||||
docker-compose --env-file .env.prod up -d
|
||||
echo "✅ Контейнеры запущены"
|
||||
echo ""
|
||||
|
||||
# Ожидание запуска БД
|
||||
echo "⏳ Ожидание запуска базы данных..."
|
||||
sleep 10
|
||||
|
||||
# Применение миграций
|
||||
echo "⬆️ Применение миграций..."
|
||||
docker-compose exec -T bot alembic upgrade head || {
|
||||
echo "⚠️ Миграции не применены (возможно БД уже актуальна)"
|
||||
}
|
||||
echo ""
|
||||
|
||||
# Статус
|
||||
echo "📊 Статус контейнеров:"
|
||||
docker-compose ps
|
||||
echo ""
|
||||
|
||||
# Проверка логов
|
||||
echo "📋 Последние логи бота:"
|
||||
docker-compose logs --tail=20 bot
|
||||
echo ""
|
||||
|
||||
echo "✅ Развертывание завершено!"
|
||||
echo ""
|
||||
echo "📝 Полезные команды:"
|
||||
echo " make docker-logs - Просмотр логов"
|
||||
echo " make docker-status - Статус контейнеров"
|
||||
echo " make docker-restart - Перезапуск"
|
||||
echo " make docker-down - Остановка"
|
||||
echo " make docker-db-backup - Бэкап БД"
|
||||
echo ""
|
||||
echo "🎉 Бот запущен и готов к работе!"
|
||||
@@ -21,9 +21,6 @@ services:
|
||||
- bot_data:/app/data
|
||||
networks:
|
||||
- lottery_network
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "python", "-c", "import sys; sys.exit(0)"]
|
||||
interval: 30s
|
||||
@@ -31,32 +28,7 @@ services:
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
# PostgreSQL Database
|
||||
db:
|
||||
image: postgres:15-alpine
|
||||
container_name: lottery_db
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: ${POSTGRES_DB:-lottery_bot_db}
|
||||
POSTGRES_USER: ${POSTGRES_USER:-lottery_user}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
PGDATA: /var/lib/postgresql/data/pgdata
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
ports:
|
||||
- "5432:5432"
|
||||
networks:
|
||||
- lottery_network
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-lottery_user} -d ${POSTGRES_DB:-lottery_bot_db}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 10s
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
driver: local
|
||||
bot_data:
|
||||
driver: local
|
||||
|
||||
|
||||
118
docs/DEPLOY_QUICKSTART.md
Normal file
118
docs/DEPLOY_QUICKSTART.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# 🚀 Быстрый деплой бота с внешним PostgreSQL
|
||||
|
||||
## Шаг 0: Установка Docker (если не установлен)
|
||||
|
||||
```bash
|
||||
# Проверка Docker
|
||||
docker --version
|
||||
docker compose version
|
||||
|
||||
# Если не установлен - см. DOCKER_INSTALL.md
|
||||
# Или быстрая установка (Ubuntu/Debian):
|
||||
sudo apt update
|
||||
sudo apt install -y docker.io docker-compose-plugin
|
||||
sudo systemctl enable docker
|
||||
sudo systemctl start docker
|
||||
|
||||
# Проверка
|
||||
make docker-check
|
||||
```
|
||||
|
||||
## Шаг 1: Подготовка PostgreSQL
|
||||
|
||||
```bash
|
||||
# Подключитесь к PostgreSQL
|
||||
psql -U postgres
|
||||
|
||||
# Создайте пользователя и БД
|
||||
CREATE USER bot_user WITH PASSWORD 'secure_password_here';
|
||||
CREATE DATABASE lottery_bot OWNER bot_user;
|
||||
GRANT ALL PRIVILEGES ON DATABASE lottery_bot TO bot_user;
|
||||
|
||||
# Выход
|
||||
\q
|
||||
```
|
||||
|
||||
## Шаг 2: Настройка .env.prod
|
||||
|
||||
```bash
|
||||
# Скопируйте пример
|
||||
cp .env.prod.example .env.prod
|
||||
|
||||
# Отредактируйте .env.prod
|
||||
nano .env.prod
|
||||
```
|
||||
|
||||
**Заполните:**
|
||||
```env
|
||||
# Telegram
|
||||
BOT_TOKEN=your_bot_token_from_botfather
|
||||
ADMIN_IDS=123456789,987654321
|
||||
|
||||
# PostgreSQL (замените на свои данные)
|
||||
DATABASE_URL=postgresql+asyncpg://bot_user:secure_password@localhost:5432/lottery_bot
|
||||
```
|
||||
|
||||
## Шаг 3: Деплой
|
||||
|
||||
### Вариант A: Docker (рекомендуется)
|
||||
|
||||
```bash
|
||||
# Билд и запуск
|
||||
make docker-deploy
|
||||
|
||||
# Или вручную:
|
||||
docker-compose build
|
||||
docker-compose up -d
|
||||
docker exec -it lottery_bot alembic upgrade head
|
||||
```
|
||||
|
||||
### Вариант B: Локально
|
||||
|
||||
```bash
|
||||
# Установка
|
||||
make install
|
||||
|
||||
# Миграции
|
||||
source .venv/bin/activate
|
||||
alembic upgrade head
|
||||
|
||||
# Запуск
|
||||
make bot-start
|
||||
```
|
||||
|
||||
## Шаг 4: Проверка
|
||||
|
||||
```bash
|
||||
# Проверить подключение к БД
|
||||
make docker-test-db
|
||||
|
||||
# Логи
|
||||
make docker-logs
|
||||
|
||||
# Статус
|
||||
make docker-status
|
||||
```
|
||||
|
||||
## 📋 Полезные команды
|
||||
|
||||
```bash
|
||||
# Остановка
|
||||
docker-compose down
|
||||
|
||||
# Перезапуск
|
||||
docker-compose restart
|
||||
|
||||
# Логи в реальном времени
|
||||
docker-compose logs -f bot
|
||||
|
||||
# Бэкап БД
|
||||
pg_dump -U bot_user lottery_bot > backup.sql
|
||||
|
||||
# Восстановление БД
|
||||
psql -U bot_user lottery_bot < backup.sql
|
||||
```
|
||||
|
||||
## 🔥 Проблемы?
|
||||
|
||||
См. [EXTERNAL_DB_SETUP.md](./EXTERNAL_DB_SETUP.md) раздел "Troubleshooting"
|
||||
170
docs/DOCKER_INSTALL.md
Normal file
170
docs/DOCKER_INSTALL.md
Normal file
@@ -0,0 +1,170 @@
|
||||
# Установка Docker и Docker Compose
|
||||
|
||||
## Для Ubuntu/Debian
|
||||
|
||||
### Установка Docker
|
||||
|
||||
```bash
|
||||
# Обновление системы
|
||||
sudo apt update
|
||||
sudo apt upgrade -y
|
||||
|
||||
# Установка зависимостей
|
||||
sudo apt install -y ca-certificates curl gnupg lsb-release
|
||||
|
||||
# Добавление GPG ключа Docker
|
||||
sudo install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
sudo chmod a+r /etc/apt/keyrings/docker.gpg
|
||||
|
||||
# Добавление репозитория Docker
|
||||
echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
|
||||
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
|
||||
# Установка Docker Engine
|
||||
sudo apt update
|
||||
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||
|
||||
# Проверка установки
|
||||
docker --version
|
||||
docker compose version
|
||||
```
|
||||
|
||||
### Настройка прав (опционально)
|
||||
|
||||
```bash
|
||||
# Добавить пользователя в группу docker (чтобы не использовать sudo)
|
||||
sudo usermod -aG docker $USER
|
||||
|
||||
# Применить изменения (нужно перелогиниться или выполнить)
|
||||
newgrp docker
|
||||
|
||||
# Проверка
|
||||
docker ps
|
||||
```
|
||||
|
||||
### Автозапуск Docker
|
||||
|
||||
```bash
|
||||
sudo systemctl enable docker
|
||||
sudo systemctl start docker
|
||||
```
|
||||
|
||||
## Для других систем
|
||||
|
||||
### CentOS/RHEL/Fedora
|
||||
|
||||
```bash
|
||||
# Установка Docker
|
||||
sudo yum install -y yum-utils
|
||||
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
|
||||
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||
|
||||
# Запуск
|
||||
sudo systemctl start docker
|
||||
sudo systemctl enable docker
|
||||
```
|
||||
|
||||
### Debian
|
||||
|
||||
```bash
|
||||
# Для Debian используйте те же команды что и для Ubuntu
|
||||
# Но в добавлении репозитория используйте:
|
||||
echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
|
||||
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
```
|
||||
|
||||
## Проверка установки
|
||||
|
||||
```bash
|
||||
# Версия Docker
|
||||
docker --version
|
||||
# Должно вывести: Docker version 24.0.x или новее
|
||||
|
||||
# Версия Docker Compose
|
||||
docker compose version
|
||||
# Должно вывести: Docker Compose version v2.x.x или новее
|
||||
|
||||
# Тест Docker
|
||||
docker run hello-world
|
||||
```
|
||||
|
||||
## Если Docker Compose v1 (старая версия)
|
||||
|
||||
Если у вас установлен `docker-compose` (v1) вместо `docker compose` (v2):
|
||||
|
||||
```bash
|
||||
# Удалите старую версию
|
||||
sudo apt remove docker-compose
|
||||
|
||||
# Установите плагин compose
|
||||
sudo apt install docker-compose-plugin
|
||||
|
||||
# Проверка
|
||||
docker compose version
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Ошибка: "Cannot connect to the Docker daemon"
|
||||
|
||||
```bash
|
||||
# Запустите Docker
|
||||
sudo systemctl start docker
|
||||
|
||||
# Проверьте статус
|
||||
sudo systemctl status docker
|
||||
```
|
||||
|
||||
### Ошибка: "permission denied"
|
||||
|
||||
```bash
|
||||
# Добавьте пользователя в группу docker
|
||||
sudo usermod -aG docker $USER
|
||||
|
||||
# Перелогиньтесь или выполните
|
||||
newgrp docker
|
||||
```
|
||||
|
||||
### Ошибка: "docker-compose: command not found" но Docker Compose установлен
|
||||
|
||||
Makefile автоматически определит правильную команду:
|
||||
- `docker compose` (v2, рекомендуется)
|
||||
- `docker-compose` (v1, устаревшая)
|
||||
|
||||
## Полезные команды
|
||||
|
||||
```bash
|
||||
# Информация о Docker
|
||||
docker info
|
||||
|
||||
# Список запущенных контейнеров
|
||||
docker ps
|
||||
|
||||
# Список всех контейнеров
|
||||
docker ps -a
|
||||
|
||||
# Список образов
|
||||
docker images
|
||||
|
||||
# Очистка неиспользуемых ресурсов
|
||||
docker system prune -a
|
||||
|
||||
# Логи контейнера
|
||||
docker logs container_name
|
||||
|
||||
# Остановить все контейнеры
|
||||
docker stop $(docker ps -aq)
|
||||
|
||||
# Удалить все контейнеры
|
||||
docker rm $(docker ps -aq)
|
||||
```
|
||||
|
||||
## Обновление Docker
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt upgrade docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||
```
|
||||
162
docs/EXTERNAL_DB_SETUP.md
Normal file
162
docs/EXTERNAL_DB_SETUP.md
Normal file
@@ -0,0 +1,162 @@
|
||||
# Настройка внешнего PostgreSQL
|
||||
|
||||
Этот гайд описывает как настроить бота для работы с внешним PostgreSQL сервером.
|
||||
|
||||
## Предварительные требования
|
||||
|
||||
1. Запущенный PostgreSQL сервер (версия 13+)
|
||||
2. Доступ к серверу по сети (если сервер на другой машине)
|
||||
3. Созданная база данных для бота
|
||||
|
||||
## Шаг 1: Подготовка PostgreSQL
|
||||
|
||||
### Создание базы данных и пользователя
|
||||
|
||||
```sql
|
||||
-- Подключитесь к PostgreSQL
|
||||
psql -U postgres
|
||||
|
||||
-- Создайте пользователя
|
||||
CREATE USER bot_user WITH PASSWORD 'your_secure_password';
|
||||
|
||||
-- Создайте базу данных
|
||||
CREATE DATABASE lottery_bot OWNER bot_user;
|
||||
|
||||
-- Выдайте права
|
||||
GRANT ALL PRIVILEGES ON DATABASE lottery_bot TO bot_user;
|
||||
```
|
||||
|
||||
### Настройка доступа (если PostgreSQL на другом сервере)
|
||||
|
||||
Отредактируйте `postgresql.conf`:
|
||||
```conf
|
||||
listen_addresses = '*' # или конкретный IP
|
||||
```
|
||||
|
||||
Отредактируйте `pg_hba.conf`:
|
||||
```conf
|
||||
# Разрешить подключение с определенного IP
|
||||
host lottery_bot bot_user 192.168.1.0/24 md5
|
||||
```
|
||||
|
||||
Перезапустите PostgreSQL:
|
||||
```bash
|
||||
sudo systemctl restart postgresql
|
||||
```
|
||||
|
||||
## Шаг 2: Настройка .env.prod
|
||||
|
||||
Отредактируйте `.env.prod`:
|
||||
|
||||
```env
|
||||
# PostgreSQL настройки
|
||||
POSTGRES_HOST=your_db_server_ip_or_domain
|
||||
POSTGRES_PORT=5432
|
||||
POSTGRES_DB=lottery_bot
|
||||
POSTGRES_USER=bot_user
|
||||
POSTGRES_PASSWORD=your_secure_password
|
||||
|
||||
# Database URL
|
||||
DATABASE_URL=postgresql+asyncpg://bot_user:your_secure_password@your_db_server_ip_or_domain:5432/lottery_bot
|
||||
```
|
||||
|
||||
### Примеры DATABASE_URL
|
||||
|
||||
**Локальная БД:**
|
||||
```
|
||||
DATABASE_URL=postgresql+asyncpg://bot_user:password@localhost:5432/lottery_bot
|
||||
```
|
||||
|
||||
**Удаленная БД:**
|
||||
```
|
||||
DATABASE_URL=postgresql+asyncpg://bot_user:password@192.168.1.100:5432/lottery_bot
|
||||
```
|
||||
|
||||
**С доменом:**
|
||||
```
|
||||
DATABASE_URL=postgresql+asyncpg://bot_user:password@db.example.com:5432/lottery_bot
|
||||
```
|
||||
|
||||
**Через Docker network (если БД в другом контейнере):**
|
||||
```
|
||||
DATABASE_URL=postgresql+asyncpg://bot_user:password@postgres_container:5432/lottery_bot
|
||||
```
|
||||
|
||||
## Шаг 3: Применение миграций
|
||||
|
||||
После настройки подключения примените миграции:
|
||||
|
||||
```bash
|
||||
# Активируйте виртуальное окружение
|
||||
source .venv/bin/activate
|
||||
|
||||
# Примените миграции
|
||||
alembic upgrade head
|
||||
```
|
||||
|
||||
## Шаг 4: Запуск бота
|
||||
|
||||
### С Docker Compose:
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### Локально:
|
||||
```bash
|
||||
make bot-start
|
||||
```
|
||||
|
||||
## Проверка подключения
|
||||
|
||||
Проверьте подключение к БД:
|
||||
|
||||
```bash
|
||||
# Из контейнера
|
||||
docker exec -it lottery_bot python -c "from src.core.database import engine; import asyncio; asyncio.run(engine.dispose())"
|
||||
|
||||
# Локально
|
||||
python -c "from src.core.database import engine; import asyncio; asyncio.run(engine.dispose())"
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Ошибка: "FATAL: password authentication failed"
|
||||
- Проверьте правильность пароля в DATABASE_URL
|
||||
- Убедитесь что пользователь создан в PostgreSQL
|
||||
- Проверьте настройки pg_hba.conf
|
||||
|
||||
### Ошибка: "could not connect to server"
|
||||
- Проверьте что PostgreSQL запущен
|
||||
- Убедитесь что порт 5432 открыт (firewall)
|
||||
- Проверьте listen_addresses в postgresql.conf
|
||||
|
||||
### Ошибка: "database does not exist"
|
||||
- Создайте базу данных (см. Шаг 1)
|
||||
- Проверьте имя БД в DATABASE_URL
|
||||
|
||||
### Ошибка: "SSL connection has been closed unexpectedly"
|
||||
- Добавьте `?ssl=require` или `?ssl=prefer` в конец DATABASE_URL
|
||||
- Или отключите SSL: `?ssl=false`
|
||||
|
||||
## Рекомендации по безопасности
|
||||
|
||||
1. **Используйте сильные пароли** для пользователя БД
|
||||
2. **Ограничьте доступ** только с нужных IP (pg_hba.conf)
|
||||
3. **Используйте SSL** для подключения к удаленной БД
|
||||
4. **Регулярно делайте бэкапы**:
|
||||
```bash
|
||||
pg_dump -U bot_user lottery_bot > backup_$(date +%Y%m%d).sql
|
||||
```
|
||||
5. **Не коммитьте .env.prod** в git (добавлен в .gitignore)
|
||||
|
||||
## Мониторинг
|
||||
|
||||
Проверка состояния подключений:
|
||||
```sql
|
||||
SELECT * FROM pg_stat_activity WHERE datname = 'lottery_bot';
|
||||
```
|
||||
|
||||
Размер базы данных:
|
||||
```sql
|
||||
SELECT pg_size_pretty(pg_database_size('lottery_bot'));
|
||||
```
|
||||
118
fix_db_schema.py
118
fix_db_schema.py
@@ -1,118 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Исправление схемы базы данных
|
||||
Добавление недостающих полей в таблицу users
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
|
||||
from src.core.database import engine
|
||||
from sqlalchemy import text
|
||||
|
||||
async def fix_database_schema():
|
||||
"""Добавление недостающих полей в базу данных"""
|
||||
print("🔧 Исправляем схему базы данных...")
|
||||
|
||||
async with engine.begin() as conn:
|
||||
|
||||
# Проверяем, есть ли поле phone
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'users' AND column_name = 'phone'"
|
||||
))
|
||||
|
||||
if not result.fetchone():
|
||||
print("📞 Добавляем поле 'phone'...")
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE users ADD COLUMN phone VARCHAR(20) NULL"
|
||||
))
|
||||
print("✅ Поле 'phone' добавлено")
|
||||
else:
|
||||
print("✅ Поле 'phone' уже существует")
|
||||
|
||||
# Проверяем, есть ли поле club_card_number
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'users' AND column_name = 'club_card_number'"
|
||||
))
|
||||
|
||||
if not result.fetchone():
|
||||
print("💳 Добавляем поле 'club_card_number'...")
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE users ADD COLUMN club_card_number VARCHAR(50) NULL"
|
||||
))
|
||||
await conn.execute(text(
|
||||
"CREATE UNIQUE INDEX ix_users_club_card_number ON users (club_card_number)"
|
||||
))
|
||||
print("✅ Поле 'club_card_number' добавлено")
|
||||
else:
|
||||
print("✅ Поле 'club_card_number' уже существует")
|
||||
|
||||
# Проверяем, есть ли поле is_registered
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'users' AND column_name = 'is_registered'"
|
||||
))
|
||||
|
||||
if not result.fetchone():
|
||||
print("📝 Добавляем поле 'is_registered'...")
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE users ADD COLUMN is_registered BOOLEAN DEFAULT FALSE NOT NULL"
|
||||
))
|
||||
print("✅ Поле 'is_registered' добавлено")
|
||||
else:
|
||||
print("✅ Поле 'is_registered' уже существует")
|
||||
|
||||
# Проверяем, есть ли поле verification_code
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'users' AND column_name = 'verification_code'"
|
||||
))
|
||||
|
||||
if not result.fetchone():
|
||||
print("🔐 Добавляем поле 'verification_code'...")
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE users ADD COLUMN verification_code VARCHAR(10) NULL"
|
||||
))
|
||||
await conn.execute(text(
|
||||
"CREATE UNIQUE INDEX ix_users_verification_code ON users (verification_code)"
|
||||
))
|
||||
print("✅ Поле 'verification_code' добавлено")
|
||||
else:
|
||||
print("✅ Поле 'verification_code' уже существует")
|
||||
|
||||
# Удаляем поле account_number, если оно есть (оно перенесено в отдельную таблицу)
|
||||
result = await conn.execute(text(
|
||||
"SELECT column_name FROM information_schema.columns "
|
||||
"WHERE table_name = 'users' AND column_name = 'account_number'"
|
||||
))
|
||||
|
||||
if result.fetchone():
|
||||
print("🗑️ Удаляем устаревшее поле 'account_number'...")
|
||||
# Сначала удаляем индекс
|
||||
try:
|
||||
await conn.execute(text("DROP INDEX IF EXISTS ix_users_account_number"))
|
||||
except:
|
||||
pass
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE users DROP COLUMN account_number"
|
||||
))
|
||||
print("✅ Поле 'account_number' удалено")
|
||||
else:
|
||||
print("✅ Поле 'account_number' уже удалено")
|
||||
|
||||
async def main():
|
||||
"""Основная функция"""
|
||||
try:
|
||||
await fix_database_schema()
|
||||
print("\n🎉 Схема базы данных успешно исправлена!")
|
||||
except Exception as e:
|
||||
print(f"❌ Ошибка при исправлении базы данных: {e}")
|
||||
finally:
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -1,76 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Генератор тестовых счетов для проверки производительности розыгрыша
|
||||
"""
|
||||
import random
|
||||
|
||||
|
||||
def generate_account_number():
|
||||
"""Генерирует случайный номер счета в формате XX-XX-XX-XX-XX-XX-XX"""
|
||||
parts = []
|
||||
for _ in range(7):
|
||||
part = f"{random.randint(0, 99):02d}"
|
||||
parts.append(part)
|
||||
return "-".join(parts)
|
||||
|
||||
|
||||
def generate_accounts(count, card_numbers=None):
|
||||
"""
|
||||
Генерирует список уникальных счетов
|
||||
|
||||
Args:
|
||||
count: Количество счетов для генерации
|
||||
card_numbers: Список номеров карт (опционально)
|
||||
|
||||
Returns:
|
||||
List[str]: Список счетов
|
||||
"""
|
||||
accounts = set()
|
||||
|
||||
while len(accounts) < count:
|
||||
account = generate_account_number()
|
||||
|
||||
# Добавляем с картой или без
|
||||
if card_numbers and random.random() > 0.3: # 70% с картой
|
||||
card = random.choice(card_numbers)
|
||||
full_account = f"{card} {account}"
|
||||
else:
|
||||
full_account = account
|
||||
|
||||
accounts.add(full_account)
|
||||
|
||||
return list(accounts)
|
||||
|
||||
|
||||
def save_to_file(accounts, filename):
|
||||
"""Сохраняет счета в файл"""
|
||||
with open(filename, 'w', encoding='utf-8') as f:
|
||||
for account in accounts:
|
||||
f.write(account + '\n')
|
||||
print(f"✅ Сохранено {len(accounts)} счетов в файл {filename}")
|
||||
|
||||
|
||||
def main():
|
||||
"""Главная функция"""
|
||||
print("🎲 Генератор тестовых счетов для розыгрыша\n")
|
||||
|
||||
# Параметры
|
||||
counts = [100, 500, 1000, 2000, 5000]
|
||||
card_numbers = ['2521', '2522', '2523', '2524', '2525']
|
||||
|
||||
for count in counts:
|
||||
print(f"Генерация {count} счетов...")
|
||||
accounts = generate_accounts(count, card_numbers)
|
||||
filename = f"test_accounts_{count}.txt"
|
||||
save_to_file(accounts, filename)
|
||||
|
||||
print("\n✅ Генерация завершена!")
|
||||
print("\nИспользование:")
|
||||
print("1. Скопируйте содержимое нужного файла")
|
||||
print("2. В боте: Управление розыгрышами → Выберите розыгрыш → Участники → Добавить массово")
|
||||
print("3. Вставьте содержимое файла")
|
||||
print("4. Проведите розыгрыш и проверьте время выполнения")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
1427
main_old.py
1427
main_old.py
File diff suppressed because it is too large
Load Diff
@@ -1,97 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Минимальная рабочая версия main.py для лотерейного бота
|
||||
"""
|
||||
from aiogram import Bot, Dispatcher
|
||||
from aiogram.types import BotCommand
|
||||
from aiogram.fsm.storage.memory import MemoryStorage
|
||||
import asyncio
|
||||
import logging
|
||||
import signal
|
||||
import sys
|
||||
|
||||
from src.core.config import BOT_TOKEN, ADMIN_IDS
|
||||
from src.core.database import async_session_maker, init_db
|
||||
|
||||
# Настройка логирования
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Инициализация бота
|
||||
bot = Bot(token=BOT_TOKEN)
|
||||
storage = MemoryStorage()
|
||||
dp = Dispatcher(storage=storage)
|
||||
|
||||
async def set_commands():
|
||||
"""Установка команд бота"""
|
||||
commands = [
|
||||
BotCommand(command="start", description="🚀 Запустить бота"),
|
||||
BotCommand(command="help", description="❓ Помощь"),
|
||||
]
|
||||
await bot.set_my_commands(commands)
|
||||
|
||||
async def main():
|
||||
"""Главная функция"""
|
||||
try:
|
||||
logger.info("🔄 Инициализация базы данных...")
|
||||
await init_db()
|
||||
|
||||
logger.info("🔄 Установка команд...")
|
||||
await set_commands()
|
||||
|
||||
# Импортируем и подключаем роутеры
|
||||
logger.info("🔄 Подключение роутеров...")
|
||||
|
||||
try:
|
||||
from src.handlers.registration_handlers import router as registration_router
|
||||
dp.include_router(registration_router)
|
||||
logger.info("✅ Registration router подключен")
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Ошибка подключения registration router: {e}")
|
||||
|
||||
try:
|
||||
from src.handlers.admin_panel import admin_router
|
||||
dp.include_router(admin_router)
|
||||
logger.info("✅ Admin router подключен")
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Ошибка подключения admin router: {e}")
|
||||
|
||||
try:
|
||||
from src.handlers.account_handlers import account_router
|
||||
dp.include_router(account_router)
|
||||
logger.info("✅ Account router подключен")
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Ошибка подключения account router: {e}")
|
||||
|
||||
# Обработка сигналов для graceful shutdown
|
||||
def signal_handler():
|
||||
logger.info("Получен сигнал завершения, остановка бота...")
|
||||
|
||||
# Настройка обработчиков сигналов
|
||||
if sys.platform != "win32":
|
||||
for sig in (signal.SIGTERM, signal.SIGINT):
|
||||
asyncio.get_event_loop().add_signal_handler(sig, signal_handler)
|
||||
|
||||
# Получаем информацию о боте
|
||||
bot_info = await bot.get_me()
|
||||
logger.info(f"🚀 Бот запущен: @{bot_info.username} ({bot_info.first_name})")
|
||||
|
||||
# Запуск бота
|
||||
await dp.start_polling(bot)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Критическая ошибка: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
finally:
|
||||
logger.info("Завершение работы")
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
asyncio.run(main())
|
||||
except KeyboardInterrupt:
|
||||
logger.info("Бот остановлен пользователем")
|
||||
except Exception as e:
|
||||
logger.error(f"Критическая ошибка: {e}")
|
||||
finally:
|
||||
logger.info("Завершение работы")
|
||||
@@ -6,6 +6,7 @@ from aiogram import Router, F
|
||||
from aiogram.types import (
|
||||
CallbackQuery, Message, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
)
|
||||
from aiogram.exceptions import TelegramBadRequest
|
||||
from aiogram.filters import StateFilter
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.fsm.state import State, StatesGroup
|
||||
@@ -2641,7 +2642,13 @@ async def conduct_lottery_draw_confirm(callback: CallbackQuery):
|
||||
[InlineKeyboardButton(text="❌ Отмена", callback_data=f"admin_lottery_{lottery_id}")]
|
||||
]
|
||||
|
||||
await callback.message.edit_text(text, reply_markup=InlineKeyboardMarkup(inline_keyboard=buttons))
|
||||
try:
|
||||
await callback.message.edit_text(text, reply_markup=InlineKeyboardMarkup(inline_keyboard=buttons))
|
||||
except TelegramBadRequest as e:
|
||||
if "message is not modified" in str(e):
|
||||
await callback.answer("Сообщение уже актуально", show_alert=False)
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
@admin_router.callback_query(F.data.startswith("admin_conduct_confirmed_"))
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
2521 11-22-33-44-55-66-77
|
||||
2521 12-23-34-45-56-67-78
|
||||
2521 13-24-35-46-57-68-79
|
||||
2521 14-25-36-47-58-69-80
|
||||
2521 15-26-37-48-59-70-81
|
||||
2521 16-27-38-49-60-71-82
|
||||
2521 17-28-39-50-61-72-83
|
||||
2521 18-29-40-51-62-73-84
|
||||
2521 19-30-41-52-63-74-85
|
||||
2521 20-31-42-53-64-75-86
|
||||
|
||||
2522 21-32-43-54-65-76-87
|
||||
2522 22-33-44-55-66-77-88
|
||||
2522 23-34-45-56-67-78-89
|
||||
2522 24-35-46-57-68-79-90
|
||||
2522 25-36-47-58-69-80-91
|
||||
2522 26-37-48-59-70-81-92
|
||||
2522 27-38-49-60-71-82-93
|
||||
2522 28-39-50-61-72-83-94
|
||||
2522 29-40-51-62-73-84-95
|
||||
2522 30-41-52-63-74-85-96
|
||||
@@ -1,100 +0,0 @@
|
||||
2524 13-44-65-38-31-54-67
|
||||
2523 31-91-70-64-88-67-03
|
||||
2525 21-87-28-91-13-49-61
|
||||
2523 35-22-65-25-15-99-32
|
||||
2525 12-72-37-11-82-58-23
|
||||
2525 96-39-53-66-81-43-28
|
||||
2522 31-19-65-97-82-87-06
|
||||
2521 54-03-08-21-52-27-86
|
||||
2525 42-85-32-06-39-68-81
|
||||
2522 94-50-44-81-24-67-25
|
||||
28-66-94-77-24-23-40
|
||||
72-64-73-89-62-11-90
|
||||
2522 12-25-21-03-46-98-22
|
||||
2524 54-06-23-93-94-44-50
|
||||
2523 23-61-39-40-29-15-28
|
||||
2525 13-85-23-66-37-16-95
|
||||
2525 97-28-72-80-14-30-78
|
||||
2525 11-69-37-13-79-35-12
|
||||
89-44-47-63-67-54-12
|
||||
2525 07-09-98-78-15-23-50
|
||||
2523 05-03-90-01-62-57-18
|
||||
65-07-18-74-28-42-66
|
||||
2525 39-77-17-98-01-23-29
|
||||
2522 05-50-21-93-79-11-61
|
||||
2525 61-18-20-81-60-90-05
|
||||
2521 15-92-74-93-64-78-54
|
||||
2523 22-21-96-99-90-45-27
|
||||
2521 30-97-48-67-95-75-79
|
||||
2524 39-57-99-03-13-46-35
|
||||
2522 98-54-80-56-33-65-44
|
||||
20-91-91-30-15-65-25
|
||||
98-04-80-73-50-11-42
|
||||
98-34-41-64-88-01-63
|
||||
2525 29-35-02-04-32-78-51
|
||||
2523 62-44-20-56-62-78-01
|
||||
2524 14-36-17-91-34-91-55
|
||||
2524 17-01-76-83-62-31-93
|
||||
04-44-22-26-04-55-87
|
||||
2523 11-43-07-89-40-00-88
|
||||
2521 84-28-72-28-33-60-44
|
||||
2525 95-40-78-88-00-43-13
|
||||
2522 69-21-29-41-81-96-77
|
||||
2524 37-22-41-64-08-13-92
|
||||
2524 73-96-94-27-64-09-09
|
||||
33-27-89-47-46-62-85
|
||||
2523 75-75-48-01-28-10-88
|
||||
72-57-79-14-18-91-23
|
||||
98-32-02-86-87-59-11
|
||||
97-19-28-45-03-08-64
|
||||
2523 74-22-18-22-46-58-94
|
||||
2525 18-13-73-83-02-10-09
|
||||
2523 41-15-99-26-09-14-97
|
||||
2525 43-58-60-55-40-73-67
|
||||
2523 42-97-48-61-70-60-38
|
||||
80-70-44-15-17-55-49
|
||||
2522 76-81-33-86-19-53-45
|
||||
2525 45-94-04-45-89-90-28
|
||||
2522 20-97-12-37-10-83-76
|
||||
2524 34-32-51-50-78-80-97
|
||||
2522 30-97-39-84-02-45-49
|
||||
83-67-91-16-68-14-66
|
||||
94-71-04-28-57-75-45
|
||||
2524 83-82-42-15-67-91-48
|
||||
2523 97-98-88-10-36-79-53
|
||||
41-22-09-70-75-40-57
|
||||
2522 77-94-56-22-88-02-16
|
||||
2525 43-11-72-35-15-47-04
|
||||
2525 35-57-25-41-26-07-37
|
||||
57-06-88-62-15-34-66
|
||||
2525 98-66-63-02-15-71-13
|
||||
58-20-77-41-06-52-33
|
||||
2521 11-98-92-27-38-94-75
|
||||
2525 09-48-71-70-71-41-26
|
||||
2525 79-05-30-49-24-22-33
|
||||
26-70-94-22-64-89-48
|
||||
2524 34-71-40-14-68-80-57
|
||||
18-87-93-44-52-37-69
|
||||
2524 09-39-78-85-80-17-81
|
||||
2521 32-08-76-43-59-61-14
|
||||
2523 93-56-87-85-14-53-72
|
||||
2521 78-51-66-89-56-33-49
|
||||
2522 20-24-45-32-47-44-53
|
||||
41-37-43-28-56-43-54
|
||||
2525 95-88-82-26-44-81-83
|
||||
95-26-50-93-40-82-27
|
||||
2521 32-43-09-99-96-51-73
|
||||
2522 62-54-92-00-89-19-66
|
||||
2525 28-53-29-95-71-21-66
|
||||
2523 68-33-54-40-40-99-32
|
||||
2523 60-51-93-71-70-19-35
|
||||
2524 01-72-11-22-48-64-15
|
||||
80-56-98-36-74-46-98
|
||||
2524 08-02-36-94-18-37-27
|
||||
2524 33-98-00-04-99-88-91
|
||||
2523 90-77-79-06-91-29-07
|
||||
2521 63-16-29-62-15-87-98
|
||||
2522 61-37-16-90-50-14-83
|
||||
2521 52-13-01-97-57-81-05
|
||||
29-11-89-59-59-44-05
|
||||
96-42-02-79-02-80-82
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,500 +0,0 @@
|
||||
2524 88-62-46-84-72-08-35
|
||||
2522 10-22-27-22-58-78-17
|
||||
51-13-02-75-49-33-24
|
||||
70-89-01-27-80-15-07
|
||||
34-92-77-76-25-70-93
|
||||
38-32-72-86-17-33-56
|
||||
87-60-70-50-25-91-84
|
||||
2523 21-14-04-05-19-46-25
|
||||
2524 89-84-04-85-69-48-11
|
||||
2524 50-35-99-27-26-02-20
|
||||
2523 28-62-92-35-74-98-25
|
||||
2522 93-14-72-96-97-42-96
|
||||
2525 25-30-32-74-67-29-85
|
||||
2521 36-86-88-64-61-88-89
|
||||
2522 44-74-59-58-15-14-89
|
||||
01-30-55-20-38-31-72
|
||||
71-18-33-96-66-96-26
|
||||
2524 94-32-58-56-35-13-97
|
||||
2523 28-87-80-20-45-21-05
|
||||
2524 72-50-32-62-44-95-03
|
||||
2522 25-60-16-18-19-11-70
|
||||
98-79-01-28-64-95-66
|
||||
96-26-10-27-17-87-71
|
||||
23-99-31-56-74-73-76
|
||||
88-78-77-67-55-73-96
|
||||
95-27-40-11-78-13-64
|
||||
81-54-62-27-54-62-69
|
||||
31-94-80-51-25-36-79
|
||||
2524 44-10-96-63-84-30-07
|
||||
2522 53-36-32-70-62-28-43
|
||||
2523 60-82-65-57-94-68-25
|
||||
2523 90-62-99-58-03-02-57
|
||||
84-93-24-28-61-92-83
|
||||
38-97-88-51-57-47-91
|
||||
2522 97-18-71-19-17-46-11
|
||||
74-25-19-72-73-69-05
|
||||
2523 96-41-78-01-63-40-13
|
||||
2525 93-75-84-73-30-84-68
|
||||
2523 29-78-54-03-00-21-31
|
||||
2524 74-45-78-17-55-77-54
|
||||
2525 42-11-31-48-56-32-88
|
||||
2525 69-47-22-59-62-43-20
|
||||
2523 01-22-13-57-05-25-44
|
||||
2525 59-22-43-08-53-48-82
|
||||
2525 32-15-12-73-96-25-50
|
||||
2525 90-04-74-22-33-88-10
|
||||
2522 30-32-71-15-43-34-55
|
||||
30-92-54-05-94-53-54
|
||||
2525 29-58-08-99-46-04-29
|
||||
46-27-64-43-09-37-58
|
||||
2525 77-95-40-98-58-08-54
|
||||
2525 02-66-43-02-60-18-34
|
||||
16-37-17-50-65-63-51
|
||||
28-00-31-28-74-01-13
|
||||
2521 18-65-37-13-86-46-08
|
||||
2524 88-84-69-86-18-46-49
|
||||
25-23-65-85-03-80-42
|
||||
2523 10-64-29-31-20-89-52
|
||||
2524 65-21-51-30-91-21-68
|
||||
33-24-81-00-31-10-06
|
||||
2522 66-21-20-66-66-77-70
|
||||
64-36-82-81-22-07-90
|
||||
2524 59-29-33-33-51-95-17
|
||||
2523 00-93-53-78-54-23-22
|
||||
2522 73-77-13-34-10-90-73
|
||||
2521 80-60-56-32-06-52-22
|
||||
61-17-66-25-81-17-53
|
||||
2524 60-47-94-82-73-16-91
|
||||
2524 42-23-08-47-92-68-73
|
||||
2523 96-42-17-80-54-21-92
|
||||
43-41-24-82-73-89-70
|
||||
58-59-94-04-58-25-95
|
||||
65-09-40-69-61-49-66
|
||||
2524 50-80-86-64-00-07-03
|
||||
2525 49-88-90-85-64-35-76
|
||||
2524 45-24-80-26-42-84-59
|
||||
2524 95-24-66-37-33-61-07
|
||||
2523 49-58-55-29-51-10-61
|
||||
2525 39-03-45-88-41-32-53
|
||||
2523 73-96-56-70-51-13-71
|
||||
65-18-22-20-11-92-26
|
||||
2525 80-30-71-96-23-95-74
|
||||
2521 68-19-86-32-40-86-59
|
||||
2522 07-03-45-99-77-61-66
|
||||
2522 53-26-95-59-95-36-13
|
||||
2525 41-02-61-74-69-53-72
|
||||
2521 40-42-28-13-59-79-73
|
||||
2522 03-31-84-02-95-87-67
|
||||
04-54-85-07-18-08-63
|
||||
2522 51-18-39-20-56-42-88
|
||||
2525 90-88-19-93-08-36-74
|
||||
2522 23-14-28-13-65-76-55
|
||||
2523 24-89-75-22-08-30-07
|
||||
15-26-21-64-07-12-45
|
||||
2521 79-89-45-51-27-87-84
|
||||
2525 01-11-24-63-37-93-77
|
||||
2524 81-41-39-29-85-72-75
|
||||
2525 64-96-76-67-37-51-52
|
||||
21-31-25-17-61-80-92
|
||||
2524 72-32-21-73-93-88-48
|
||||
84-27-78-23-47-96-13
|
||||
2523 52-86-55-42-99-36-96
|
||||
2524 10-33-99-48-82-51-25
|
||||
95-69-56-50-65-47-42
|
||||
2525 99-89-69-98-27-91-33
|
||||
06-20-51-97-71-00-53
|
||||
2522 22-05-43-81-46-67-40
|
||||
2521 37-08-49-25-33-08-77
|
||||
2524 63-03-27-24-77-20-41
|
||||
65-59-99-21-28-67-74
|
||||
51-89-42-53-15-48-48
|
||||
41-60-33-82-91-19-40
|
||||
2522 47-26-52-13-21-61-61
|
||||
32-81-00-16-63-90-66
|
||||
2524 18-12-12-11-89-20-60
|
||||
2522 29-93-53-71-59-57-17
|
||||
2522 17-61-02-56-63-48-90
|
||||
2522 87-56-66-57-13-34-32
|
||||
27-43-61-72-26-68-94
|
||||
2525 15-74-04-57-85-46-89
|
||||
2525 58-35-93-12-58-24-84
|
||||
41-09-96-02-81-97-85
|
||||
04-92-76-03-21-36-38
|
||||
36-82-09-76-50-91-40
|
||||
2521 31-48-77-83-23-85-58
|
||||
91-08-41-12-22-67-92
|
||||
2525 91-01-95-06-20-56-66
|
||||
2523 92-09-07-53-90-73-56
|
||||
2523 24-88-11-05-06-18-63
|
||||
2525 14-89-03-92-45-65-53
|
||||
2523 73-98-00-08-94-74-60
|
||||
11-25-05-77-54-25-38
|
||||
2525 24-14-14-61-13-96-41
|
||||
28-33-55-89-06-90-31
|
||||
2523 92-90-32-07-42-96-04
|
||||
2525 79-80-48-56-75-29-12
|
||||
2521 77-97-88-83-04-44-09
|
||||
2523 82-96-37-98-15-52-75
|
||||
2522 64-34-21-10-96-85-39
|
||||
2524 31-52-64-02-96-39-16
|
||||
03-50-03-64-37-62-21
|
||||
2521 49-63-37-97-53-63-00
|
||||
2525 94-49-52-77-74-48-81
|
||||
55-40-74-74-81-86-50
|
||||
2524 06-70-54-03-82-67-17
|
||||
75-19-75-29-43-35-82
|
||||
2521 42-96-95-66-89-84-01
|
||||
2521 55-33-17-44-67-26-89
|
||||
2524 56-64-65-06-52-00-85
|
||||
2522 93-66-95-15-90-23-90
|
||||
2523 31-25-99-15-61-01-30
|
||||
2525 54-54-54-47-69-06-33
|
||||
2525 17-40-02-42-79-86-21
|
||||
2522 21-12-01-11-51-55-14
|
||||
2521 46-20-64-13-21-06-15
|
||||
2523 92-85-71-89-97-70-84
|
||||
2523 22-84-47-04-78-47-01
|
||||
62-49-03-81-98-15-91
|
||||
2524 79-54-71-16-36-91-63
|
||||
2522 02-11-79-98-69-92-57
|
||||
2525 32-76-56-57-96-23-90
|
||||
2523 06-87-57-07-02-01-85
|
||||
2521 18-35-94-83-28-73-15
|
||||
2523 97-04-86-66-40-64-86
|
||||
2521 55-97-94-59-99-20-57
|
||||
2525 18-46-50-17-69-33-41
|
||||
2522 09-48-99-58-34-13-61
|
||||
2523 28-82-53-71-21-05-09
|
||||
2523 08-12-90-23-74-10-27
|
||||
2525 32-08-45-22-72-72-76
|
||||
60-67-63-50-96-10-27
|
||||
2525 75-03-19-97-62-80-88
|
||||
2522 97-86-67-50-27-37-08
|
||||
49-08-22-06-86-17-86
|
||||
2524 09-80-21-70-82-91-48
|
||||
96-06-92-25-94-08-57
|
||||
2525 21-35-94-03-85-72-61
|
||||
2521 39-93-53-66-86-81-96
|
||||
2524 06-18-23-18-88-94-09
|
||||
2521 52-96-14-51-04-51-36
|
||||
2522 10-62-26-66-78-03-94
|
||||
2525 58-22-74-01-66-37-97
|
||||
2524 22-82-49-98-55-97-36
|
||||
2523 04-16-77-51-80-89-13
|
||||
70-51-03-12-10-26-56
|
||||
2521 80-93-55-85-90-06-27
|
||||
2525 18-63-31-58-45-52-61
|
||||
17-10-85-46-30-32-82
|
||||
73-84-60-73-28-53-48
|
||||
2521 13-98-24-82-40-06-10
|
||||
2521 58-59-74-00-18-34-85
|
||||
2524 92-02-64-75-83-14-50
|
||||
10-26-44-71-18-12-71
|
||||
2523 25-09-58-53-10-53-54
|
||||
2521 34-51-86-52-12-41-76
|
||||
2522 71-42-30-72-71-45-59
|
||||
2524 00-71-32-40-12-45-68
|
||||
2524 74-50-48-06-05-52-06
|
||||
48-88-23-94-23-40-74
|
||||
2525 91-22-15-04-72-70-70
|
||||
2521 76-78-90-23-44-92-83
|
||||
2525 57-39-63-94-24-69-04
|
||||
14-88-43-54-27-70-11
|
||||
2522 18-25-25-91-36-53-23
|
||||
2524 36-15-88-30-21-64-83
|
||||
2525 66-11-70-60-37-02-63
|
||||
43-11-84-99-73-28-48
|
||||
01-03-64-24-84-70-15
|
||||
2524 48-76-97-28-23-64-71
|
||||
2524 77-08-08-23-73-96-22
|
||||
2521 64-02-43-87-85-72-84
|
||||
2525 85-46-13-04-03-63-60
|
||||
2524 56-96-76-02-20-13-95
|
||||
31-54-15-57-42-74-53
|
||||
89-00-93-32-62-12-11
|
||||
45-76-98-25-74-09-04
|
||||
2521 64-30-44-10-39-95-33
|
||||
44-71-95-86-12-54-08
|
||||
63-13-57-14-13-48-16
|
||||
41-87-71-95-17-22-88
|
||||
2521 55-23-84-04-27-20-38
|
||||
2523 80-64-38-39-76-43-04
|
||||
2523 81-83-82-90-45-95-65
|
||||
2523 57-84-88-16-25-30-98
|
||||
2525 78-21-73-66-17-08-23
|
||||
13-96-69-65-56-65-03
|
||||
2522 76-37-07-36-14-56-29
|
||||
2525 25-69-00-04-35-06-73
|
||||
2525 63-19-14-57-67-48-50
|
||||
2521 35-43-79-88-05-41-04
|
||||
2525 24-39-13-22-92-33-38
|
||||
39-87-05-09-65-00-95
|
||||
2522 18-68-83-63-94-11-52
|
||||
59-66-84-42-56-03-62
|
||||
36-35-03-95-91-45-41
|
||||
16-11-69-63-84-39-80
|
||||
04-84-19-52-59-91-38
|
||||
2523 18-18-33-99-33-21-00
|
||||
2524 23-70-82-88-62-37-02
|
||||
2524 84-81-71-58-92-39-45
|
||||
45-37-02-62-10-07-76
|
||||
82-02-00-62-68-89-90
|
||||
2524 86-09-14-71-82-07-96
|
||||
00-46-39-33-52-92-78
|
||||
2522 52-39-25-89-07-07-57
|
||||
2524 84-73-35-01-08-20-67
|
||||
01-20-59-64-93-70-69
|
||||
2521 54-32-02-66-48-17-66
|
||||
2522 27-88-88-20-04-95-37
|
||||
2522 64-20-24-10-80-29-56
|
||||
97-57-32-45-22-40-46
|
||||
96-34-25-40-82-57-74
|
||||
2522 81-31-85-33-45-63-70
|
||||
2524 66-71-41-81-31-98-25
|
||||
49-82-16-11-72-89-45
|
||||
2521 66-43-39-05-15-18-35
|
||||
2525 33-11-45-38-33-86-68
|
||||
2522 98-15-12-20-40-53-38
|
||||
2523 88-42-37-81-18-01-02
|
||||
2521 11-65-99-21-43-15-22
|
||||
53-13-41-07-68-00-08
|
||||
2524 47-73-46-61-53-08-26
|
||||
2523 08-19-28-22-45-02-64
|
||||
2521 44-82-74-93-95-67-71
|
||||
2523 58-08-17-31-34-08-12
|
||||
2525 14-35-43-99-32-32-85
|
||||
16-39-50-48-61-01-68
|
||||
21-01-79-67-64-02-34
|
||||
2523 29-90-42-53-74-49-24
|
||||
43-36-98-42-50-74-58
|
||||
2521 94-81-74-15-33-82-12
|
||||
2525 58-11-35-62-67-84-14
|
||||
51-29-63-65-41-59-61
|
||||
2521 83-82-27-34-21-39-89
|
||||
2524 02-33-52-60-73-83-02
|
||||
98-60-39-67-78-63-16
|
||||
2523 64-01-33-01-30-29-51
|
||||
11-75-71-71-03-02-16
|
||||
2522 26-61-47-07-99-43-61
|
||||
2525 47-52-94-94-22-86-50
|
||||
38-06-39-62-20-43-40
|
||||
2525 35-95-33-15-26-71-68
|
||||
2525 42-85-13-31-42-01-39
|
||||
2522 49-75-29-96-44-83-78
|
||||
77-78-32-83-24-38-75
|
||||
2523 49-04-42-96-56-31-75
|
||||
2525 97-48-18-70-00-51-18
|
||||
44-65-44-13-62-33-58
|
||||
41-59-53-82-42-97-31
|
||||
2525 25-11-42-32-67-02-45
|
||||
71-63-18-02-65-19-04
|
||||
95-17-37-75-09-90-68
|
||||
2524 03-54-07-90-12-65-23
|
||||
80-79-45-70-64-72-68
|
||||
2523 31-58-15-79-76-04-38
|
||||
20-15-21-46-53-62-33
|
||||
2521 36-38-82-78-34-89-65
|
||||
2524 84-20-61-66-19-69-95
|
||||
2525 48-16-40-86-41-78-35
|
||||
2524 03-37-64-84-01-78-94
|
||||
2524 44-67-25-32-81-53-15
|
||||
2525 48-52-48-87-90-98-18
|
||||
30-60-22-87-47-25-15
|
||||
2525 33-84-89-80-86-70-09
|
||||
73-93-46-17-69-91-97
|
||||
2522 84-97-55-42-32-60-92
|
||||
2525 07-07-64-14-63-51-14
|
||||
2524 55-03-93-60-14-91-74
|
||||
2523 32-19-25-22-77-78-15
|
||||
2521 73-53-49-22-54-23-90
|
||||
2521 78-87-15-24-92-85-90
|
||||
2522 34-62-94-56-11-17-51
|
||||
2522 30-07-45-21-59-94-54
|
||||
2523 55-92-76-54-95-29-71
|
||||
76-03-18-42-39-37-30
|
||||
89-26-94-14-17-99-40
|
||||
50-10-05-18-34-97-32
|
||||
2521 04-25-61-71-00-32-50
|
||||
2523 56-82-78-00-94-99-90
|
||||
2524 34-99-74-17-91-98-84
|
||||
75-74-30-25-42-81-71
|
||||
2524 37-69-87-33-41-40-02
|
||||
50-19-15-78-99-25-22
|
||||
18-49-62-94-65-95-87
|
||||
2523 77-16-41-76-81-66-35
|
||||
2522 59-70-39-69-97-92-96
|
||||
2525 81-72-07-51-68-40-23
|
||||
2525 63-60-68-44-43-62-08
|
||||
2521 73-20-40-52-98-97-29
|
||||
2523 38-27-54-83-03-00-26
|
||||
2522 08-39-39-32-25-45-56
|
||||
2523 40-34-67-04-37-33-29
|
||||
2524 11-41-84-92-94-16-33
|
||||
2521 89-55-98-69-20-03-41
|
||||
2521 27-09-16-26-04-82-81
|
||||
2521 38-83-20-21-79-29-81
|
||||
2525 61-09-59-92-28-67-66
|
||||
47-19-80-43-43-20-93
|
||||
2521 87-80-59-51-20-32-74
|
||||
2524 70-14-85-72-40-80-60
|
||||
2523 77-57-03-64-45-21-38
|
||||
2521 88-33-82-62-01-49-55
|
||||
88-11-93-34-85-87-69
|
||||
06-02-35-69-77-05-11
|
||||
2525 84-91-87-54-60-51-46
|
||||
2525 78-99-73-78-24-94-24
|
||||
29-50-87-38-87-93-90
|
||||
2521 84-73-41-32-87-95-52
|
||||
2521 53-62-20-06-17-74-40
|
||||
2524 13-47-06-47-93-65-29
|
||||
2522 38-85-34-37-71-05-30
|
||||
2523 48-39-49-57-23-78-96
|
||||
2522 81-22-48-06-91-47-42
|
||||
15-65-95-20-46-73-48
|
||||
2521 80-46-01-82-74-75-03
|
||||
2521 11-40-88-15-16-96-49
|
||||
2524 43-94-42-84-35-12-17
|
||||
2524 18-12-45-80-30-07-72
|
||||
2525 57-99-35-42-43-67-68
|
||||
63-99-70-67-80-84-31
|
||||
2521 19-80-66-96-16-61-44
|
||||
90-66-93-65-04-32-71
|
||||
52-73-25-85-08-22-10
|
||||
41-42-86-69-91-89-93
|
||||
2525 69-06-01-51-03-59-91
|
||||
2522 25-00-80-31-11-83-55
|
||||
18-77-42-88-77-67-11
|
||||
2525 83-90-27-60-78-24-26
|
||||
2523 94-00-59-37-68-05-50
|
||||
2521 55-74-61-32-63-51-01
|
||||
2522 61-90-85-23-11-51-03
|
||||
2523 94-78-26-87-62-57-55
|
||||
2524 22-42-80-60-85-42-48
|
||||
2521 47-06-03-02-78-96-05
|
||||
2524 78-54-40-11-40-54-75
|
||||
68-20-77-52-00-10-70
|
||||
2521 04-82-37-21-22-19-17
|
||||
2524 62-94-76-61-11-56-75
|
||||
14-04-11-98-47-23-56
|
||||
2521 54-41-86-59-91-91-61
|
||||
14-00-07-96-01-62-04
|
||||
29-18-98-86-00-88-70
|
||||
62-78-07-66-28-68-93
|
||||
23-67-08-74-60-57-55
|
||||
2521 44-26-69-25-31-41-36
|
||||
2523 65-82-68-93-69-64-68
|
||||
25-23-22-44-51-33-19
|
||||
2521 45-37-36-91-84-70-59
|
||||
2521 99-23-86-83-01-62-70
|
||||
85-94-26-28-50-89-75
|
||||
2521 16-30-23-12-48-81-01
|
||||
36-43-94-12-58-24-73
|
||||
2522 22-11-15-28-77-93-46
|
||||
24-00-68-13-80-33-10
|
||||
2524 79-10-22-21-74-10-56
|
||||
2525 50-92-57-27-51-67-57
|
||||
53-28-93-58-39-45-05
|
||||
2522 49-13-78-56-46-96-33
|
||||
2523 65-40-89-45-25-45-78
|
||||
2523 59-35-54-94-01-68-62
|
||||
2521 21-26-28-37-80-04-15
|
||||
31-71-93-03-54-89-84
|
||||
2524 06-16-02-83-98-00-11
|
||||
2524 79-24-11-13-14-02-37
|
||||
2522 08-95-10-92-33-49-44
|
||||
2521 49-65-96-35-05-04-53
|
||||
2522 41-32-18-41-45-88-81
|
||||
2521 53-55-62-25-06-39-43
|
||||
2521 05-14-32-15-50-24-82
|
||||
2525 60-47-47-27-56-11-89
|
||||
2521 44-77-64-51-88-05-75
|
||||
2523 25-51-51-60-61-81-76
|
||||
2523 92-38-26-84-23-01-06
|
||||
28-67-09-28-67-04-31
|
||||
2525 29-39-37-88-09-23-79
|
||||
33-48-56-81-66-84-89
|
||||
23-38-63-69-33-39-02
|
||||
2522 70-04-29-62-18-94-74
|
||||
2524 31-07-43-44-22-06-24
|
||||
2524 58-41-39-65-11-94-61
|
||||
2525 85-80-40-57-39-02-03
|
||||
2524 45-80-38-47-70-95-24
|
||||
82-85-24-60-48-90-50
|
||||
04-03-01-57-35-97-62
|
||||
2524 82-00-55-91-97-52-37
|
||||
2523 97-00-38-05-71-74-38
|
||||
32-09-89-80-29-48-51
|
||||
84-75-37-85-77-75-29
|
||||
2523 51-44-85-74-10-90-74
|
||||
2523 25-63-16-22-75-48-79
|
||||
80-59-44-91-58-46-30
|
||||
2522 31-48-06-26-42-59-84
|
||||
48-50-24-48-30-74-73
|
||||
31-26-27-54-59-28-34
|
||||
2522 87-66-84-15-33-31-95
|
||||
51-85-47-66-51-64-87
|
||||
2523 55-09-83-65-81-58-51
|
||||
2522 99-11-54-41-04-24-54
|
||||
78-44-82-14-91-00-67
|
||||
31-38-18-34-44-79-59
|
||||
2521 75-13-20-65-21-16-15
|
||||
2523 26-44-92-56-41-70-22
|
||||
95-71-53-73-55-50-94
|
||||
10-44-09-45-67-13-75
|
||||
2525 06-21-87-86-54-94-02
|
||||
2524 31-85-09-42-29-45-57
|
||||
2525 42-01-75-05-25-11-40
|
||||
2524 12-14-10-27-19-30-99
|
||||
79-97-04-48-87-42-00
|
||||
2521 90-02-73-89-64-29-10
|
||||
2523 29-17-32-76-08-65-75
|
||||
2524 70-31-69-39-33-84-38
|
||||
2525 71-52-62-55-12-16-57
|
||||
36-69-53-13-49-70-66
|
||||
85-12-10-39-29-80-35
|
||||
2524 26-09-42-08-04-99-55
|
||||
2523 33-23-74-47-43-33-24
|
||||
2525 06-91-79-15-79-29-41
|
||||
60-88-10-40-92-23-52
|
||||
2523 24-05-58-34-80-77-14
|
||||
2522 74-71-28-79-29-38-72
|
||||
2521 80-50-12-20-47-99-78
|
||||
2521 06-83-17-55-45-79-82
|
||||
2521 13-52-26-76-99-70-20
|
||||
2524 84-64-14-58-40-09-62
|
||||
2524 86-97-11-55-57-83-16
|
||||
2522 79-38-56-35-52-07-41
|
||||
91-38-01-67-78-65-73
|
||||
2523 05-11-50-18-20-12-38
|
||||
2521 03-88-90-27-37-15-37
|
||||
2525 83-26-08-00-50-20-68
|
||||
2521 68-65-73-31-70-44-45
|
||||
2524 54-66-91-09-07-74-26
|
||||
2525 72-65-73-73-62-24-96
|
||||
07-41-74-07-86-07-39
|
||||
2522 64-48-93-29-40-97-14
|
||||
2525 79-90-61-88-87-15-59
|
||||
2524 50-47-16-17-09-15-14
|
||||
2521 46-06-40-88-48-85-88
|
||||
91-27-05-71-25-84-20
|
||||
2522 12-22-39-13-04-78-78
|
||||
2525 58-11-44-63-05-97-71
|
||||
2521 70-16-43-07-87-51-85
|
||||
2521 58-92-61-20-12-28-60
|
||||
57-80-24-58-22-03-15
|
||||
2524 12-08-29-52-75-46-34
|
||||
2524 63-17-74-41-08-29-16
|
||||
81-05-91-02-20-96-92
|
||||
96-59-37-84-38-68-85
|
||||
34-09-34-90-82-90-14
|
||||
45-66-92-96-14-48-83
|
||||
2522 01-61-02-21-68-28-60
|
||||
89-01-37-64-20-77-75
|
||||
14-00-50-43-04-66-06
|
||||
2521 06-35-29-40-03-24-19
|
||||
2524 78-34-98-20-72-56-24
|
||||
54-05-64-46-00-00-54
|
||||
87-00-71-87-41-99-40
|
||||
70-50-43-54-84-95-28
|
||||
2524 87-53-38-76-20-49-78
|
||||
File diff suppressed because it is too large
Load Diff
68
test_bot.py
68
test_bot.py
@@ -1,68 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Упрощенная версия main.py для диагностики
|
||||
"""
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
# Настройка логирования
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
async def test_imports():
|
||||
"""Тест импортов по порядку"""
|
||||
try:
|
||||
logger.info("1. Тест импорта config...")
|
||||
from src.core.config import BOT_TOKEN, ADMIN_IDS, DATABASE_URL
|
||||
logger.info(f"✅ Config OK. BOT_TOKEN: {BOT_TOKEN[:10]}..., ADMIN_IDS: {ADMIN_IDS}")
|
||||
|
||||
logger.info("2. Тест импорта aiogram...")
|
||||
from aiogram import Bot, Dispatcher
|
||||
logger.info("✅ Aiogram OK")
|
||||
|
||||
logger.info("3. Тест создания бота...")
|
||||
bot = Bot(token=BOT_TOKEN)
|
||||
logger.info("✅ Bot created OK")
|
||||
|
||||
logger.info("4. Тест импорта database...")
|
||||
from src.core.database import async_session_maker, init_db
|
||||
logger.info("✅ Database imports OK")
|
||||
|
||||
logger.info("5. Тест подключения к БД...")
|
||||
async with async_session_maker() as session:
|
||||
logger.info("✅ Database connection OK")
|
||||
|
||||
logger.info("6. Тест импорта services...")
|
||||
from src.core.services import UserService, LotteryService
|
||||
logger.info("✅ Services OK")
|
||||
|
||||
logger.info("7. Тест импорта handlers...")
|
||||
from src.handlers.registration_handlers import router as registration_router
|
||||
logger.info("✅ Registration handlers OK")
|
||||
|
||||
from src.handlers.admin_panel import admin_router
|
||||
logger.info("✅ Admin panel OK")
|
||||
|
||||
logger.info("8. Тест создания диспетчера...")
|
||||
dp = Dispatcher()
|
||||
dp.include_router(registration_router)
|
||||
dp.include_router(admin_router)
|
||||
logger.info("✅ Dispatcher OK")
|
||||
|
||||
logger.info("9. Тест получения информации о боте...")
|
||||
bot_info = await bot.get_me()
|
||||
logger.info(f"✅ Bot info: {bot_info.username} ({bot_info.first_name})")
|
||||
|
||||
await bot.session.close()
|
||||
logger.info("✅ Все тесты пройдены успешно!")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Ошибка: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(test_imports())
|
||||
@@ -1,74 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Скрипт для тестирования функциональности бота
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
|
||||
from src.core.database import async_session_maker
|
||||
from src.core.models import User, Lottery
|
||||
from sqlalchemy import select
|
||||
|
||||
async def test_database_connectivity():
|
||||
"""Тест подключения к базе данных"""
|
||||
print("🔌 Тестируем подключение к базе данных...")
|
||||
|
||||
async with async_session_maker() as session:
|
||||
# Проверяем подключение
|
||||
result = await session.execute(select(1))
|
||||
print("✅ Подключение к PostgreSQL работает")
|
||||
|
||||
# Проверяем количество пользователей
|
||||
users_count = await session.execute(select(User))
|
||||
users = users_count.scalars().all()
|
||||
print(f"📊 В базе {len(users)} пользователей")
|
||||
|
||||
# Проверяем количество лотерей
|
||||
lotteries_count = await session.execute(select(Lottery))
|
||||
lotteries = lotteries_count.scalars().all()
|
||||
print(f"🎰 В базе {len(lotteries)} лотерей")
|
||||
|
||||
async def test_bot_imports():
|
||||
"""Тест импортов бота"""
|
||||
print("🔄 Тестируем импорты модулей...")
|
||||
|
||||
try:
|
||||
from src.handlers.registration_handlers import router as registration_router
|
||||
print("✅ registration_router импортирован")
|
||||
|
||||
from src.handlers.admin_panel import admin_router
|
||||
print("✅ admin_router импортирован")
|
||||
|
||||
from src.handlers.account_handlers import account_router
|
||||
print("✅ account_router импортирован")
|
||||
|
||||
from src.core.config import BOT_TOKEN
|
||||
print("✅ BOT_TOKEN получен из конфигурации")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Ошибка импорта: {e}")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
async def main():
|
||||
"""Основная функция тестирования"""
|
||||
print("🤖 Тестирование функциональности лотерейного бота")
|
||||
print("=" * 50)
|
||||
|
||||
# Тест импортов
|
||||
imports_ok = await test_bot_imports()
|
||||
|
||||
if imports_ok:
|
||||
print("\n")
|
||||
# Тест базы данных
|
||||
await test_database_connectivity()
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print("✅ Тестирование завершено")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user