From 4dc5539da2432350fef1244983766eea77e44f27 Mon Sep 17 00:00:00 2001 From: vrubelroman Date: Thu, 20 Nov 2025 03:14:06 +0300 Subject: [PATCH] bug today --- LichessClientTG_bot/bot.py | 78 ++++++++++++++++++--------- LichessClientTG_bot/lichess_api.py | 24 ++++++--- LichessWebServices/lichess_client.py | 16 ++++-- LichessWebServices/stats_service.py | 29 ++++++++-- test_kostik2811.py | 80 ++++++++++++++++++++++++++++ 5 files changed, 189 insertions(+), 38 deletions(-) create mode 100755 test_kostik2811.py diff --git a/LichessClientTG_bot/bot.py b/LichessClientTG_bot/bot.py index 62ea00c..62216cb 100644 --- a/LichessClientTG_bot/bot.py +++ b/LichessClientTG_bot/bot.py @@ -732,8 +732,11 @@ class LichessBot: """Get statistics for a period - shows stats for all players with activity""" user_id = update.effective_user.id + logger.info(f"🔍 get_stats called: user_id={user_id}, period={period}") + # Get all gamers for this user 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) if not gamers: @@ -752,6 +755,7 @@ class LichessBot: has_any_activity = False for i, gamer in enumerate(gamers): username = gamer['username'] + logger.info(f"🔍 Processing gamer {i+1}/{len(gamers)}: {username} for period {period}") # Send message about processing this player processing_msg = None @@ -761,15 +765,28 @@ class LichessBot: pass # Get stats based on period - if period == "today": - data = await self.lichess_api.get_today_stats(username) - elif period == "yesterday": - data = await self.lichess_api.get_yesterday_stats(username) - elif period == "week": - data = await self.lichess_api.get_week_stats(username) - else: - await update.message.reply_text(t('unknown_period', lang)) - return + try: + logger.info(f"🔍 Making API request for {username}, period={period}") + if period == "today": + data = await self.lichess_api.get_today_stats(username) + elif period == "yesterday": + data = await self.lichess_api.get_yesterday_stats(username) + elif period == "week": + data = await self.lichess_api.get_week_stats(username) + 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 if processing_msg: @@ -780,27 +797,40 @@ class LichessBot: # Check if there's activity has_activity = False - if data and data.get('data'): - api_data = data.get('data', {}) - tasks = api_data.get('tasks', {}) - games = api_data.get('games', {}) - - # Check for puzzles activity - if tasks and tasks.get('total', 0) > 0: - has_activity = True - - # Check for games activity - if games: - for game_type, game_data in games.items(): - if game_data and game_data.get('games_played', 0) > 0: - has_activity = True - break + if data: + if data.get('data'): + api_data = data.get('data', {}) + tasks = api_data.get('tasks', {}) + games = api_data.get('games', {}) + + logger.info(f"🔍 Activity check for {username}: tasks={tasks}, games={games}") + + # Check for puzzles activity + if tasks and tasks.get('total', 0) > 0: + has_activity = True + logger.info(f"✅ {username} has puzzles activity: {tasks.get('total')}") + + # Check for games activity + 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 if has_activity: formatted_response = StatsFormatter.format_stats_response(data, username, period, lang) await update.message.reply_text(formatted_response) has_any_activity = True + else: + logger.info(f"ℹ️ No activity found for {username}, skipping response") # Add delay between requests to avoid rate limiting if i < len(gamers) - 1: diff --git a/LichessClientTG_bot/lichess_api.py b/LichessClientTG_bot/lichess_api.py index 2a36a56..f25f704 100644 --- a/LichessClientTG_bot/lichess_api.py +++ b/LichessClientTG_bot/lichess_api.py @@ -37,19 +37,31 @@ class LichessAPI: async def get_today_stats(self, username: str) -> Optional[Dict[str, Any]]: """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() + url = f"{self.stats_base_url}/stats/{username}/today" + logger.info(f"🔍 Making request to: {url}") try: async with aiohttp.ClientSession() as session: - async with session.get( - f"{self.stats_base_url}/stats/{username}/today" - ) as response: + async with session.get(url) as response: + logger.info(f"🔍 Response status: {response.status} for {username}") 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: - 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 + 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: - 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 async def get_yesterday_stats(self, username: str) -> Optional[Dict[str, Any]]: diff --git a/LichessWebServices/lichess_client.py b/LichessWebServices/lichess_client.py index 91fa797..7d2e698 100644 --- a/LichessWebServices/lichess_client.py +++ b/LichessWebServices/lichess_client.py @@ -59,33 +59,39 @@ class LichessClient: httpx.HTTPStatusError: При ошибках HTTP (кроме 404) Exception: При других ошибках """ + logger.info(f"🔍 LichessClient.get_user_activity: username={username}") try: # Rate limiting: ждем если нужно await self.rate_limiter.wait_if_needed() # Формируем URL для получения активности пользователя url = f"{self.base_url}/user/{username}/activity" - logger.info(f"Запрос активности пользователя {username}") + logger.info(f"🔍 Making request to Lichess API: {url}") # Выполняем HTTP GET запрос response = await self.client.get(url) + logger.info(f"🔍 Lichess API response status: {response.status_code} for {username}") response.raise_for_status() # Проверяем статус ответа # Возвращаем 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: if e.response.status_code == 404: # Пользователь не найден - это нормальная ситуация - logger.warning(f"Пользователь {username} не найден") + logger.warning(f"⚠️ Пользователь {username} не найден (404)") return None else: # Другие HTTP ошибки - логируем и пробрасываем - logger.error(f"HTTP ошибка при получении активности пользователя {username}: {e}") + logger.error(f"❌ HTTP ошибка при получении активности пользователя {username}: status={e.response.status_code}, error={e}") raise except Exception as e: # Обрабатываем все остальные ошибки - logger.error(f"Ошибка при получении активности пользователя {username}: {e}") + logger.error(f"❌ Ошибка при получении активности пользователя {username}: {e}") + import traceback + logger.error(traceback.format_exc()) 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]]]: diff --git a/LichessWebServices/stats_service.py b/LichessWebServices/stats_service.py index 1747b87..1b1d8d0 100644 --- a/LichessWebServices/stats_service.py +++ b/LichessWebServices/stats_service.py @@ -213,29 +213,49 @@ class StatsService: Returns: ActivityResponse с данными статистики или сообщением об ошибке """ + logger.info(f"🔍 StatsService.get_today_stats: username={username}") try: + logger.info(f"🔍 Calling lichess_client.get_user_activity for {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: + logger.warning(f"⚠️ No activity data for {username}") return ActivityResponse( message=f"Пользователь {username} не найден или неактивен" ) + logger.info(f"🔍 Activity data length: {len(activity_data) if isinstance(activity_data, list) else 'not a list'}") + today = date.today() + logger.info(f"🔍 Looking for activity for today: {today}") # Ищем активность за сегодня + # Lichess возвращает интервалы, которые могут начинаться вчера, но включать активность сегодня today_activity = None for activity in activity_data: - activity_date = self._parse_lichess_interval(activity['interval']) - if activity_date == today: + interval = activity['interval'] + # Парсим начало и конец интервала + 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 + logger.info(f"✅ Found today activity for {username} (interval: {start_date} to {end_date})") break if not today_activity: + logger.info(f"ℹ️ No activity found for today ({today}) for {username}") return ActivityResponse( message=f"Активности за сегодняшний день ({today}) не было" ) # Обрабатываем данные + logger.info(f"🔍 Processing activity data for {username}") games_stats = self._process_games_by_mode(today_activity.get('games', {})) tasks_stats = self._process_tasks(today_activity.get('puzzles', {})) @@ -245,13 +265,16 @@ class StatsService: games=GamesStats(**games_stats) ) + logger.info(f"✅ Successfully processed stats for {username}") return ActivityResponse( message="Статистика за сегодняшний день", data=user_stats ) except Exception as e: - logger.error(f"Ошибка при получении статистики за сегодня: {e}") + logger.error(f"❌ Ошибка при получении статистики за сегодня для {username}: {e}") + import traceback + logger.error(traceback.format_exc()) return ActivityResponse( message=f"Ошибка при получении статистики: {str(e)}" ) diff --git a/test_kostik2811.py b/test_kostik2811.py new file mode 100755 index 0000000..4df3035 --- /dev/null +++ b/test_kostik2811.py @@ -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()) +