#!/usr/bin/env python """ Enhanced Scheduler Bot with SQLite database support """ import sqlite3 import datetime from telegram import Update from telegram.ext import Application, CommandHandler, ContextTypes, MessageHandler, filters # 🔑 REPLACE THIS with your bot token from @BotFather BOT_TOKEN = "8248686383:AAGN5UJ73H9i7LQzIBR3TjuJgUGNTFyRHk8" # Database setup DATABASE_NAME = "schedule.db" def init_db(): """Initialize the SQLite database and create tables if they don't exist.""" conn = sqlite3.connect(DATABASE_NAME) cursor = conn.cursor() # Create table for schedule entries cursor.execute(''' CREATE TABLE IF NOT EXISTS schedule ( id INTEGER PRIMARY KEY AUTOINCREMENT, day TEXT NOT NULL, period INTEGER NOT NULL, subject TEXT NOT NULL, class_name TEXT NOT NULL, room TEXT NOT NULL, UNIQUE(day, period) ) ''') conn.commit() conn.close() def add_schedule_entry(day, period, subject, class_name, room): """Add a new schedule entry to the database.""" conn = sqlite3.connect(DATABASE_NAME) cursor = conn.cursor() try: cursor.execute(''' INSERT OR REPLACE INTO schedule (day, period, subject, class_name, room) VALUES (?, ?, ?, ?, ?) ''', (day, period, subject, class_name, room)) conn.commit() conn.close() return True except sqlite3.Error as e: print(f"Database error: {e}") conn.close() return False def load_schedule_from_db(): """Load schedule from the SQLite database.""" conn = sqlite3.connect(DATABASE_NAME) cursor = conn.cursor() cursor.execute("SELECT day, period, subject, class_name, room FROM schedule ORDER BY day, period") rows = cursor.fetchall() conn.close() # Group by day schedule = {} for day, period, subject, class_name, room in rows: if day not in schedule: schedule[day] = [] class_info = f"Subject: {subject} Class: {class_name} Room: {room}" schedule[day].append((str(period), class_info)) return schedule # Initialize the database init_db() # Map period numbers to times - Updated as requested period_times = { '1': ('09:00', '09:40'), '2': ('10:00', '10:40'), '3': ('11:00', '11:40'), '4': ('11:50', '12:30'), '5': ('12:40', '13:20'), '6': ('13:30', '14:10'), '7': ('14:20', '15:00'), '8': ('15:20', '16:00'), '9': ('16:15', '16:55'), '10': ('17:05', '17:45'), '11': ('17:55', '18:35'), '12': ('18:45', '19:20'), '13': ('19:20', '20:00') } # User states for tracking conversations user_states = {} # Stores user conversation state async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): """Send welcome message when command /start is issued.""" await update.message.reply_text( "🤖 Hello! I'm your enhanced class scheduler bot with database support!\n" "Use /whereami to find your current class\n" "Use /schedule to see today's full schedule\n" "Use /tomorrow to see tomorrow's schedule\n" "Use /add to add a new class to the schedule\n" "Use /help for all commands" ) async def where_am_i(update: Update, context: ContextTypes.DEFAULT_TYPE): """Tell user where they should be right now.""" # Reload schedule from DB to ensure latest data schedule = load_schedule_from_db() if not schedule: await update.message.reply_text("❌ Schedule not loaded from database.") return now = datetime.datetime.now() current_time = now.strftime("%H:%M") current_day = now.strftime("%A") await update.message.reply_text(f"📅 Today is {current_day}") await update.message.reply_text(f"⏰ Current time: {current_time}") # Check if we have schedule for today if current_day not in schedule: await update.message.reply_text("😊 No classes scheduled for today!") return # Find current class found_class = False for period_num, class_info in schedule[current_day]: start_time, end_time = period_times[period_num] if start_time <= current_time <= end_time: await update.message.reply_text(f"🎯 You should be in: {class_info}") found_class = True break if not found_class: await update.message.reply_text("😊 No class right now! Free period.") async def schedule(update: Update, context: ContextTypes.DEFAULT_TYPE): """Show the complete weekly schedule.""" # Reload schedule from DB to ensure latest data schedule = load_schedule_from_db() if not schedule: await update.message.reply_text("❌ Schedule not loaded from database.") return schedule_text = "📚 Weekly Schedule:\n\n" # Define the standard order of days in a week days_of_week = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] for day in days_of_week: if day in schedule and schedule[day]: # Check if the day exists in the schedule and has classes schedule_text += f"*{day}'s Schedule:*\n" for period_num, class_info in schedule[day]: start, end = period_times[period_num] schedule_text += f" ⏰ {start}-{end}: {class_info}\n" schedule_text += "\n" else: schedule_text += f"{day}: No classes scheduled\n\n" await update.message.reply_text(schedule_text) async def tomorrow(update: Update, context: ContextTypes.DEFAULT_TYPE): """Show tomorrow's schedule.""" # Reload schedule from DB to ensure latest data schedule = load_schedule_from_db() if not schedule: await update.message.reply_text("❌ Schedule not loaded from database.") return tomorrow_date = datetime.datetime.now() + datetime.timedelta(days=1) tomorrow_day = tomorrow_date.strftime("%A") if tomorrow_day not in schedule or not schedule[tomorrow_day]: await update.message.reply_text(f"😊 No classes scheduled for {tomorrow_day}!") return schedule_text = f"📚 {tomorrow_day}'s Schedule:\n\n" for period_num, class_info in schedule[tomorrow_day]: start, end = period_times[period_num] schedule_text += f"⏰ {start}-{end}: {class_info}\n" await update.message.reply_text(schedule_text) async def add(update: Update, context: ContextTypes.DEFAULT_TYPE): """Start the process of adding a new schedule entry.""" user_id = update.effective_user.id user_states[user_id] = {"step": "waiting_day"} await update.message.reply_text( "📅 Adding a new class to the schedule.\n" "Please enter the day of the week (e.g., Monday, Tuesday, etc.):" ) async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE): """Handle user messages during the add process.""" user_id = update.effective_user.id if user_id not in user_states: # Not in a conversation, ignore return state_info = user_states[user_id] message_text = update.message.text.strip() if state_info["step"] == "waiting_day": # Validate day input valid_days = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"] if message_text.lower() not in valid_days: await update.message.reply_text( f"'{message_text}' is not a valid day of the week.\n" "Please enter a valid day (e.g., Monday, Tuesday, etc.):" ) return state_info["day"] = message_text.capitalize() state_info["step"] = "waiting_period" await update.message.reply_text( f"Got it! Day: {state_info['day']}\n" "Now please enter the period number (1-13):" ) elif state_info["step"] == "waiting_period": try: period = int(message_text) if period < 1 or period > 13: raise ValueError("Period must be between 1 and 13") state_info["period"] = period state_info["step"] = "waiting_subject" await update.message.reply_text( f"Got it! Period: {period}\n" "Now please enter the subject name:" ) except ValueError: await update.message.reply_text( f"'{message_text}' is not a valid period number.\n" "Please enter a number between 1 and 13:" ) elif state_info["step"] == "waiting_subject": state_info["subject"] = message_text state_info["step"] = "waiting_class" await update.message.reply_text( f"Got it! Subject: {message_text}\n" "Now please enter the class name (e.g., 10ABC, 6A/6B, etc.):" ) elif state_info["step"] == "waiting_class": state_info["class_name"] = message_text state_info["step"] = "waiting_room" await update.message.reply_text( f"Got it! Class: {message_text}\n" "Finally, please enter the room number:" ) elif state_info["step"] == "waiting_room": state_info["room"] = message_text # Add to database success = add_schedule_entry( state_info["day"], state_info["period"], state_info["subject"], state_info["class_name"], message_text ) if success: await update.message.reply_text( f"✅ Successfully added to schedule!\n\n" f"Day: {state_info['day']}\n" f"Period: {state_info['period']}\n" f"Subject: {state_info['subject']}\n" f"Class: {state_info['class_name']}\n" f"Room: {state_info['room']}" ) else: await update.message.reply_text( f"❌ Failed to add to schedule. Please try again." ) # Clean up user state del user_states[user_id] async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE): """Send help message with all commands.""" await update.message.reply_text( "Available commands:\n" "/start - Start the bot\n" "/whereami - Find your current class\n" "/schedule - Show today's full schedule\n" "/tomorrow - Show tomorrow's schedule\n" "/add - Add a new class to the schedule\n" "/help - Show this help message" ) def main(): """Start the bot.""" # Create the Application application = Application.builder().token(BOT_TOKEN).build() # Add command handlers application.add_handler(CommandHandler("start", start)) application.add_handler(CommandHandler("whereami", where_am_i)) application.add_handler(CommandHandler("schedule", schedule)) application.add_handler(CommandHandler("tomorrow", tomorrow)) application.add_handler(CommandHandler("add", add)) application.add_handler(CommandHandler("help", help_command)) # Add message handler for conversation flow application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message)) # Start the Bot print("🤖 Enhanced scheduler bot with database support is running...") print("📊 Database initialized successfully!") print("Press Ctrl+C to stop the bot") application.run_polling() if __name__ == "__main__": main()