This commit is contained in:
2026-02-05 10:15:09 +03:00
parent 2427fce842
commit 67241a5ed0
33 changed files with 13147 additions and 154 deletions

View File

@@ -0,0 +1,344 @@
#!/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()