Исправление двойного ответа и улучшение системы
- Исправлен баг с двойным ответом в /getgamers (добавлена обработка ошибок) - Добавлена автоматическая миграция токенов при инициализации БД - Исправлен веб-интерфейс - теперь берет токены из user_gamers - Улучшен start.sh - создает бэкап базы перед перезапуском - Добавлен export_db.sh для экспорта базы данных - start.sh безопасно обновляет проект и сохраняет все данные
This commit is contained in:
parent
cbc5244240
commit
6cb5a9b99f
13 changed files with 186 additions and 11 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -55,3 +55,6 @@ npm-debug.log
|
||||||
# Файлы кеша
|
# Файлы кеша
|
||||||
.cache/
|
.cache/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -229,11 +229,24 @@ class LichessBot:
|
||||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||||
|
|
||||||
# Edit the loading message with the results
|
# Edit the loading message with the results
|
||||||
|
try:
|
||||||
await loading_msg.edit_text(
|
await loading_msg.edit_text(
|
||||||
gamers_text,
|
gamers_text,
|
||||||
parse_mode='HTML',
|
parse_mode='HTML',
|
||||||
reply_markup=reply_markup
|
reply_markup=reply_markup
|
||||||
)
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error editing message: {e}")
|
||||||
|
# If edit fails, delete the loading message and send a new one
|
||||||
|
try:
|
||||||
|
await loading_msg.delete()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
await update.message.reply_text(
|
||||||
|
gamers_text,
|
||||||
|
parse_mode='HTML',
|
||||||
|
reply_markup=reply_markup
|
||||||
|
)
|
||||||
|
|
||||||
async def select_gamer(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
async def select_gamer(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
"""Handle gamer selection"""
|
"""Handle gamer selection"""
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,49 @@ class Database:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
|
# Migrate tokens from gamers to user_gamers if needed
|
||||||
|
self._migrate_tokens_from_gamers()
|
||||||
|
|
||||||
logger.info("Database initialized successfully")
|
logger.info("Database initialized successfully")
|
||||||
|
|
||||||
|
def _migrate_tokens_from_gamers(self):
|
||||||
|
"""Migrate tokens from old gamers table to user_gamers table if needed"""
|
||||||
|
with sqlite3.connect(self.db_path) as conn:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# Check if there are tokens in gamers table that need migration
|
||||||
|
cursor.execute("SELECT COUNT(*) FROM gamers WHERE token IS NOT NULL")
|
||||||
|
gamers_with_tokens = cursor.fetchone()[0]
|
||||||
|
|
||||||
|
if gamers_with_tokens == 0:
|
||||||
|
return # No tokens to migrate
|
||||||
|
|
||||||
|
# Check if user_gamers already has tokens
|
||||||
|
cursor.execute("SELECT COUNT(*) FROM user_gamers WHERE token IS NOT NULL")
|
||||||
|
user_gamers_with_tokens = cursor.fetchone()[0]
|
||||||
|
|
||||||
|
if user_gamers_with_tokens > 0:
|
||||||
|
return # Migration already done
|
||||||
|
|
||||||
|
# Migrate tokens from gamers to user_gamers
|
||||||
|
cursor.execute("SELECT id, token FROM gamers WHERE token IS NOT NULL")
|
||||||
|
gamers_tokens = cursor.fetchall()
|
||||||
|
|
||||||
|
migrated = 0
|
||||||
|
for gamer_id, token in gamers_tokens:
|
||||||
|
# Update all user-gamer relationships for this gamer
|
||||||
|
cursor.execute(
|
||||||
|
"UPDATE user_gamers SET token = ? WHERE gamer_id = ? AND token IS NULL",
|
||||||
|
(token, gamer_id)
|
||||||
|
)
|
||||||
|
migrated += cursor.rowcount
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
if migrated > 0:
|
||||||
|
logger.info(f"Migrated {migrated} tokens from gamers to user_gamers")
|
||||||
|
|
||||||
def add_or_get_telegram_user(self, user_id: int, username: Optional[str] = None,
|
def add_or_get_telegram_user(self, user_id: int, username: Optional[str] = None,
|
||||||
first_name: Optional[str] = None, last_name: Optional[str] = None) -> bool:
|
first_name: Optional[str] = None, last_name: Optional[str] = None) -> bool:
|
||||||
"""Add or update Telegram user"""
|
"""Add or update Telegram user"""
|
||||||
|
|
|
||||||
66
LichessClientTG_bot/migrate_tokens.py
Normal file
66
LichessClientTG_bot/migrate_tokens.py
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Миграция токенов из старой таблицы gamers в новую таблицу user_gamers
|
||||||
|
"""
|
||||||
|
import sqlite3
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def migrate_tokens():
|
||||||
|
"""Migrate tokens from gamers table to user_gamers table"""
|
||||||
|
db_path = "/app/data/lichess_bot.db"
|
||||||
|
|
||||||
|
try:
|
||||||
|
with sqlite3.connect(db_path) as conn:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# Проверяем есть ли токены в gamers
|
||||||
|
cursor.execute("SELECT id, username, token FROM gamers WHERE token IS NOT NULL")
|
||||||
|
gamers_with_tokens = cursor.fetchall()
|
||||||
|
|
||||||
|
if not gamers_with_tokens:
|
||||||
|
print("В базе нет токенов для миграции")
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"Найдено {len(gamers_with_tokens)} игроков с токенами")
|
||||||
|
|
||||||
|
migrated = 0
|
||||||
|
for gamer_id, gamer_username, token in gamers_with_tokens:
|
||||||
|
# Находим всех пользователей, отслеживающих этого игрока
|
||||||
|
cursor.execute("SELECT user_id FROM user_gamers WHERE gamer_id = ?", (gamer_id,))
|
||||||
|
users = cursor.fetchall()
|
||||||
|
|
||||||
|
for (user_id,) in users:
|
||||||
|
# Проверяем есть ли уже токен у этого пользователя для этого игрока
|
||||||
|
cursor.execute(
|
||||||
|
"SELECT token FROM user_gamers WHERE user_id = ? AND gamer_id = ?",
|
||||||
|
(user_id, gamer_id)
|
||||||
|
)
|
||||||
|
existing_token = cursor.fetchone()
|
||||||
|
|
||||||
|
if existing_token and existing_token[0]:
|
||||||
|
# Токен уже есть, пропускаем
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Переносим токен
|
||||||
|
cursor.execute(
|
||||||
|
"UPDATE user_gamers SET token = ? WHERE user_id = ? AND gamer_id = ?",
|
||||||
|
(token, user_id, gamer_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor.execute("SELECT username FROM telegram_users WHERE user_id = ?", (user_id,))
|
||||||
|
user_data = cursor.fetchone()
|
||||||
|
user_name = user_data[0] if user_data else f"ID:{user_id}"
|
||||||
|
|
||||||
|
print(f" - Перенесен токен для {gamer_username} -> пользователю @{user_name}")
|
||||||
|
migrated += 1
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
print(f"\n✅ Миграция завершена. Перенесено {migrated} токенов")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Ошибка при миграции: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
migrate_tokens()
|
||||||
|
|
||||||
3
LichessWebView/.gitignore
vendored
3
LichessWebView/.gitignore
vendored
|
|
@ -23,3 +23,6 @@ wheels/
|
||||||
*.egg
|
*.egg
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ def get_user_gamers(user_id):
|
||||||
SELECT
|
SELECT
|
||||||
g.id,
|
g.id,
|
||||||
g.username,
|
g.username,
|
||||||
g.token,
|
ug.token,
|
||||||
ug.is_active,
|
ug.is_active,
|
||||||
ug.period_minutes,
|
ug.period_minutes,
|
||||||
ug.created_at
|
ug.created_at
|
||||||
|
|
@ -94,7 +94,7 @@ def get_user_gamers(user_id):
|
||||||
gamers.append({
|
gamers.append({
|
||||||
'id': row[0],
|
'id': row[0],
|
||||||
'username': row[1],
|
'username': row[1],
|
||||||
'has_token': bool(row[2]),
|
'has_token': bool(row[2]), # Token from user_gamers, not gamers
|
||||||
'is_active': bool(row[3]),
|
'is_active': bool(row[3]),
|
||||||
'period_minutes': row[4],
|
'period_minutes': row[4],
|
||||||
'created_at': row[5]
|
'created_at': row[5]
|
||||||
|
|
@ -114,3 +114,6 @@ def get_user_gamers(user_id):
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(host='0.0.0.0', port=5000, debug=True)
|
app.run(host='0.0.0.0', port=5000, debug=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,6 @@ services:
|
||||||
environment:
|
environment:
|
||||||
- FLASK_ENV=production
|
- FLASK_ENV=production
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
Flask==3.0.0
|
Flask==3.0.0
|
||||||
flask-cors==4.0.0
|
flask-cors==4.0.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -438,3 +438,6 @@
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -238,3 +238,6 @@ Roman Vrubel
|
||||||
- [Telegram Bot API](https://core.telegram.org/bots/api)
|
- [Telegram Bot API](https://core.telegram.org/bots/api)
|
||||||
- [FastAPI Documentation](https://fastapi.tiangolo.com/)
|
- [FastAPI Documentation](https://fastapi.tiangolo.com/)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ services:
|
||||||
- PYTHONUNBUFFERED=1
|
- PYTHONUNBUFFERED=1
|
||||||
volumes:
|
volumes:
|
||||||
- ./LichessWebServices:/app
|
- ./LichessWebServices:/app
|
||||||
restart: unless-stopped
|
restart: always
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
|
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
|
|
@ -26,7 +26,7 @@ services:
|
||||||
- PYTHONPATH=/app
|
- PYTHONPATH=/app
|
||||||
- PYTHONUNBUFFERED=1
|
- PYTHONUNBUFFERED=1
|
||||||
network_mode: "host"
|
network_mode: "host"
|
||||||
restart: unless-stopped
|
restart: always
|
||||||
depends_on:
|
depends_on:
|
||||||
- lichess-api
|
- lichess-api
|
||||||
healthcheck:
|
healthcheck:
|
||||||
|
|
@ -44,7 +44,7 @@ services:
|
||||||
- "5000:5000"
|
- "5000:5000"
|
||||||
volumes:
|
volumes:
|
||||||
- ./LichessClientTG_bot/data:/app/data:ro
|
- ./LichessClientTG_bot/data:/app/data:ro
|
||||||
restart: unless-stopped
|
restart: always
|
||||||
depends_on:
|
depends_on:
|
||||||
- lichess-bot
|
- lichess-bot
|
||||||
|
|
||||||
|
|
@ -52,3 +52,6 @@ networks:
|
||||||
default:
|
default:
|
||||||
name: lichess-network
|
name: lichess-network
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
20
export_db.sh
Normal file
20
export_db.sh
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "📤 Экспорт базы данных..."
|
||||||
|
|
||||||
|
if [ ! -f "LichessClientTG_bot/data/lichess_bot.db" ]; then
|
||||||
|
echo "❌ База данных не найдена!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p backups
|
||||||
|
timestamp=$(date +%Y%m%d_%H%M%S)
|
||||||
|
|
||||||
|
# Экспортируем базу
|
||||||
|
cp LichessClientTG_bot/data/lichess_bot.db "backups/export_lichess_bot_${timestamp}.db"
|
||||||
|
|
||||||
|
echo "✅ База данных экспортирована: backups/export_lichess_bot_${timestamp}.db"
|
||||||
|
echo ""
|
||||||
|
echo "Для импорта на другом компьютере используйте:"
|
||||||
|
echo " cp backups/export_lichess_bot_${timestamp}.db LichessClientTG_bot/data/lichess_bot.db"
|
||||||
|
|
||||||
13
start.sh
13
start.sh
|
|
@ -14,10 +14,18 @@ if ! command -v docker-compose &> /dev/null; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Останавливаем существующие контейнеры
|
# Останавливаем существующие контейнеры (без удаления volumes для сохранения данных)
|
||||||
echo "🛑 Остановка существующих контейнеров..."
|
echo "🛑 Остановка существующих контейнеров..."
|
||||||
docker-compose down
|
docker-compose down
|
||||||
|
|
||||||
|
# Бэкап базы данных (на всякий случай)
|
||||||
|
echo "💾 Создание резервной копии базы данных..."
|
||||||
|
if [ -d "LichessClientTG_bot/data" ]; then
|
||||||
|
mkdir -p backups
|
||||||
|
cp -f LichessClientTG_bot/data/lichess_bot.db backups/lichess_bot_$(date +%Y%m%d_%H%M%S).db 2>/dev/null || true
|
||||||
|
echo "✅ Бэкап создан"
|
||||||
|
fi
|
||||||
|
|
||||||
# Пересобираем образы
|
# Пересобираем образы
|
||||||
echo "🔨 Пересборка Docker образов..."
|
echo "🔨 Пересборка Docker образов..."
|
||||||
docker-compose build
|
docker-compose build
|
||||||
|
|
@ -48,3 +56,6 @@ echo ""
|
||||||
echo "🛑 Для остановки используйте:"
|
echo "🛑 Для остановки используйте:"
|
||||||
echo " docker-compose down"
|
echo " docker-compose down"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue