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"""
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -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]]:
|
||||
|
|
|
|||
|
|
@ -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]]]:
|
||||
|
|
|
|||
|
|
@ -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)}"
|
||||
)
|
||||
|
|
|
|||
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