bug today
This commit is contained in:
parent
faf6ec0c35
commit
4dc5539da2
5 changed files with 189 additions and 38 deletions
|
|
@ -732,8 +732,11 @@ class LichessBot:
|
||||||
"""Get statistics for a period - shows stats for all players with activity"""
|
"""Get statistics for a period - shows stats for all players with activity"""
|
||||||
user_id = update.effective_user.id
|
user_id = update.effective_user.id
|
||||||
|
|
||||||
|
logger.info(f"🔍 get_stats called: user_id={user_id}, period={period}")
|
||||||
|
|
||||||
# Get all gamers for this user
|
# Get all gamers for this user
|
||||||
gamers = self.db.get_user_gamers(user_id)
|
gamers = self.db.get_user_gamers(user_id)
|
||||||
|
logger.info(f"🔍 Found {len(gamers)} gamers for user {user_id}: {[g['username'] for g in gamers]}")
|
||||||
|
|
||||||
lang = self.get_user_language_from_update(update)
|
lang = self.get_user_language_from_update(update)
|
||||||
if not gamers:
|
if not gamers:
|
||||||
|
|
@ -752,6 +755,7 @@ class LichessBot:
|
||||||
has_any_activity = False
|
has_any_activity = False
|
||||||
for i, gamer in enumerate(gamers):
|
for i, gamer in enumerate(gamers):
|
||||||
username = gamer['username']
|
username = gamer['username']
|
||||||
|
logger.info(f"🔍 Processing gamer {i+1}/{len(gamers)}: {username} for period {period}")
|
||||||
|
|
||||||
# Send message about processing this player
|
# Send message about processing this player
|
||||||
processing_msg = None
|
processing_msg = None
|
||||||
|
|
@ -761,15 +765,28 @@ class LichessBot:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Get stats based on period
|
# Get stats based on period
|
||||||
if period == "today":
|
try:
|
||||||
data = await self.lichess_api.get_today_stats(username)
|
logger.info(f"🔍 Making API request for {username}, period={period}")
|
||||||
elif period == "yesterday":
|
if period == "today":
|
||||||
data = await self.lichess_api.get_yesterday_stats(username)
|
data = await self.lichess_api.get_today_stats(username)
|
||||||
elif period == "week":
|
elif period == "yesterday":
|
||||||
data = await self.lichess_api.get_week_stats(username)
|
data = await self.lichess_api.get_yesterday_stats(username)
|
||||||
else:
|
elif period == "week":
|
||||||
await update.message.reply_text(t('unknown_period', lang))
|
data = await self.lichess_api.get_week_stats(username)
|
||||||
return
|
else:
|
||||||
|
await update.message.reply_text(t('unknown_period', lang))
|
||||||
|
return
|
||||||
|
|
||||||
|
logger.info(f"🔍 API response for {username}: data={data is not None}, type={type(data)}")
|
||||||
|
if data:
|
||||||
|
logger.info(f"🔍 API response keys: {data.keys() if isinstance(data, dict) else 'not a dict'}")
|
||||||
|
if isinstance(data, dict) and 'message' in data:
|
||||||
|
logger.info(f"🔍 API message: {data.get('message')}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"❌ Error getting stats for {username}: {e}")
|
||||||
|
import traceback
|
||||||
|
logger.error(traceback.format_exc())
|
||||||
|
data = None
|
||||||
|
|
||||||
# Delete processing message
|
# Delete processing message
|
||||||
if processing_msg:
|
if processing_msg:
|
||||||
|
|
@ -780,27 +797,40 @@ class LichessBot:
|
||||||
|
|
||||||
# Check if there's activity
|
# Check if there's activity
|
||||||
has_activity = False
|
has_activity = False
|
||||||
if data and data.get('data'):
|
if data:
|
||||||
api_data = data.get('data', {})
|
if data.get('data'):
|
||||||
tasks = api_data.get('tasks', {})
|
api_data = data.get('data', {})
|
||||||
games = api_data.get('games', {})
|
tasks = api_data.get('tasks', {})
|
||||||
|
games = api_data.get('games', {})
|
||||||
# Check for puzzles activity
|
|
||||||
if tasks and tasks.get('total', 0) > 0:
|
logger.info(f"🔍 Activity check for {username}: tasks={tasks}, games={games}")
|
||||||
has_activity = True
|
|
||||||
|
# Check for puzzles activity
|
||||||
# Check for games activity
|
if tasks and tasks.get('total', 0) > 0:
|
||||||
if games:
|
has_activity = True
|
||||||
for game_type, game_data in games.items():
|
logger.info(f"✅ {username} has puzzles activity: {tasks.get('total')}")
|
||||||
if game_data and game_data.get('games_played', 0) > 0:
|
|
||||||
has_activity = True
|
# Check for games activity
|
||||||
break
|
if games:
|
||||||
|
for game_type, game_data in games.items():
|
||||||
|
if game_data and game_data.get('games_played', 0) > 0:
|
||||||
|
has_activity = True
|
||||||
|
logger.info(f"✅ {username} has {game_type} activity: {game_data.get('games_played')} games")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# API вернул ответ, но без данных (нет активности)
|
||||||
|
message = data.get('message', 'No message')
|
||||||
|
logger.info(f"ℹ️ API response for {username}: {message} (no activity data)")
|
||||||
|
else:
|
||||||
|
logger.warning(f"⚠️ No response data for {username}: data is None")
|
||||||
|
|
||||||
# Only send response if there's activity
|
# Only send response if there's activity
|
||||||
if has_activity:
|
if has_activity:
|
||||||
formatted_response = StatsFormatter.format_stats_response(data, username, period, lang)
|
formatted_response = StatsFormatter.format_stats_response(data, username, period, lang)
|
||||||
await update.message.reply_text(formatted_response)
|
await update.message.reply_text(formatted_response)
|
||||||
has_any_activity = True
|
has_any_activity = True
|
||||||
|
else:
|
||||||
|
logger.info(f"ℹ️ No activity found for {username}, skipping response")
|
||||||
|
|
||||||
# Add delay between requests to avoid rate limiting
|
# Add delay between requests to avoid rate limiting
|
||||||
if i < len(gamers) - 1:
|
if i < len(gamers) - 1:
|
||||||
|
|
|
||||||
|
|
@ -37,19 +37,31 @@ class LichessAPI:
|
||||||
|
|
||||||
async def get_today_stats(self, username: str) -> Optional[Dict[str, Any]]:
|
async def get_today_stats(self, username: str) -> Optional[Dict[str, Any]]:
|
||||||
"""Get today's statistics from our stats API"""
|
"""Get today's statistics from our stats API"""
|
||||||
|
logger.info(f"🔍 LichessAPI.get_today_stats: username={username}, stats_base_url={self.stats_base_url}")
|
||||||
await self.rate_limiter.wait_if_needed()
|
await self.rate_limiter.wait_if_needed()
|
||||||
|
url = f"{self.stats_base_url}/stats/{username}/today"
|
||||||
|
logger.info(f"🔍 Making request to: {url}")
|
||||||
try:
|
try:
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.get(
|
async with session.get(url) as response:
|
||||||
f"{self.stats_base_url}/stats/{username}/today"
|
logger.info(f"🔍 Response status: {response.status} for {username}")
|
||||||
) as response:
|
|
||||||
if response.status == 200:
|
if response.status == 200:
|
||||||
return await response.json()
|
result = await response.json()
|
||||||
|
logger.info(f"🔍 Successfully got stats for {username}: {result.get('message', 'no message')}")
|
||||||
|
return result
|
||||||
else:
|
else:
|
||||||
logger.error(f"Failed to get today stats: {response.status}")
|
error_text = await response.text()
|
||||||
|
logger.error(f"❌ Failed to get today stats for {username}: status={response.status}, error={error_text[:200]}")
|
||||||
return None
|
return None
|
||||||
|
except aiohttp.ClientError as e:
|
||||||
|
logger.error(f"❌ Client error getting today stats for {username}: {e}")
|
||||||
|
import traceback
|
||||||
|
logger.error(traceback.format_exc())
|
||||||
|
return None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error getting today stats: {e}")
|
logger.error(f"❌ Error getting today stats for {username}: {e}")
|
||||||
|
import traceback
|
||||||
|
logger.error(traceback.format_exc())
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def get_yesterday_stats(self, username: str) -> Optional[Dict[str, Any]]:
|
async def get_yesterday_stats(self, username: str) -> Optional[Dict[str, Any]]:
|
||||||
|
|
|
||||||
|
|
@ -59,33 +59,39 @@ class LichessClient:
|
||||||
httpx.HTTPStatusError: При ошибках HTTP (кроме 404)
|
httpx.HTTPStatusError: При ошибках HTTP (кроме 404)
|
||||||
Exception: При других ошибках
|
Exception: При других ошибках
|
||||||
"""
|
"""
|
||||||
|
logger.info(f"🔍 LichessClient.get_user_activity: username={username}")
|
||||||
try:
|
try:
|
||||||
# Rate limiting: ждем если нужно
|
# Rate limiting: ждем если нужно
|
||||||
await self.rate_limiter.wait_if_needed()
|
await self.rate_limiter.wait_if_needed()
|
||||||
|
|
||||||
# Формируем URL для получения активности пользователя
|
# Формируем URL для получения активности пользователя
|
||||||
url = f"{self.base_url}/user/{username}/activity"
|
url = f"{self.base_url}/user/{username}/activity"
|
||||||
logger.info(f"Запрос активности пользователя {username}")
|
logger.info(f"🔍 Making request to Lichess API: {url}")
|
||||||
|
|
||||||
# Выполняем HTTP GET запрос
|
# Выполняем HTTP GET запрос
|
||||||
response = await self.client.get(url)
|
response = await self.client.get(url)
|
||||||
|
logger.info(f"🔍 Lichess API response status: {response.status_code} for {username}")
|
||||||
response.raise_for_status() # Проверяем статус ответа
|
response.raise_for_status() # Проверяем статус ответа
|
||||||
|
|
||||||
# Возвращаем JSON данные
|
# Возвращаем JSON данные
|
||||||
return response.json()
|
result = response.json()
|
||||||
|
logger.info(f"🔍 Received activity data for {username}: {len(result) if isinstance(result, list) else 'not a list'} items")
|
||||||
|
return result
|
||||||
|
|
||||||
except httpx.HTTPStatusError as e:
|
except httpx.HTTPStatusError as e:
|
||||||
if e.response.status_code == 404:
|
if e.response.status_code == 404:
|
||||||
# Пользователь не найден - это нормальная ситуация
|
# Пользователь не найден - это нормальная ситуация
|
||||||
logger.warning(f"Пользователь {username} не найден")
|
logger.warning(f"⚠️ Пользователь {username} не найден (404)")
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
# Другие HTTP ошибки - логируем и пробрасываем
|
# Другие HTTP ошибки - логируем и пробрасываем
|
||||||
logger.error(f"HTTP ошибка при получении активности пользователя {username}: {e}")
|
logger.error(f"❌ HTTP ошибка при получении активности пользователя {username}: status={e.response.status_code}, error={e}")
|
||||||
raise
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Обрабатываем все остальные ошибки
|
# Обрабатываем все остальные ошибки
|
||||||
logger.error(f"Ошибка при получении активности пользователя {username}: {e}")
|
logger.error(f"❌ Ошибка при получении активности пользователя {username}: {e}")
|
||||||
|
import traceback
|
||||||
|
logger.error(traceback.format_exc())
|
||||||
raise
|
raise
|
||||||
|
|
||||||
async def get_games_of_period(self, username: str, since_ms: int, until_ms: int, rated_only: bool = True) -> Optional[List[Dict[str, Any]]]:
|
async def get_games_of_period(self, username: str, since_ms: int, until_ms: int, rated_only: bool = True) -> Optional[List[Dict[str, Any]]]:
|
||||||
|
|
|
||||||
|
|
@ -213,29 +213,49 @@ class StatsService:
|
||||||
Returns:
|
Returns:
|
||||||
ActivityResponse с данными статистики или сообщением об ошибке
|
ActivityResponse с данными статистики или сообщением об ошибке
|
||||||
"""
|
"""
|
||||||
|
logger.info(f"🔍 StatsService.get_today_stats: username={username}")
|
||||||
try:
|
try:
|
||||||
|
logger.info(f"🔍 Calling lichess_client.get_user_activity for {username}")
|
||||||
activity_data = await self.lichess_client.get_user_activity(username)
|
activity_data = await self.lichess_client.get_user_activity(username)
|
||||||
|
logger.info(f"🔍 Activity data received: {activity_data is not None}, type={type(activity_data)}")
|
||||||
if not activity_data:
|
if not activity_data:
|
||||||
|
logger.warning(f"⚠️ No activity data for {username}")
|
||||||
return ActivityResponse(
|
return ActivityResponse(
|
||||||
message=f"Пользователь {username} не найден или неактивен"
|
message=f"Пользователь {username} не найден или неактивен"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logger.info(f"🔍 Activity data length: {len(activity_data) if isinstance(activity_data, list) else 'not a list'}")
|
||||||
|
|
||||||
today = date.today()
|
today = date.today()
|
||||||
|
logger.info(f"🔍 Looking for activity for today: {today}")
|
||||||
|
|
||||||
# Ищем активность за сегодня
|
# Ищем активность за сегодня
|
||||||
|
# Lichess возвращает интервалы, которые могут начинаться вчера, но включать активность сегодня
|
||||||
today_activity = None
|
today_activity = None
|
||||||
for activity in activity_data:
|
for activity in activity_data:
|
||||||
activity_date = self._parse_lichess_interval(activity['interval'])
|
interval = activity['interval']
|
||||||
if activity_date == today:
|
# Парсим начало и конец интервала
|
||||||
|
start_timestamp = interval['start'] / 1000
|
||||||
|
end_timestamp = interval['end'] / 1000
|
||||||
|
start_date = datetime.fromtimestamp(start_timestamp).date()
|
||||||
|
end_date = datetime.fromtimestamp(end_timestamp).date()
|
||||||
|
|
||||||
|
logger.debug(f"🔍 Checking activity interval: {start_date} to {end_date} vs today: {today}")
|
||||||
|
|
||||||
|
# Проверяем, попадает ли сегодняшняя дата в интервал
|
||||||
|
if start_date <= today <= end_date:
|
||||||
today_activity = activity
|
today_activity = activity
|
||||||
|
logger.info(f"✅ Found today activity for {username} (interval: {start_date} to {end_date})")
|
||||||
break
|
break
|
||||||
|
|
||||||
if not today_activity:
|
if not today_activity:
|
||||||
|
logger.info(f"ℹ️ No activity found for today ({today}) for {username}")
|
||||||
return ActivityResponse(
|
return ActivityResponse(
|
||||||
message=f"Активности за сегодняшний день ({today}) не было"
|
message=f"Активности за сегодняшний день ({today}) не было"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Обрабатываем данные
|
# Обрабатываем данные
|
||||||
|
logger.info(f"🔍 Processing activity data for {username}")
|
||||||
games_stats = self._process_games_by_mode(today_activity.get('games', {}))
|
games_stats = self._process_games_by_mode(today_activity.get('games', {}))
|
||||||
tasks_stats = self._process_tasks(today_activity.get('puzzles', {}))
|
tasks_stats = self._process_tasks(today_activity.get('puzzles', {}))
|
||||||
|
|
||||||
|
|
@ -245,13 +265,16 @@ class StatsService:
|
||||||
games=GamesStats(**games_stats)
|
games=GamesStats(**games_stats)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logger.info(f"✅ Successfully processed stats for {username}")
|
||||||
return ActivityResponse(
|
return ActivityResponse(
|
||||||
message="Статистика за сегодняшний день",
|
message="Статистика за сегодняшний день",
|
||||||
data=user_stats
|
data=user_stats
|
||||||
)
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Ошибка при получении статистики за сегодня: {e}")
|
logger.error(f"❌ Ошибка при получении статистики за сегодня для {username}: {e}")
|
||||||
|
import traceback
|
||||||
|
logger.error(traceback.format_exc())
|
||||||
return ActivityResponse(
|
return ActivityResponse(
|
||||||
message=f"Ошибка при получении статистики: {str(e)}"
|
message=f"Ошибка при получении статистики: {str(e)}"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
80
test_kostik2811.py
Executable file
80
test_kostik2811.py
Executable file
|
|
@ -0,0 +1,80 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Скрипт для тестирования запросов к Lichess API для пользователя kostik2811
|
||||||
|
"""
|
||||||
|
import asyncio
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Добавляем пути к модулям
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'LichessWebServices'))
|
||||||
|
|
||||||
|
from lichess_client import LichessClient
|
||||||
|
from stats_service import StatsService
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# Настройка логирования
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.INFO,
|
||||||
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||||
|
)
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
async def test_kostik2811():
|
||||||
|
"""Тестирование запросов для kostik2811"""
|
||||||
|
username = "kostik2811"
|
||||||
|
|
||||||
|
logger.info(f"🔍 Тестирование запросов для пользователя: {username}")
|
||||||
|
|
||||||
|
# Тест 1: Прямой запрос к Lichess API
|
||||||
|
logger.info("\n" + "="*50)
|
||||||
|
logger.info("ТЕСТ 1: Прямой запрос к Lichess API")
|
||||||
|
logger.info("="*50)
|
||||||
|
|
||||||
|
lichess_client = LichessClient()
|
||||||
|
try:
|
||||||
|
activity_data = await lichess_client.get_user_activity(username)
|
||||||
|
if activity_data:
|
||||||
|
logger.info(f"✅ Получены данные активности: {len(activity_data)} записей")
|
||||||
|
for i, activity in enumerate(activity_data[:3]): # Показываем первые 3
|
||||||
|
logger.info(f" Активность {i+1}: {activity.get('interval', 'N/A')}")
|
||||||
|
else:
|
||||||
|
logger.warning(f"⚠️ Данные активности не получены (None или пусто)")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"❌ Ошибка при запросе к Lichess API: {e}")
|
||||||
|
import traceback
|
||||||
|
logger.error(traceback.format_exc())
|
||||||
|
finally:
|
||||||
|
await lichess_client.close()
|
||||||
|
|
||||||
|
# Тест 2: Запрос через StatsService
|
||||||
|
logger.info("\n" + "="*50)
|
||||||
|
logger.info("ТЕСТ 2: Запрос через StatsService.get_today_stats")
|
||||||
|
logger.info("="*50)
|
||||||
|
|
||||||
|
lichess_client2 = LichessClient()
|
||||||
|
stats_service = StatsService(lichess_client2)
|
||||||
|
try:
|
||||||
|
result = await stats_service.get_today_stats(username)
|
||||||
|
logger.info(f"✅ Результат StatsService: message={result.message}")
|
||||||
|
if result.data:
|
||||||
|
logger.info(f" Данные: username={result.data.username}")
|
||||||
|
logger.info(f" Задачи: {result.data.tasks}")
|
||||||
|
logger.info(f" Игры: {result.data.games}")
|
||||||
|
else:
|
||||||
|
logger.warning(f"⚠️ Нет данных в результате")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"❌ Ошибка в StatsService: {e}")
|
||||||
|
import traceback
|
||||||
|
logger.error(traceback.format_exc())
|
||||||
|
finally:
|
||||||
|
await lichess_client2.close()
|
||||||
|
|
||||||
|
logger.info("\n" + "="*50)
|
||||||
|
logger.info("Тестирование завершено")
|
||||||
|
logger.info("="*50)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(test_kostik2811())
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue