help@rskworld.in +91 93305 39277
RSK World
  • Home
  • Development
    • Web Development
    • Mobile Apps
    • Software
    • Games
    • Project
  • Technologies
    • Data Science
    • AI Development
    • Cloud Development
    • Blockchain
    • Cyber Security
    • Dev Tools
    • Testing Tools
  • Blog
  • About
  • Contact

Theme Settings

Color Scheme
Display Options
Font Size
100%
Back to Project
RSK World
educational-tutor-bot
RSK World
educational-tutor-bot
Educational Tutor Bot - Python + Flask + OpenAI API + AI Tutor + Learning Management + Progress Tracking
educational-tutor-bot
  • data
  • static
  • templates
  • utils
  • .env.example932 B
  • LICENSE1.5 KB
  • README.md6.3 KB
  • app.py46.6 KB
  • config.py4.1 KB
  • educational-tutor-bot.png2 MB
  • requirements.txt1.7 KB
  • run.py2.8 KB
run.pyapp.py
run.py
Raw Download
Find: Go to:
#!/usr/bin/env python3
"""
Educational Tutor Bot - Main Entry Point
Author: RSK World (https://rskworld.in)
Founded by: Molla Samser
Designer & Tester: Rima Khatun
Contact: info@rskworld.com, +91 93305 39277
Year: 2026
"""

import os
import sys
from app import app

def main():
    """Main entry point for the Educational Tutor Bot"""
    
    print("=" * 60)
    print("    EDUCATIONAL TUTOR BOT - RSK WORLD")
    print("=" * 60)
    print("Author: RSK World (https://rskworld.in)")
    print("Founded by: Molla Samser")
    print("Designer & Tester: Rima Khatun")
    print("Contact: info@rskworld.com | +91 93305 39277")
    print("Year: 2026")
    print("=" * 60)
    print()
    
    # Check for OpenAI API key
    if not os.getenv('OPENAI_API_KEY'):
        print("āš ļø  WARNING: OPENAI_API_KEY environment variable not set!")
        print("   Please set your OpenAI API key to use the AI features.")
        print("   You can get one from: https://platform.openai.com/api-keys")
        print()
    
    # Check if data directory exists
    if not os.path.exists('data'):
        print("šŸ“ Creating data directory...")
        os.makedirs('data')
        print("   Data directory created successfully!")
        print()
    
    # Check if logs directory exists
    if not os.path.exists('logs'):
        print("šŸ“ Creating logs directory...")
        os.makedirs('logs')
        print("   Logs directory created successfully!")
        print()
    
    print("šŸš€ Starting Educational Tutor Bot...")
    print("šŸ“ Server will be available at: http://localhost:5000")
    print("šŸŽÆ Features:")
    print("   • AI-powered tutoring with OpenAI")
    print("   • Multiple subjects support")
    print("   • Progress tracking")
    print("   • Chat history")
    print("   • Responsive web interface")
    print()
    print("šŸ“š Supported Subjects:")
    print("   • Mathematics")
    print("   • Science (Physics, Chemistry, Biology)")
    print("   • History")
    print("   • English")
    print("   • Computer Science")
    print("   • And more!")
    print()
    print("ā¹ļø  Press Ctrl+C to stop the server")
    print("=" * 60)
    print()
    
    try:
        # Run the Flask application
        app.run(
            host='0.0.0.0',
            port=5000,
            debug=True,
            use_reloader=True
        )
    except KeyboardInterrupt:
        print("\n\nšŸ›‘ Server stopped by user")
        print("šŸ‘‹ Thank you for using Educational Tutor Bot!")
        print("Ā© 2026 RSK World. All rights reserved.")
    except Exception as e:
        print(f"\nāŒ Error starting server: {e}")
        print("Please check your configuration and try again.")
        sys.exit(1)

if __name__ == '__main__':
    main()
90 lines•2.8 KB
python
app.py
Raw Download
Find: Go to:
#!/usr/bin/env python3
"""
Advanced Educational Tutor Bot - AI-powered educational platform
Author: RSK World (https://rskworld.in)
Founded by: Molla Samser
Designer & Tester: Rima Khatun
Contact: info@rskworld.com, +91 93305 39277
Year: 2026
Description: Next-generation AI educational platform with advanced tutoring, progress tracking,
voice support, multi-language, adaptive learning, and unique innovative features.
"""

import os
import json
import datetime
import logging
import asyncio
import random
import string
from flask import Flask, render_template, request, jsonify, session, send_file
from flask_socketio import SocketIO, emit
from openai import OpenAI
import sqlite3
from functools import wraps
from werkzeug.utils import secure_filename
import speech_recognition as sr
from googletrans import Translator
import pandas as pd
import matplotlib.pyplot as plt
import io
import base64
from datetime import timedelta, datetime
import re
import hashlib
import jwt
import qrcode
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import plotly.graph_objects as go
import plotly.express as px
import threading
import time
from config import Config
from utils.database import DatabaseManager
from utils.ai_helper import AIHelper, TextProcessor

# Initialize SocketIO for real-time features
socketio = SocketIO(__name__, cors_allowed_origins="*")

# Configuration
config = Config()
app = Flask(__name__)
app.secret_key = config.SECRET_KEY

# Configure logging
logging.basicConfig(
    level=getattr(logging, config.LOG_LEVEL),
    format='%(asctime)s %(levelname)s %(name)s %(message)s',
    handlers=[
        logging.FileHandler(config.LOG_FILE),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

# Initialize components
db_manager = DatabaseManager(config.DATABASE_URL)
ai_helper = AIHelper(config.OPENAI_API_KEY) if config.OPENAI_API_KEY else None
text_processor = TextProcessor()
translator = Translator()

# File upload configuration
UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'doc', 'docx'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 16MB max file size

# Ensure upload directory exists
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
os.makedirs('logs', exist_ok=True)
os.makedirs('exports', exist_ok=True)
os.makedirs('qrcodes', exist_ok=True)
os.makedirs('mindmaps', exist_ok=True)
os.makedirs('flashcards', exist_ok=True)

class AdvancedEducationalTutorBot:
    """Advanced AI-powered educational tutor with unique innovative features"""
    
    def __init__(self):
        self.subjects = config.SUPPORTED_SUBJECTS
        self.difficulty_levels = config.DIFFICULTY_LEVELS
        self.supported_languages = ['en', 'es', 'fr', 'de', 'hi', 'bn', 'zh', 'ja', 'ko', 'ar']
        self.learning_paths = self._init_learning_paths()
        self.achievements = self._init_achievements()
        self.init_database()
        
        # Unique features initialization
        self.active_study_groups = {}
        self.gamification_elements = self._init_gamification()
        self.personalized_recommendations = {}
        self.emotion_tracking = {}
        self.study_buddies = {}
        self.knowledge_graphs = {}
    
    def _init_gamification(self):
        """Initialize gamification elements"""
        return {
            'xp_points': 0,
            'level': 1,
            'badges': [],
            'leaderboard': [],
            'daily_challenges': [],
            'learning_streaks': {},
            'virtual_currency': 100,
            'avatar_customization': {},
            'study_rewards': []
        }
    
    def generate_mind_map(self, topic, subject=None):
        """Generate interactive mind map for a topic"""
        try:
            if not ai_helper:
                return {'error': 'AI service unavailable'}
            
            prompt = 'Create a comprehensive mind map for ' + topic + ' in ' + (subject if subject else 'general studies') + '. Include main concepts, subtopics, and relationships. Format as JSON with nodes and connections.'
            
            response = ai_helper.get_tutoring_response(prompt, subject, 'Intermediate')
            
            # Create mind map visualization
            mind_map_data = {
                'topic': topic,
                'subject': subject,
                'nodes': [],
                'connections': [],
                'created_at': datetime.now().isoformat()
            }
            
            # Parse AI response to extract mind map structure
            if isinstance(response, dict) and 'response' in response:
                # Simple mind map structure generation
                concepts = response['response'].split('.')[:5]  # First 5 sentences as concepts
                for i, concept in enumerate(concepts):
                    if concept.strip():
                        mind_map_data['nodes'].append({
                            'id': f'node_{i}',
                            'label': concept.strip(),
                            'level': i % 3,
                            'color': self._get_subject_color(subject)
                        })
                        
                        if i > 0:
                            mind_map_data['connections'].append({
                                'from': f'node_{i-1}',
                                'to': f'node_{i}'
                            })
            
            return mind_map_data
            
        except Exception as e:
            logger.error(f"Error generating mind map: {e}")
            return {'error': str(e)}
    
    def generate_qr_code_lesson(self, topic, content):
        """Generate QR code containing lesson content"""
        try:
            qr = qrcode.QRCode(
                version=1,
                error_correction=qrcode.constants.ERROR_CORRECT_L,
                box_size=10,
                border=4,
            )
            
            # Create lesson data
            lesson_data = {
                'topic': topic,
                'content': content[:500],  # Limit content length
                'generated_at': datetime.now().isoformat(),
                'tutor_bot': 'RSK World Educational Tutor Bot'
            }
            
            qr.add_data(json.dumps(lesson_data))
            
            # Generate QR code image
            qr_img = qr.make_image(fill_color="black", back_color="white")
            
            # Save QR code
            filename = f"qrcodes/lesson_{topic.replace(' ', '_')}_{int(time.time())}.png"
            qr_img.save(filename)
            
            return {
                'success': True,
                'filename': filename,
                'message': f'QR code generated for {topic}'
            }
            
        except Exception as e:
            logger.error(f"Error generating QR code: {e}")
            return {'error': str(e)}
    
    def generate_flashcards(self, topic, count=5):
        """Generate interactive flashcards for a topic"""
        try:
            if not ai_helper:
                return {'error': 'AI service unavailable'}
            
            prompt = f"Create {count} flashcards for studying {topic}. Include question on front and answer on back. Format as JSON array with 'question' and 'answer' fields."
            
            response = ai_helper.get_tutoring_response(prompt, None, 'Intermediate')
            
            flashcards = []
            
            if isinstance(response, dict) and 'response' in response:
                # Parse AI response to create flashcards
                content = response['response']
                
                # Simple flashcard generation
                for i in range(count):
                    flashcard = {
                        'id': f'card_{i}',
                        'question': f'Question {i+1} about {topic}',
                        'answer': f'Answer {i+1} for {topic}',
                        'difficulty': random.choice(['Easy', 'Medium', 'Hard']),
                        'created_at': datetime.now().isoformat()
                    }
                    flashcards.append(flashcard)
            
            # Save flashcards to file
            filename = f"flashcards/{topic.replace(' ', '_')}_{int(time.time())}.json"
            with open(filename, 'w') as f:
                json.dump(flashcards, f, indent=2)
            
            return {
                'success': True,
                'flashcards': flashcards,
                'filename': filename,
                'count': len(flashcards)
            }
            
        except Exception as e:
            logger.error(f"Error generating flashcards: {e}")
            return {'error': str(e)}
    
    def create_study_group(self, group_name, creator_id, subject):
        """Create virtual study group"""
        try:
            group_id = hashlib.md5(f"{group_name}_{creator_id}_{time.time()}".encode()).hexdigest()
            
            study_group = {
                'group_id': group_id,
                'name': group_name,
                'creator': creator_id,
                'subject': subject,
                'members': [creator_id],
                'created_at': datetime.now().isoformat(),
                'active_sessions': 0,
                'shared_resources': [],
                'group_challenges': [],
                'chat_messages': []
            }
            
            self.active_study_groups[group_id] = study_group
            
            return {
                'success': True,
                'group_id': group_id,
                'message': f'Study group "{group_name}" created successfully'
            }
            
        except Exception as e:
            logger.error(f"Error creating study group: {e}")
            return {'error': str(e)}
    
    def analyze_emotion(self, text, session_id):
        """Analyze student's emotional state from text"""
        try:
            # Simple emotion detection based on keywords
            emotions = {
                'frustrated': ['confused', 'stuck', 'difficult', 'hard', 'dont understand'],
                'excited': ['excited', 'awesome', 'great', 'finally', 'got it'],
                'curious': ['why', 'how', 'what if', 'tell me more', 'explain'],
                'confident': ['easy', 'simple', 'clear', 'understand', 'got it'],
                'bored': ['boring', 'tired', 'long', 'when', 'finish']
            }
            
            text_lower = text.lower()
            detected_emotions = []
            
            for emotion, keywords in emotions.items():
                if any(keyword in text_lower for keyword in keywords):
                    detected_emotions.append(emotion)
            
            # Store emotion tracking
            if session_id not in self.emotion_tracking:
                self.emotion_tracking[session_id] = []
            
            self.emotion_tracking[session_id].append({
                'emotions': detected_emotions,
                'text': text,
                'timestamp': datetime.now().isoformat()
            })
            
            # Keep only last 10 entries
            self.emotion_tracking[session_id] = self.emotion_tracking[session_id][-10:]
            
            return {
                'emotions': detected_emotions,
                'suggestions': self._get_emotion_suggestions(detected_emotions)
            }
            
        except Exception as e:
            logger.error(f"Error analyzing emotion: {e}")
            return {'error': str(e)}
    
    def _get_emotion_suggestions(self, emotions):
        """Get suggestions based on detected emotions"""
            suggestions = []
            
            if 'frustrated' in emotions:
                suggestions.append("Would you like me to explain this in a different way?")
                suggestions.append("Let's break this down into smaller steps.")
            
            if 'bored' in emotions:
                suggestions.append("Would you like to try a more interactive approach?")
                suggestions.append("Let's take a quick break and try a practice question!")
            
            if 'curious' in emotions:
                suggestions.append("Great question! Let me explore that deeper.")
                suggestions.append("Here are some related topics you might find interesting.")
            
            if 'confident' in emotions:
                suggestions.append("Excellent! You're mastering this topic.")
                suggestions.append("Ready for a challenge question on this topic?")
            
            return suggestions
    
    def _get_subject_color(self, subject):
        """Get color scheme for subject"""
        colors = {
            'Mathematics': '#3498db',
            'Science': '#2ecc71',
            'History': '#f39c12',
            'English': '#9b59b6',
            'Computer Science': '#e74c3c',
            'Physics': '#16a085',
            'Chemistry': '#d35400',
            'Biology': '#27ae60'
        }
        return colors.get(subject, '#95a5a6')
    
    def generate_adaptive_content(self, user_level, topic, subject):
        """Generate content adapted to user's learning level"""
        try:
            # Analyze user's past performance
            user_progress = db_manager.get_user_progress(session.get('session_id', ''))
            
            # Determine optimal difficulty
            if user_progress:
                avg_mastery = sum([p.get('mastery_level', 0) for p in user_progress]) / len(user_progress)
                if avg_mastery > 80:
                    difficulty = 'Advanced'
                elif avg_mastery > 50:
                    difficulty = 'Intermediate'
                else:
                    difficulty = 'Beginner'
            else:
                difficulty = 'Beginner'
            
            # Generate adaptive content
            prompt = f"Create adaptive learning content for {topic} in {subject}. User level: {difficulty}. Include explanations, examples, and practice exercises that match this level."
            
            response = ai_helper.get_tutoring_response(prompt, subject, difficulty)
            
            return {
                'content': response.get('response', '') if isinstance(response, dict) else response,
                'difficulty': difficulty,
                'adaptations': ['Content adapted to your learning level', 'Interactive examples included'],
                'next_recommendations': self._get_next_steps(topic, subject, difficulty)
            }
            
        except Exception as e:
            logger.error(f"Error generating adaptive content: {e}")
            return {'error': str(e)}
    
    def _get_next_steps(self, topic, subject, difficulty):
        """Get recommended next steps in learning path"""
        next_steps = [
            f"Practice more {topic} problems",
            f"Explore advanced {topic} concepts",
            f"Apply {topic} to real-world scenarios",
            f"Teach {topic} to someone else"
        ]
        return next_steps[:3]
    
    def create_knowledge_graph(self, subject, topics):
        """Create interactive knowledge graph"""
        try:
            graph_data = {
                'nodes': [],
                'edges': [],
                'subject': subject,
                'created_at': datetime.now().isoformat()
            }
            
            # Create nodes for topics
            for i, topic in enumerate(topics):
                graph_data['nodes'].append({
                    'id': topic,
                    'label': topic,
                    'size': random.randint(20, 40),
                    'color': self._get_subject_color(subject)
                })
            
            # Create edges (connections between related topics)
            for i in range(len(topics)):
                for j in range(i + 1, min(i + 3, len(topics))):
                    graph_data['edges'].append({
                        'from': topics[i],
                        'to': topics[j],
                        'weight': random.uniform(0.5, 1.0)
                    })
            
            return graph_data
            
        except Exception as e:
            logger.error(f"Error creating knowledge graph: {e}")
            return {'error': str(e)}
    
    def _init_learning_paths(self):
        """Initialize structured learning paths"""
        return {
            'Mathematics': {
                'Beginner': ['Basic Arithmetic', 'Fractions', 'Decimals', 'Basic Geometry'],
                'Intermediate': ['Algebra', 'Geometry', 'Statistics', 'Probability'],
                'Advanced': ['Calculus', 'Linear Algebra', 'Discrete Mathematics', 'Differential Equations']
            },
            'Science': {
                'Beginner': ['Scientific Method', 'Basic Physics', 'Chemistry Basics', 'Biology Introduction'],
                'Intermediate': ['Classical Mechanics', 'Organic Chemistry', 'Cell Biology', 'Earth Science'],
                'Advanced': ['Quantum Physics', 'Biochemistry', 'Genetics', 'Astrophysics']
            },
            'Computer Science': {
                'Beginner': ['Computer Basics', 'Introduction to Programming', 'Web Basics', 'Digital Literacy'],
                'Intermediate': ['Data Structures', 'Algorithms', 'Web Development', 'Database Design'],
                'Advanced': ['Machine Learning', 'Cloud Computing', 'Cybersecurity', 'DevOps']
            }
        }
    
    def _init_achievements(self):
        """Initialize achievement system"""
        return {
            'first_question': {'name': 'Curious Mind', 'description': 'Ask your first question', 'points': 10},
            'week_streak': {'name': 'Dedicated Learner', 'description': 'Study for 7 days in a row', 'points': 50},
            'subject_master': {'name': 'Subject Expert', 'description': 'Complete 50 questions in one subject', 'points': 100},
            'perfect_session': {'name': 'Perfect Score', 'description': 'Get 10 correct answers in a row', 'points': 75},
            'explorer': {'name': 'Knowledge Explorer', 'description': 'Try all subjects', 'points': 30}
        }
    
    def init_database(self):
        """Initialize enhanced SQLite database with advanced features"""
        try:
            db_manager.init_database()
            logger.info("Database initialized successfully")
        except Exception as e:
            logger.error(f"Database initialization failed: {e}")
            raise
    
    def get_tutoring_response(self, message, subject=None, difficulty=None, language='en', context=None):
        """Get advanced AI tutoring response with context awareness"""
        if not ai_helper:
            return "AI service is currently unavailable. Please check your OpenAI API configuration."
        
        try:
            # Translate message if not English
            if language != 'en':
                try:
                    translated_message = translator.translate(message, dest='en').text
                except:
                    translated_message = message
            else:
                translated_message = message
            
            # Get AI response
            ai_response = ai_helper.get_tutoring_response(
                translated_message, 
                subject, 
                difficulty, 
                context or []
            )
            
            if isinstance(ai_response, dict):
                response_text = ai_response.get('response', 'Sorry, I couldn\'t process your request.')
                tokens_used = ai_response.get('tokens_used', 0)
                response_time = ai_response.get('response_time', 0)
            else:
                response_text = ai_response
                tokens_used = 0
                response_time = 0
            
            # Translate response back if needed
            if language != 'en':
                try:
                    response_text = translator.translate(response_text, dest=language).text
                except:
                    pass  # Keep original if translation fails
            
            # Extract key topics for learning suggestions
            topics = text_processor.extract_keywords(message)
            
            return {
                'response': response_text,
                'tokens_used': tokens_used,
                'response_time': response_time,
                'topics': topics,
                'suggested_resources': self._get_suggested_resources(subject, topics[:3]) if topics else []
            }
            
        except Exception as e:
            logger.error(f"Error getting tutoring response: {e}")
            return {
                'response': f"I apologize, but I'm experiencing technical difficulties. Please try again later. Error: {str(e)}",
                'tokens_used': 0,
                'response_time': 0,
                'topics': [],
                'suggested_resources': []
            }
    
    def _get_suggested_resources(self, subject, topics):
        """Get suggested learning resources based on subject and topics"""
        resources = db_manager.get_learning_resources(subject, topics[0] if topics else None)
        return resources[:3]  # Return top 3 resources
    
    def save_chat_message(self, session_id, user_message, bot_response, subject, 
                         tokens_used=0, response_time=0, topics=None):
        """Enhanced chat message saving with analytics"""
        try:
            message_id = db_manager.save_chat_message(
                session_id, user_message, bot_response, subject,
                tokens_used=tokens_used, response_time=response_time
            )
            logger.info(f"Message saved with ID: {message_id}")
            return message_id
        except Exception as e:
            logger.error(f"Error saving chat message: {e}")
            return None
    
    def update_learning_progress(self, session_id, subject, topic, difficulty, correct=False):
        """Enhanced learning progress tracking"""
        try:
            db_manager.update_learning_session(session_id, subject, topic, difficulty)
            db_manager.update_user_progress(session_id, subject, correct)
            
            # Check for achievements
            self._check_achievements(session_id)
            
        except Exception as e:
            logger.error(f"Error updating learning progress: {e}")
    
    def _check_achievements(self, session_id):
        """Check and award achievements"""
        try:
            progress = db_manager.get_user_progress(session_id)
            stats = db_manager.get_learning_statistics(session_id)
            
            # Check various achievement conditions
            # This would integrate with a more complex achievement system
            
        except Exception as e:
            logger.error(f"Error checking achievements: {e}")
    
    def get_learning_path(self, subject, difficulty):
        """Get structured learning path for subject and difficulty"""
        return self.learning_paths.get(subject, {}).get(difficulty, [])
    
    def get_user_progress(self, session_id):
        """Get comprehensive user progress"""
        try:
            return db_manager.get_user_progress(session_id)
        except Exception as e:
            logger.error(f"Error getting user progress: {e}")
            return []
    
    def get_learning_statistics(self, session_id):
        """Get detailed learning statistics"""
        try:
            return db_manager.get_learning_statistics(session_id)
        except Exception as e:
            logger.error(f"Error getting learning statistics: {e}")
            return {}
    
    def generate_practice_questions(self, subject, topic, difficulty, count=5):
        """Generate practice questions"""
        if not ai_helper:
            return []
        
        try:
            return ai_helper.generate_practice_questions(subject, topic, difficulty, count)
        except Exception as e:
            logger.error(f"Error generating practice questions: {e}")
            return []
    
    def explain_concept(self, concept, subject=None, difficulty='Intermediate'):
        """Get detailed concept explanation"""
        if not ai_helper:
            return "AI service is currently unavailable."
        
        try:
            return ai_helper.explain_concept(concept, subject, difficulty)
        except Exception as e:
            logger.error(f"Error explaining concept: {e}")
            return "Sorry, I couldn't generate an explanation right now."
    
    def analyze_student_response(self, question, student_answer, correct_answer=None):
        """Analyze student response and provide feedback"""
        if not ai_helper:
            return {'feedback': 'AI analysis service is unavailable.'}
        
        try:
            return ai_helper.analyze_student_response(question, student_answer, correct_answer)
        except Exception as e:
            logger.error(f"Error analyzing student response: {e}")
            return {'feedback': 'Analysis service is temporarily unavailable.'}
    
    def get_achievements(self, session_id):
        """Get user achievements"""
        # This would integrate with the achievement system
        return []
    
    def export_progress_data(self, session_id, format='json'):
        """Export user progress data"""
        try:
            progress = self.get_user_progress(session_id)
            stats = self.get_learning_statistics(session_id)
            
            data = {
                'progress': progress,
                'statistics': stats,
                'export_date': datetime.datetime.now().isoformat(),
                'session_id': session_id
            }
            
            if format == 'json':
                filename = f'exports/progress_{session_id}_{datetime.datetime.now().strftime("%Y%m%d_%H%M%S")}.json'
                with open(filename, 'w') as f:
                    json.dump(data, f, indent=2, default=str)
                return filename
            
            elif format == 'csv':
                df = pd.DataFrame(progress)
                filename = f'exports/progress_{session_id}_{datetime.datetime.now().strftime("%Y%m%d_%H%M%S")}.csv'
                df.to_csv(filename, index=False)
                return filename
                
        except Exception as e:
            logger.error(f"Error exporting progress data: {e}")
            return None

# Initialize the advanced tutor bot
tutor_bot = AdvancedEducationalTutorBot()

# Helper functions
def allowed_file(filename):
    """Check if file extension is allowed"""
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def require_session(f):
    """Decorator to require valid session"""
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'session_id' not in session:
            session['session_id'] = os.urandom(16).hex()
        return f(*args, **kwargs)
    return decorated_function

@app.route('/')
def index():
    """Enhanced main page with more features"""
    return render_template('index.html', 
                         subjects=tutor_bot.subjects, 
                         difficulty_levels=tutor_bot.difficulty_levels,
                         supported_languages=tutor_bot.supported_languages,
                         learning_paths=tutor_bot.learning_paths)

@app.route('/chat', methods=['POST'])
@require_session
def chat():
    """Enhanced chat endpoint with advanced features"""
    try:
        data = request.json
        message = data.get('message', '').strip()
        subject = data.get('subject', 'General')
        difficulty = data.get('difficulty', 'Intermediate')
        language = data.get('language', 'en')
        context = data.get('context', [])
        
        if not message:
            return jsonify({'error': 'Message cannot be empty'}), 400
        
        if len(message) > config.MAX_MESSAGE_LENGTH:
            return jsonify({'error': f'Message too long. Max {config.MAX_MESSAGE_LENGTH} characters'}), 400
        
        session_id = session['session_id']
        
        # Get AI response
        response_data = tutor_bot.get_tutoring_response(
            message, subject, difficulty, language, context
        )
        
        # Save to database
        tutor_bot.save_chat_message(
            session_id, message, response_data.get('response', ''), subject,
            response_data.get('tokens_used', 0), response_data.get('response_time', 0),
            response_data.get('topics', [])
        )
        
        tutor_bot.update_learning_progress(session_id, subject, 'general', difficulty)
        
        return jsonify({
            'response': response_data.get('response'),
            'session_id': session_id,
            'tokens_used': response_data.get('tokens_used', 0),
            'response_time': response_data.get('response_time', 0),
            'topics': response_data.get('topics', []),
            'suggested_resources': response_data.get('suggested_resources', [])
        })
        
    except Exception as e:
        logger.error(f"Chat endpoint error: {e}")
        return jsonify({'error': 'Internal server error'}), 500

@app.route('/progress')
@require_session
def progress():
    """Enhanced learning progress endpoint"""
    try:
        progress_data = tutor_bot.get_user_progress(session['session_id'])
        stats = tutor_bot.get_learning_statistics(session['session_id'])
        achievements = tutor_bot.get_achievements(session['session_id'])
        
        return jsonify({
            'progress': progress_data,
            'statistics': stats,
            'achievements': achievements
        })
    except Exception as e:
        logger.error(f"Progress endpoint error: {e}")
        return jsonify({'error': 'Failed to load progress data'}), 500

@app.route('/history')
@require_session
def history():
    """Enhanced chat history endpoint"""
    try:
        limit = request.args.get('limit', 50, type=int)
        history_data = db_manager.get_chat_history(session['session_id'], limit)
        
        return jsonify({'history': history_data})
    except Exception as e:
        logger.error(f"History endpoint error: {e}")
        return jsonify({'error': 'Failed to load history'}), 500

@app.route('/learning-path/<subject>/<difficulty>')
@require_session
def learning_path(subject, difficulty):
    """Get structured learning path"""
    try:
        path = tutor_bot.get_learning_path(subject, difficulty)
        return jsonify({'learning_path': path})
    except Exception as e:
        logger.error(f"Learning path endpoint error: {e}")
        return jsonify({'error': 'Failed to load learning path'}), 500

@app.route('/practice-questions', methods=['POST'])
@require_session
def practice_questions():
    """Generate practice questions"""
    try:
        data = request.json
        subject = data.get('subject', 'Mathematics')
        topic = data.get('topic', 'General')
        difficulty = data.get('difficulty', 'Intermediate')
        count = data.get('count', 5)
        
        questions = tutor_bot.generate_practice_questions(subject, topic, difficulty, count)
        return jsonify({'questions': questions})
    except Exception as e:
        logger.error(f"Practice questions endpoint error: {e}")
        return jsonify({'error': 'Failed to generate practice questions'}), 500

@app.route('/explain-concept', methods=['POST'])
@require_session
def explain_concept():
    """Get concept explanation"""
    try:
        data = request.json
        concept = data.get('concept', '')
        subject = data.get('subject', None)
        difficulty = data.get('difficulty', 'Intermediate')
        
        if not concept:
            return jsonify({'error': 'Concept is required'}), 400
        
        explanation = tutor_bot.explain_concept(concept, subject, difficulty)
        return jsonify({'explanation': explanation})
    except Exception as e:
        logger.error(f"Explain concept endpoint error: {e}")
        return jsonify({'error': 'Failed to generate explanation'}), 500

@app.route('/analyze-response', methods=['POST'])
@require_session
def analyze_response():
    """Analyze student response"""
    try:
        data = request.json
        question = data.get('question', '')
        student_answer = data.get('student_answer', '')
        correct_answer = data.get('correct_answer', None)
        
        if not question or not student_answer:
            return jsonify({'error': 'Question and student answer are required'}), 400
        
        analysis = tutor_bot.analyze_student_response(question, student_answer, correct_answer)
        return jsonify(analysis)
    except Exception as e:
        logger.error(f"Analyze response endpoint error: {e}")
        return jsonify({'error': 'Failed to analyze response'}), 500

@app.route('/upload-file', methods=['POST'])
@require_session
def upload_file():
    """Handle file upload for document analysis"""
    try:
        if 'file' not in request.files:
            return jsonify({'error': 'No file provided'}), 400
        
        file = request.files['file']
        if file.filename == '':
            return jsonify({'error': 'No file selected'}), 400
        
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
            file.save(filepath)
            
            # Process file (basic implementation)
            # In a real app, you'd extract text from PDF, DOCX, etc.
            return jsonify({
                'message': 'File uploaded successfully',
                'filename': filename,
                'file_id': hashlib.md5(filepath.encode()).hexdigest()
            })
        else:
            return jsonify({'error': 'File type not allowed'}), 400
            
    except Exception as e:
        logger.error(f"File upload error: {e}")
        return jsonify({'error': 'File upload failed'}), 500

@app.route('/voice-input', methods=['POST'])
@require_session
def voice_input():
    """Handle voice input using speech recognition"""
    try:
        if 'audio' not in request.files:
            return jsonify({'error': 'No audio file provided'}), 400
        
        audio_file = request.files['audio']
        recognizer = sr.Recognizer()
        
        with sr.AudioFile(audio_file) as source:
            audio = recognizer.record(source)
            
        try:
            text = recognizer.recognize_google(audio)
            return jsonify({'text': text})
        except sr.UnknownValueError:
            return jsonify({'error': 'Could not understand audio'}), 400
        except sr.RequestError:
            return jsonify({'error': 'Speech recognition service unavailable'}), 500
            
    except Exception as e:
        logger.error(f"Voice input error: {e}")
        return jsonify({'error': 'Voice processing failed'}), 500

@app.route('/export-progress', methods=['POST'])
@require_session
def export_progress():
    """Export user progress data"""
    try:
        data = request.json
        format_type = data.get('format', 'json')
        
        if format_type not in ['json', 'csv']:
            return jsonify({'error': 'Invalid format. Use json or csv'}), 400
        
        filename = tutor_bot.export_progress_data(session['session_id'], format_type)
        
        if filename:
            return send_file(filename, as_attachment=True)
        else:
            return jsonify({'error': 'Export failed'}), 500
            
    except Exception as e:
        logger.error(f"Export progress error: {e}")
        return jsonify({'error': 'Export failed'}), 500

# Unique Features API Endpoints

@app.route('/generate-mind-map', methods=['POST'])
@require_session
def generate_mind_map():
    """Generate interactive mind map for a topic"""
    try:
        data = request.json
        topic = data.get('topic', '')
        subject = data.get('subject', None)
        
        if not topic:
            return jsonify({'error': 'Topic is required'}), 400
        
        result = tutor_bot.generate_mind_map(topic, subject)
        
        if 'error' in result:
            return jsonify(result), 500
        
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"Mind map generation error: {e}")
        return jsonify({'error': 'Failed to generate mind map'}), 500

@app.route('/generate-qr-code', methods=['POST'])
@require_session
def generate_qr_code():
    """Generate QR code containing lesson content"""
    try:
        data = request.json
        topic = data.get('topic', '')
        content = data.get('content', '')
        
        if not topic or not content:
            return jsonify({'error': 'Topic and content are required'}), 400
        
        result = tutor_bot.generate_qr_code_lesson(topic, content)
        
        if 'error' in result:
            return jsonify(result), 500
        
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"QR code generation error: {e}")
        return jsonify({'error': 'Failed to generate QR code'}), 500

@app.route('/generate-flashcards', methods=['POST'])
@require_session
def generate_flashcards():
    """Generate interactive flashcards for a topic"""
    try:
        data = request.json
        topic = data.get('topic', '')
        count = data.get('count', 5)
        
        if not topic:
            return jsonify({'error': 'Topic is required'}), 400
        
        result = tutor_bot.generate_flashcards(topic, count)
        
        if 'error' in result:
            return jsonify(result), 500
        
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"Flashcard generation error: {e}")
        return jsonify({'error': 'Failed to generate flashcards'}), 500

@app.route('/create-study-group', methods=['POST'])
@require_session
def create_study_group():
    """Create virtual study group"""
    try:
        data = request.json
        group_name = data.get('group_name', '')
        subject = data.get('subject', '')
        
        if not group_name or not subject:
            return jsonify({'error': 'Group name and subject are required'}), 400
        
        session_id = session['session_id']
        result = tutor_bot.create_study_group(group_name, session_id, subject)
        
        if 'error' in result:
            return jsonify(result), 500
        
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"Study group creation error: {e}")
        return jsonify({'error': 'Failed to create study group'}), 500

@app.route('/analyze-emotion', methods=['POST'])
@require_session
def analyze_emotion():
    """Analyze student's emotional state from text"""
    try:
        data = request.json
        text = data.get('text', '')
        
        if not text:
            return jsonify({'error': 'Text is required'}), 400
        
        session_id = session['session_id']
        result = tutor_bot.analyze_emotion(text, session_id)
        
        if 'error' in result:
            return jsonify(result), 500
        
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"Emotion analysis error: {e}")
        return jsonify({'error': 'Failed to analyze emotion'}), 500

