From 595c9419f4be478cc92b295a25e65581ce4e5b00 Mon Sep 17 00:00:00 2001 From: vrubelroman Date: Sun, 23 Nov 2025 01:46:12 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B0=20=D0=B4=D1=83=D0=B1=D0=BB=D0=B8=D0=BA?= =?UTF-8?q?=D0=B0=D1=82=D1=8B=20=D0=B8=20=D1=80=D1=8F=D0=B4=20=D0=B1=D0=B0?= =?UTF-8?q?=D0=B3=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LichessClientTG_bot/bot.py | 73 ++++++++++++++++++++++++++++--- LichessClientTG_bot/formatters.py | 3 ++ LichessClientTG_bot/i18n.py | 4 +- 3 files changed, 71 insertions(+), 9 deletions(-) diff --git a/LichessClientTG_bot/bot.py b/LichessClientTG_bot/bot.py index 493fc9f..e952579 100644 --- a/LichessClientTG_bot/bot.py +++ b/LichessClientTG_bot/bot.py @@ -278,19 +278,29 @@ class LichessBot: async def addgamer_start(self, update: Update, context: ContextTypes.DEFAULT_TYPE): """Start addgamer command - simple username only""" - logger.info(f"addgamer_start called for user {update.effective_user.id}") + user_id = update.effective_user.id + logger.info(f"addgamer_start called for user {user_id}") + + # Check if we're already awaiting a username (prevent duplicate messages) + if context and hasattr(context, "user_data") and context.user_data.get('awaiting_addgamer_username'): + logger.info(f"addgamer_start: Already awaiting username for user {user_id}, skipping duplicate call") + return + lang = self.get_user_language_from_update(update) try: # Mark that we are awaiting a username reply if context and hasattr(context, "user_data"): context.user_data['awaiting_addgamer_username'] = True await update.message.reply_text(t('addgamer_prompt', lang)) - logger.info(f"Addgamer prompt sent to user {update.effective_user.id}") + logger.info(f"Addgamer prompt sent to user {user_id}") self.counters.increment('addgamer') except Exception as e: logger.error(f"Error sending addgamer prompt: {e}") import traceback logger.error(traceback.format_exc()) + # Clear flag on error + if context and hasattr(context, "user_data"): + context.user_data['awaiting_addgamer_username'] = False # No conversation state returned; handler-based flow return @@ -420,18 +430,46 @@ class LichessBot: ) return WAITING_FOR_USERNAME + # Check if this gamer is already tracked by this user + user_gamers = self.db.get_user_gamers(user_id) + existing_gamer = next((g for g in user_gamers if g['username'].lower() == username.lower()), None) + + if existing_gamer: + # Player is already being tracked by this user + await update.message.reply_text( + t('gamer_already_added', lang, username=username) + ) + # Clear awaiting flag + try: + context.user_data['awaiting_addgamer_username'] = False + except Exception: + pass + return + # Add gamer to database (without token) - # Check if gamer already exists + # Check if gamer already exists in global gamers table import sqlite3 with sqlite3.connect(self.db.db_path) as conn: cursor = conn.cursor() cursor.execute("SELECT id FROM gamers WHERE username = ?", (username,)) - existing_gamer = cursor.fetchone() - is_new_gamer = existing_gamer is None + existing_gamer_row = cursor.fetchone() + is_new_gamer = existing_gamer_row is None gamer_id = self.db.add_gamer(username) # Link user to gamer (without token) - self.db.add_user_gamer(user_id, gamer_id, None) + added = self.db.add_user_gamer(user_id, gamer_id, None) + + # If add_user_gamer returned False, it means the pair already exists (shouldn't happen after our check, but just in case) + if not added: + await update.message.reply_text( + t('gamer_already_added', lang, username=username) + ) + # Clear awaiting flag + try: + context.user_data['awaiting_addgamer_username'] = False + except Exception: + pass + return # Set default period to 1 hour (60 minutes) for new gamer self.db.set_user_gamer_period(user_id, gamer_id, 60) @@ -486,10 +524,13 @@ class LichessBot: lang = self.get_user_language_from_update(update) if not gamers: + logger.info(f"getgamers: No gamers found for user {user_id}, sending no_gamers message") await update.message.reply_text(t('no_gamers', lang)) self.counters.increment('getgamers') return + logger.info(f"getgamers: Proceeding with {len(gamers)} gamers for user {user_id}") + self.counters.increment('getgamers') # Show loading message @@ -560,6 +601,17 @@ class LichessBot: ) logger.info(f"getgamers: prepared {len(gamers_data)} gamers for display") + + # Check if we have any gamers to display + if not gamers_data: + logger.warning(f"getgamers: No gamers data prepared, but gamers list was not empty. This should not happen.") + try: + await loading_msg.delete() + except: + pass + await update.message.reply_text(t('no_gamers', lang)) + return + gamers_text = t('select_active_gamer', lang) + "\n".join(text_lines) logger.info(f"getgamers: message length: {len(gamers_text)} characters") @@ -581,6 +633,8 @@ class LichessBot: gamers_text, parse_mode='HTML' ) + + logger.info(f"getgamers: Completed successfully for user {user_id}, displayed {len(gamers_data)} gamers") async def select_gamer(self, update: Update, context: ContextTypes.DEFAULT_TYPE): """Handle gamer selection""" @@ -836,7 +890,12 @@ class LichessBot: else: # API вернул ответ, но без данных (нет активности) message = data.get('message', 'No message') - logger.info(f"ℹ️ API response for {username}: {message} (no activity data)") + # Filter out old "No active player" messages - this functionality is deprecated + if 'No active player' in message or 'Нет активного игрока' in message or 'active player' in message.lower() or 'активного игрока' in message.lower(): + logger.info(f"ℹ️ API response for {username}: filtered out deprecated 'No active player' message") + message = None + else: + logger.info(f"ℹ️ API response for {username}: {message} (no activity data)") else: logger.warning(f"⚠️ No response data for {username}: data is None") diff --git a/LichessClientTG_bot/formatters.py b/LichessClientTG_bot/formatters.py index 1874f16..26b24ad 100644 --- a/LichessClientTG_bot/formatters.py +++ b/LichessClientTG_bot/formatters.py @@ -18,6 +18,9 @@ class StatsFormatter: """Format statistics response according to the template""" if not data or data.get('data') is None: message = data.get('message', t('no_data', lang)) if data else t('no_data', lang) + # Filter out old "No active player" messages - this functionality is deprecated + if 'No active player' in message or 'Нет активного игрока' in message or 'active player' in message.lower() or 'активного игрока' in message.lower(): + return t('no_data', lang) return f"📭 {message}" # Extract data from API response diff --git a/LichessClientTG_bot/i18n.py b/LichessClientTG_bot/i18n.py index 51c70b9..1d89354 100644 --- a/LichessClientTG_bot/i18n.py +++ b/LichessClientTG_bot/i18n.py @@ -57,6 +57,7 @@ TRANSLATIONS = { 'token_username_error': "❌ Failed to get username from token. Please try again.", 'empty_username': "❌ Username cannot be empty. Please try again.", 'user_not_found': "❌ Player {username} not found on Lichess. Check the spelling of the name.", + 'gamer_already_added': "ℹ️ Player {username} is already being tracked.\n\nTo add another player, use /addgamer", # Get gamers 'no_gamers': "📭 No players in database. Use /addgamer to add.", @@ -75,7 +76,6 @@ TRANSLATIONS = { 'delete_failed': "❌ Failed to delete player", # Stats commands - 'no_active_gamer': "❌ No active player. Use /getgamers to select.", 'unknown_period': "❌ Unknown period", 'no_data': "📭 No data", 'stats_title': "📊 Statistics {username} • {date_range}\n\n", @@ -180,6 +180,7 @@ TRANSLATIONS = { 'token_username_error': "❌ Не удалось получить username из токена. Попробуйте еще раз.", 'empty_username': "❌ Username не может быть пустым. Попробуйте еще раз.", 'user_not_found': "❌ Игрок {username} не найден на Lichess. Проверьте правильность написания имени.", + 'gamer_already_added': "ℹ️ Игрок {username} уже отслеживается.\n\nДля добавления следующего игрока воспользуйтесь /addgamer", # Get gamers 'no_gamers': "📭 Нет игроков в базе данных. Используйте /addgamer для добавления.", @@ -198,7 +199,6 @@ TRANSLATIONS = { 'delete_failed': "❌ Не удалось удалить игрока", # Stats commands - 'no_active_gamer': "❌ Нет активного игрока. Используйте /getgamers для выбора.", 'unknown_period': "❌ Неизвестный период", 'no_data': "📭 Нет данных", 'stats_title': "📊 Статистика {username} • {date_range}\n\n",