admin panel

This commit is contained in:
vrubelroman 2025-11-13 01:00:48 +03:00
parent 3362bf89e2
commit 23de80f94d
6 changed files with 424 additions and 20 deletions

View file

@ -13,12 +13,13 @@ from telegram.ext import (
from config import (
TELEGRAM_BOT_TOKEN, PERIOD_OPTIONS, POLL_INTERVAL,
POLL_TIMEOUT, DROP_PENDING_UPDATES, ALLOWED_UPDATES,
LICHESS_STATS_API_BASE_URL
LICHESS_STATS_API_BASE_URL, ADMINPANEL_TELEGRAM_BOT_TOKEN
)
from database import Database
from lichess_api import LichessAPI
from formatters import StatsFormatter
from i18n import t
from admin_bot import get_admin_bot, init_admin_bot
# Configure logging
logging.basicConfig(
@ -70,31 +71,60 @@ class LichessBot:
async def start(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Start command handler"""
logger.info(f"📝 start() method called for user {update.effective_user.id}")
# Register user in database
user = update.effective_user
lang_code = user.language_code if user else None
self.db.add_or_get_telegram_user(
logger.info(f"User info: id={user.id}, username={user.username}, lang_code={lang_code}")
is_new_user = self.db.add_or_get_telegram_user(
user_id=user.id,
username=user.username,
first_name=user.first_name,
last_name=user.last_name,
language_code=lang_code
)
# Notify admin bot about new user
if is_new_user:
admin_bot = get_admin_bot()
if admin_bot:
await admin_bot.notify_new_user(
user_id=user.id,
username=user.username,
first_name=user.first_name
)
lang = self.get_user_language_from_update(update)
await update.message.reply_text(t('start_message', lang))
start_msg = t('start_message', lang)
await update.message.reply_text(start_msg)
async def start_and_addgamer(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Start command that automatically launches addgamer"""
# First run the regular start command
await self.start(update, context)
# Then start addgamer conversation
return await self.addgamer_start(update, context)
"""Start command that shows welcome message and starts addgamer conversation"""
try:
# Run the regular start command
await self.start(update, context)
# Start addgamer conversation and return state
return await self.addgamer_start(update, context)
except Exception as e:
logger.error(f"Error in start_and_addgamer: {e}")
import traceback
logger.error(traceback.format_exc())
try:
await update.message.reply_text(f"Error: {e}")
except:
pass
return ConversationHandler.END
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}")
lang = self.get_user_language_from_update(update)
await update.message.reply_text(t('addgamer_prompt', lang))
try:
await update.message.reply_text(t('addgamer_prompt', lang))
logger.info(f"Addgamer prompt sent to user {update.effective_user.id}")
except Exception as e:
logger.error(f"Error sending addgamer prompt: {e}")
import traceback
logger.error(traceback.format_exc())
return WAITING_FOR_USERNAME
async def addtoken_start(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
@ -126,6 +156,14 @@ class LichessBot:
)
else:
# Add new gamer and link with token
# Check if gamer already exists
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
gamer_id = self.db.add_gamer(username)
self.db.add_user_gamer(user_id, gamer_id, token)
@ -137,6 +175,17 @@ class LichessBot:
if len(user_gamers) == 1:
self.db.set_user_active_gamer(user_id, gamer_id)
# Notify admin bot about new player (only if it's a new gamer)
if is_new_gamer:
admin_bot = get_admin_bot()
if admin_bot:
user_obj = update.effective_user
await admin_bot.notify_new_player(
player_username=username,
added_by_user_id=user_id,
added_by_username=user_obj.username if user_obj else None
)
await update.message.reply_text(
t('gamer_added_with_token', lang, username=username)
)
@ -175,6 +224,14 @@ class LichessBot:
return WAITING_FOR_USERNAME
# Add gamer to database (without token)
# Check if gamer already exists
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
gamer_id = self.db.add_gamer(username)
# Link user to gamer (without token)
self.db.add_user_gamer(user_id, gamer_id, None)
@ -187,6 +244,28 @@ class LichessBot:
if len(user_gamers) == 1:
self.db.set_user_active_gamer(user_id, gamer_id)
# Notify admin bot about new player (only if it's a new gamer)
if is_new_gamer:
logger.info(f"New gamer detected: {username}, notifying admin bot...")
admin_bot = get_admin_bot()
if admin_bot:
user_obj = update.effective_user
try:
await admin_bot.notify_new_player(
player_username=username,
added_by_user_id=user_id,
added_by_username=user_obj.username if user_obj else None
)
logger.info(f"Admin bot notification sent for player {username}")
except Exception as e:
logger.error(f"Failed to notify admin bot: {e}")
import traceback
logger.error(traceback.format_exc())
else:
logger.warning("Admin bot not available for notification")
else:
logger.info(f"Gamer {username} already exists, skipping admin notification")
lang = self.get_user_language_from_update(update)
await update.message.reply_text(
t('gamer_added', lang, username=username)
@ -748,12 +827,13 @@ class LichessBot:
addgamer_conv = ConversationHandler(
entry_points=[
CommandHandler("addgamer", self.addgamer_start),
CommandHandler("start", self.start_and_addgamer) # Custom entry point that calls start and addgamer
CommandHandler("start", self.start_and_addgamer) # Also handle /start to start addgamer flow
],
states={
WAITING_FOR_USERNAME: [MessageHandler(filters.TEXT & ~filters.COMMAND, self.handle_username)],
},
fallbacks=[CommandHandler("cancel", lambda u, c: ConversationHandler.END)]
fallbacks=[CommandHandler("cancel", lambda u, c: ConversationHandler.END)],
name="addgamer_conversation"
)
# Conversation handler for addtoken (token required)
@ -765,8 +845,7 @@ class LichessBot:
fallbacks=[CommandHandler("cancel", lambda u, c: ConversationHandler.END)]
)
# Add all handlers
# Note: start command is handled by addgamer_conv entry_points
# Add conversation handlers
application.add_handler(addgamer_conv)
application.add_handler(addtoken_conv)
application.add_handler(CommandHandler("getgamers", self.getgamers))
@ -785,6 +864,9 @@ class LichessBot:
def main():
"""Main function"""
# Initialize admin bot for notifications (admin bot runs as separate service)
init_admin_bot()
bot = LichessBot()
# Create application with Long Polling configuration
@ -802,14 +884,29 @@ def main():
application.post_init = post_init
# Add error handler
async def error_handler(update: object, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Log the error and send a telegram message to notify the developer."""
logger.error(f"Exception while handling an update: {context.error}")
import traceback
logger.error(traceback.format_exc())
application.add_error_handler(error_handler)
# Start the bot with Long Polling
logger.info("Starting Lichess Statistics Bot with Long Polling...")
application.run_polling(
poll_interval=POLL_INTERVAL,
timeout=POLL_TIMEOUT,
drop_pending_updates=DROP_PENDING_UPDATES,
allowed_updates=ALLOWED_UPDATES
)
try:
application.run_polling(
poll_interval=POLL_INTERVAL,
timeout=POLL_TIMEOUT,
drop_pending_updates=DROP_PENDING_UPDATES,
allowed_updates=ALLOWED_UPDATES
)
except Exception as e:
logger.error(f"Fatal error in run_polling: {e}")
import traceback
logger.error(traceback.format_exc())
raise
if __name__ == '__main__':
main()