feat: Add admin management system with super admin controls
Some checks failed
continuous-integration/drone/pr Build is failing
Some checks failed
continuous-integration/drone/pr Build is failing
- Implemented two-level admin hierarchy (super admin from .env and assigned admins) - Only super admins (from ADMIN_IDS in .env) can manage admin assignments - Added admin management menu to settings (visible only for super admins) - Admins can add/remove other admins through the bot interface - Protected super admins from deletion - Added CLI tool for admin management (scripts/manage_admins.py) - Added database check script (scripts/check_db.py) - Added deployment scripts for server setup - Added comprehensive documentation on admin management system - Added backup and server deployment guides
This commit is contained in:
134
scripts/check_db.py
Normal file
134
scripts/check_db.py
Normal file
@@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Скрипт для проверки и инициализации БД перед запуском бота
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Добавляем путь к проекту
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
from src.core.database import engine, async_session_maker, Base
|
||||
from src.core.models import User, Lottery, Participation, Winner, Account
|
||||
from sqlalchemy import text, inspect, select
|
||||
import logging
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def check_db_connection():
|
||||
"""Проверка подключения к БД"""
|
||||
logger.info("🔍 Проверка подключения к БД...")
|
||||
try:
|
||||
async with async_session_maker() as session:
|
||||
result = await session.execute(text("SELECT 1"))
|
||||
logger.info("✅ Подключение к БД успешно")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Ошибка подключения к БД: {e}")
|
||||
return False
|
||||
|
||||
|
||||
async def check_tables():
|
||||
"""Проверка наличия таблиц"""
|
||||
logger.info("📊 Проверка таблиц БД...")
|
||||
|
||||
async with engine.begin() as conn:
|
||||
inspector = inspect(conn)
|
||||
tables = inspector.get_table_names()
|
||||
|
||||
required_tables = ['users', 'lotteries', 'participations', 'winners', 'accounts']
|
||||
|
||||
missing_tables = [t for t in required_tables if t not in tables]
|
||||
|
||||
if missing_tables:
|
||||
logger.warning(f"⚠️ Отсутствуют таблицы: {', '.join(missing_tables)}")
|
||||
return False, missing_tables
|
||||
else:
|
||||
logger.info(f"✅ Все необходимые таблицы найдены: {', '.join(required_tables)}")
|
||||
return True, []
|
||||
|
||||
|
||||
async def create_tables():
|
||||
"""Создание таблиц БД"""
|
||||
logger.info("📝 Создание таблиц БД...")
|
||||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.run_sync(Base.metadata.create_all)
|
||||
logger.info("✅ Таблицы созданы успешно")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Ошибка при создании таблиц: {e}")
|
||||
return False
|
||||
|
||||
|
||||
async def check_data():
|
||||
"""Проверка наличия данных"""
|
||||
logger.info("📈 Проверка данных в БД...")
|
||||
|
||||
async with async_session_maker() as session:
|
||||
users_count = await session.execute(select(User))
|
||||
users_count = len(users_count.scalars().all())
|
||||
|
||||
lotteries_count = await session.execute(select(Lottery))
|
||||
lotteries_count = len(lotteries_count.scalars().all())
|
||||
|
||||
logger.info(f"👥 Пользователей: {users_count}")
|
||||
logger.info(f"🎲 Розыгрышей: {lotteries_count}")
|
||||
|
||||
return {
|
||||
'users': users_count,
|
||||
'lotteries': lotteries_count
|
||||
}
|
||||
|
||||
|
||||
async def main():
|
||||
"""Главная функция"""
|
||||
logger.info("=" * 60)
|
||||
logger.info("🔧 Проверка и инициализация БД")
|
||||
logger.info("=" * 60)
|
||||
|
||||
# Шаг 1: Проверка подключения
|
||||
if not await check_db_connection():
|
||||
logger.error("❌ Не удалось подключиться к БД. Проверьте переменную DATABASE_URL")
|
||||
return False
|
||||
|
||||
# Шаг 2: Проверка таблиц
|
||||
tables_exist, missing_tables = await check_tables()
|
||||
|
||||
if not tables_exist:
|
||||
logger.info("🔄 Создание отсутствующих таблиц...")
|
||||
if not await create_tables():
|
||||
logger.error("❌ Не удалось создать таблицы")
|
||||
return False
|
||||
logger.info("✅ Таблицы созданы")
|
||||
|
||||
# Шаг 3: Проверка данных
|
||||
data = await check_data()
|
||||
|
||||
# Итоговая информация
|
||||
logger.info("")
|
||||
logger.info("=" * 60)
|
||||
logger.info("✅ БД готова к работе!")
|
||||
logger.info("=" * 60)
|
||||
logger.info("")
|
||||
logger.info("📋 Информация о БД:")
|
||||
logger.info(f" 👥 Пользователей: {data['users']}")
|
||||
logger.info(f" 🎲 Розыгрышей: {data['lotteries']}")
|
||||
logger.info("")
|
||||
logger.info("🚀 Вы можете запустить бота командой:")
|
||||
logger.info(" python3 main.py")
|
||||
logger.info("")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = asyncio.run(main())
|
||||
sys.exit(0 if success else 1)
|
||||
Reference in New Issue
Block a user