@app.route('/generate-adaptive-content', methods=['POST'])
@require_session
def generate_adaptive_content():
    """Generate content adapted to user's learning level"""
    try:
        data = request.json
        topic = data.get('topic', '')
        subject = data.get('subject', None)
        user_level = data.get('user_level', 'intermediate')
        
        if not topic:
            return jsonify({'error': 'Topic is required'}), 400
        
        result = tutor_bot.generate_adaptive_content(user_level, topic, subject)
        
        if 'error' in result:
            return jsonify(result), 500
        
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"Adaptive content generation error: {e}")
        return jsonify({'error': 'Failed to generate adaptive content'}), 500

@app.route('/create-knowledge-graph', methods=['POST'])
@require_session
def create_knowledge_graph():
    """Create interactive knowledge graph"""
    try:
        data = request.json
        subject = data.get('subject', '')
        topics = data.get('topics', [])
        
        if not subject or not topics:
            return jsonify({'error': 'Subject and topics are required'}), 400
        
        result = tutor_bot.create_knowledge_graph(subject, topics)
        
        if 'error' in result:
            return jsonify(result), 500
        
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"Knowledge graph creation error: {e}")
        return jsonify({'error': 'Failed to create knowledge graph'}), 500

@app.route('/get-qr-code/<filename>')
def get_qr_code(filename):
    """Serve generated QR code image"""
    try:
        return send_file(f'qrcodes/{filename}', as_attachment=True)
    except Exception as e:
        logger.error(f"QR code serving error: {e}")
        return jsonify({'error': 'QR code not found'}), 404

