add statistics

This commit is contained in:
vrubelroman 2025-11-13 13:32:46 +03:00
parent 23de80f94d
commit ceb62b408a
6 changed files with 318 additions and 3 deletions

View file

@ -20,6 +20,7 @@ from lichess_api import LichessAPI
from formatters import StatsFormatter
from i18n import t
from admin_bot import get_admin_bot, init_admin_bot
from message_counters import MessageCounters
# Configure logging
logging.basicConfig(
@ -38,6 +39,7 @@ class LichessBot:
self.periodic_tasks = {} # Store periodic tasks
self.period_start_times = {} # Store start times for each gamer
self.application = None # Will be set when application is created
self.counters = MessageCounters() # Message counters
def get_user_language_from_update(self, update: Update) -> str:
"""Always return English language"""
@ -65,9 +67,38 @@ class LichessBot:
# Start periodic task with user_id and gamer
await self.start_periodic_task(gamer, user_id, gamer['period_minutes'])
logger.info(f"Started periodic task for {gamer['username']} (user {user_id}) with period {gamer['period_minutes']} minutes")
# Start daily counter reset task
asyncio.create_task(self.daily_counter_reset_task())
logger.info("Started daily counter reset task")
except Exception as e:
logger.error(f"Error starting existing periodic tasks: {e}")
async def daily_counter_reset_task(self):
"""Background task to reset daily counters at midnight"""
while True:
try:
# Calculate seconds until next midnight
now = datetime.now()
next_midnight = (now + timedelta(days=1)).replace(hour=0, minute=0, second=0, microsecond=0)
seconds_until_midnight = (next_midnight - now).total_seconds()
logger.info(f"Daily counter reset task: waiting {seconds_until_midnight} seconds until next midnight")
await asyncio.sleep(seconds_until_midnight)
# Reset daily counters
self.counters._reset_daily_counters_if_needed()
logger.info("Daily counters reset at midnight")
except asyncio.CancelledError:
break
except Exception as e:
logger.error(f"Error in daily counter reset task: {e}")
import traceback
logger.error(traceback.format_exc())
# Wait 1 hour before retrying
await asyncio.sleep(3600)
async def start(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Start command handler"""
@ -96,6 +127,7 @@ class LichessBot:
lang = self.get_user_language_from_update(update)
start_msg = t('start_message', lang)
await update.message.reply_text(start_msg)
self.counters.increment('start')
async def start_and_addgamer(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Start command that shows welcome message and starts addgamer conversation"""
@ -121,6 +153,7 @@ class LichessBot:
try:
await update.message.reply_text(t('addgamer_prompt', lang))
logger.info(f"Addgamer prompt sent to user {update.effective_user.id}")
self.counters.increment('addgamer')
except Exception as e:
logger.error(f"Error sending addgamer prompt: {e}")
import traceback
@ -131,6 +164,7 @@ class LichessBot:
"""Start addtoken command - token required"""
lang = self.get_user_language_from_update(update)
await update.message.reply_text(t('addtoken_prompt', lang))
self.counters.increment('addtoken')
return WAITING_FOR_TOKEN
async def handle_token(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
@ -283,8 +317,11 @@ class LichessBot:
lang = self.get_user_language_from_update(update)
if not gamers:
await update.message.reply_text(t('no_gamers', lang))
self.counters.increment('getgamers')
return
self.counters.increment('getgamers')
# Show loading message
loading_msg = await update.message.reply_text(t('loading_ratings', lang))
@ -431,8 +468,11 @@ class LichessBot:
lang = self.get_user_language_from_update(update)
if not gamers:
await update.message.reply_text(t('no_gamers_to_delete', lang))
self.counters.increment('delgamer')
return
self.counters.increment('delgamer')
# Show loading message
loading_msg = await update.message.reply_text(t('loading_gamers', lang))
@ -563,6 +603,14 @@ class LichessBot:
# Format and send response
formatted_response = StatsFormatter.format_stats_response(data, username, period, lang)
await update.message.reply_text(formatted_response)
# Increment counter for the period command
if period == "today":
self.counters.increment('today')
elif period == "yesterday":
self.counters.increment('yesterday')
elif period == "week":
self.counters.increment('week')
async def today(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Today command"""
@ -603,6 +651,7 @@ class LichessBot:
t('select_period', lang, username=active_gamer['username']),
reply_markup=reply_markup
)
self.counters.increment('setperiod')
async def select_period(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle period selection"""
@ -668,6 +717,7 @@ class LichessBot:
f"Bot uses English language only."
)
await update.message.reply_text(message)
self.counters.increment('lang')
else:
await update.message.reply_text("❌ Failed to get user information")
@ -689,6 +739,7 @@ class LichessBot:
await update.message.reply_text(
"✅ Language reset! Bot uses English language only."
)
self.counters.increment('resetlang')
else:
await update.message.reply_text("❌ Failed to get user information")
@ -799,6 +850,8 @@ class LichessBot:
logger.info(f"Sent periodic notification for {gamer['username']} to user {user_id}")
# Обновляем время начала только после успешной отправки уведомления
self.period_start_times[task_key] = now
# Increment periodic notification counter
self.counters.increment('periodic_notification')
except Exception as e:
logger.error(f"Failed to send notification to user {user_id}: {e}")
# Не обновляем время начала при ошибке отправки