from typing import Dict, Any, Optional from datetime import datetime class StatsFormatter: @staticmethod def _format_rating_change(rating_change: int) -> str: """Format rating change with colored circles""" if rating_change > 0: return f"🟢 +{rating_change}" elif rating_change < 0: return f"🔴 {rating_change}" else: return f"0" @staticmethod def format_stats_response(data: Dict[str, Any], username: str, period: str) -> str: """Format statistics response according to the template""" if not data or data.get('data') is None: message = data.get('message', 'Нет данных') if data else 'Нет данных' return f"📭 {message}" # Extract data from API response api_data = data.get('data', {}) tasks = api_data.get('tasks', {}) games = api_data.get('games', {}) # Format date range date_range = StatsFormatter._get_date_range(period) # Format tasks section task_text = "" if tasks and tasks.get('total', 0) > 0: total_tasks = tasks.get('total', 0) solved = tasks.get('solved', 0) unsolved = tasks.get('unsolved', 0) task_text = f"🧩 Задачи: {total_tasks} (✅ {solved} - ❌ {unsolved})\n\n" # Format games section games_text = "" if games: for game_type, game_data in games.items(): if not game_data or game_data.get('games_played', 0) == 0: continue # Get game type emoji emoji = StatsFormatter._get_game_type_emoji(game_type) games_count = game_data.get('games_played', 0) rating_change = game_data.get('rating_change', 0) rating = game_data.get('final_rating', 0) wins = game_data.get('wins', 0) losses = game_data.get('losses', 0) draws = game_data.get('draws', 0) # Format rating change rating_change_str = StatsFormatter._format_rating_change(rating_change) games_text += f"{emoji} {game_type.title()} — {games_count} игр • {rating_change_str}\n" games_text += f"Рейтинг: {rating}\n" games_text += f"✅ Победы: {wins}\n" games_text += f"❌ Поражения: {losses}\n" games_text += f"🤝 Ничьи: {draws}\n\n" # Combine all parts result = f"📊 Статистика {username} • {date_range}\n\n" result += task_text result += games_text.rstrip() return result @staticmethod def _get_date_range(period: str) -> str: """Get date range string for the period""" from datetime import datetime, timedelta today = datetime.now() if period == "today": return today.strftime("%d.%m.%Y") elif period == "yesterday": yesterday = today - timedelta(days=1) return yesterday.strftime("%d.%m.%Y") elif period == "week": week_ago = today - timedelta(days=7) return f"{week_ago.strftime('%d.%m.%Y')}–{today.strftime('%d.%m.%Y')}" else: return today.strftime("%d.%m.%Y") @staticmethod def _get_game_type_emoji(game_type: str) -> str: """Get emoji for game type""" emoji_map = { 'bullet': '⚡️', 'blitz': '🔥', 'rapid': '🐇', 'classical': '♟️', 'correspondence': '📮' } return emoji_map.get(game_type.lower(), '🎯') @staticmethod def format_period_notification(username: str, games_data: Optional[Dict], puzzles_data: Optional[Dict], period_minutes: int) -> str: """Format notification for periodic checks""" from datetime import datetime # Format period text if period_minutes == 1: period_text = "за 1 минуту" elif period_minutes in [2, 3, 4]: period_text = f"за {period_minutes} минуты" else: period_text = f"за {period_minutes} минут" result = f"📊 Статистика {username} • {period_text}\n\n" # Format puzzles first (if available and there's actual activity) if puzzles_data and puzzles_data.get('data'): puzzles_info = puzzles_data['data'] total_puzzles = puzzles_info.get('total_attempts', 0) solved = puzzles_info.get('solved', 0) failed = puzzles_info.get('failed', 0) # Only show tasks section if there's actual activity (not all zeros) if total_puzzles > 0 or solved > 0 or failed > 0: result += f"🧩 Задачи: {total_puzzles} (✅ {solved} - ❌ {failed})\n\n" # Format games if games_data and games_data.get('data'): games_info = games_data['data'] total_games = games_info.get('total', {}).get('games_played', 0) # Show details for each game type if there were games if total_games > 0: for game_type, game_data in games_info.items(): if game_type != 'total' and game_data and game_data.get('games_played', 0) > 0: emoji = StatsFormatter._get_game_type_emoji(game_type) games_count = game_data.get('games_played', 0) rating_change = game_data.get('rating_change', 0) rating = game_data.get('rating', 0) wins = game_data.get('wins', 0) losses = game_data.get('losses', 0) draws = game_data.get('draws', 0) rating_change_str = StatsFormatter._format_rating_change(rating_change) result += f"{emoji} {game_type.title()} — {games_count} игр • {rating_change_str}\n" result += f"Рейтинг: {rating}\n" result += f"✅ Победы: {wins}\n" result += f"❌ Поражения: {losses}\n" result += f"🤝 Ничьи: {draws}\n\n" # If no activity if not (games_data and games_data.get('data')) and not (puzzles_data and puzzles_data.get('data')): result += "📭 Нет активности за этот период" return result.rstrip()