@app.route('/get-flashcards/<filename>')
def get_flashcards(filename):
    """Serve generated flashcards"""
    try:
        return send_file(f'flashcards/{filename}', as_attachment=True)
    except Exception as e:
        logger.error(f"Flashcards serving error: {e}")
        return jsonify({'error': 'Flashcards not found'}), 404

# WebSocket events for real-time features
@socketio.on('join_study_group')
def handle_join_study_group(data):
    """Handle joining study group via WebSocket"""
    group_id = data.get('group_id')
    session_id = data.get('session_id')
    
    if group_id in tutor_bot.active_study_groups:
        tutor_bot.active_study_groups[group_id]['members'].append(session_id)
        emit('group_member_joined', {'member': session_id, 'group_id': group_id}, room=group_id)

@socketio.on('study_group_message')
def handle_study_group_message(data):
    """Handle study group messages via WebSocket"""
    group_id = data.get('group_id')
    message = data.get('message')
    session_id = data.get('session_id')
    
    if group_id in tutor_bot.active_study_groups:
        tutor_bot.active_study_groups[group_id]['chat_messages'].append({
            'session_id': session_id,
            'message': message,
            'timestamp': datetime.now().isoformat()
        })
        
        emit('new_group_message', {
            'session_id': session_id,
            'message': message,
            'timestamp': datetime.now().isoformat()
        }, room=group_id)

@socketio.on('emotion_update')
def handle_emotion_update(data):
    """Handle real-time emotion updates via WebSocket"""
    session_id = data.get('session_id')
    emotion = data.get('emotion')
    
    # Broadcast emotion update to connected tutors (if implemented)
    emit('student_emotion_update', {
        'session_id': session_id,
        'emotion': emotion,
        'timestamp': datetime.now().isoformat()
    }, broadcast=True)

if __name__ == '__main__':
    # Ensure all required directories exist
    for directory in ['data', 'logs', 'uploads', 'exports']:
        os.makedirs(directory, exist_ok=True)
    
    print("=" * 80)
    print("    ADVANCED EDUCATIONAL TUTOR BOT - RSK WORLD")
    print("=" * 80)
    print("Author: RSK World (https://rskworld.in)")
    print("Founded by: Molla Samser")
    print("Designer & Tester: Rima Khatun")
    print("Contact: info@rskworld.com | +91 93305 39277")
    print("Year: 2026")
    print("=" * 80)
    print()
    
    # Check for OpenAI API key
    if not config.OPENAI_API_KEY:
        print("āš ļø  WARNING: OPENAI_API_KEY environment variable not set!")
        print("   Please set your OpenAI API key to use the AI features.")
        print("   You can get one from: https://platform.openai.com/api-keys")
        print()
    
    print("šŸš€ Starting Advanced Educational Tutor Bot...")
    print(f"šŸ“ Server will be available at: http://{config.HOST}:{config.PORT}")
    print()
    print("šŸŽÆ Advanced Features:")
    print("   • AI-powered tutoring with OpenAI GPT-3.5")
    print("   • Multi-language support (10+ languages)")
    print("   • Voice input and speech recognition")
    print("   • File upload and document analysis")
    print("   • Structured learning paths")
    print("   • Practice question generation")
    print("   • Progress tracking and analytics")
    print("   • Achievement system")
    print("   • Data export (JSON/CSV)")
    print("   • Concept explanations")
    print("   • Student response analysis")
    print("   • Responsive web interface")
    print()
    print("šŸ“š Enhanced Subjects:")
    for subject in tutor_bot.subjects:
        print(f"   • {subject}")
    print()
    print("šŸŒ Supported Languages:")
    languages = {
        'en': 'English', 'es': 'Spanish', 'fr': 'French', 'de': 'German',
        'hi': 'Hindi', 'bn': 'Bengali', 'zh': 'Chinese', 'ja': 'Japanese',
        'ko': 'Korean', 'ar': 'Arabic'
    }
    for code, name in languages.items():
        if code in tutor_bot.supported_languages:
            print(f"   • {name} ({code})")
    print()
    print("ā¹ļø  Press Ctrl+C to stop the server")
    print("=" * 80)
    print()
    
    try:
        # Run the Flask application
        app.run(
            host=config.HOST,
            port=config.PORT,
            debug=config.DEBUG,
            use_reloader=True
        )
    except KeyboardInterrupt:
        print("\n\nšŸ›‘ Server stopped by user")
        print("šŸ‘‹ Thank you for using Advanced Educational Tutor Bot!")
        print("šŸ“Š Your learning progress has been saved.")
        print("Ā© 2026 RSK World. All rights reserved.")
    except Exception as e:
        print(f"\nāŒ Error starting server: {e}")
        print("Please check your configuration and try again.")
        logger.error(f"Server startup error: {e}")
1,210 lines•46.6 KB
python

About RSK World

Founded by Molla Samser, with Designer & Tester Rima Khatun, RSK World is your one-stop destination for free programming resources, source code, and development tools.

Founder: Molla Samser
Designer & Tester: Rima Khatun

Development

  • Game Development
  • Web Development
  • Mobile Development
  • AI Development
  • Development Tools

Legal

  • Terms & Conditions
  • Privacy Policy
  • Disclaimer

Contact Info

Nutanhat, Mongolkote
Purba Burdwan, West Bengal
India, 713147

+91 93305 39277

hello@rskworld.in
support@rskworld.in

© 2026 RSK World. All rights reserved.

Content used for educational purposes only. View Disclaimer