# config.py import os from dotenv import load_dotenv load_dotenv() class Config: DEBUG = os.getenv('DEBUG', 'False').lower() == 'true' LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO') MODELS_CACHE_DIR = os.getenv('MODELS_CACHE_DIR', './models') HISTORY_FILE = os.getenv('HISTORY_FILE', 'learning_path_history.json') MAX_AUDIO_LENGTH = int(os.getenv('MAX_AUDIO_LENGTH', '600')) # seconds MAX_TEXT_LENGTH = int(os.getenv('MAX_TEXT_LENGTH', '1000')) SUPPORTED_AUDIO_FORMATS = ['.wav', '.mp3', '.ogg', '.flac'] # Visualization settings MAX_TOPICS = int(os.getenv('MAX_TOPICS', '10')) MAX_SUBTOPICS = int(os.getenv('MAX_SUBTOPICS', '5')) FIGURE_DPI = int(os.getenv('FIGURE_DPI', '300')) # Model settings MODEL_TRANSCRIBER = os.getenv('MODEL_TRANSCRIBER', 'openai/whisper-base') MODEL_GENERATOR = os.getenv('MODEL_GENERATOR', 'gpt2') # Retry settings MAX_RETRIES = int(os.getenv('MAX_RETRIES', '3')) RETRY_DELAY = int(os.getenv('RETRY_DELAY', '1')) # utils.py import logging import json from typing import Dict, Any, Optional, List, Tuple import os from datetime import datetime from config import Config class Utils: @staticmethod def setup_logging() -> logging.Logger: logger = logging.getLogger("LearningPathGenerator") level = getattr(logging, Config.LOG_LEVEL) logger.setLevel(level) handler = logging.FileHandler("app.log") formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) handler.setFormatter(formatter) logger.addHandler(handler) return logger @staticmethod def save_json(data: Dict[str, Any], filename: str) -> bool: try: with open(filename, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) return True except Exception as e: logging.error(f"Error saving JSON: {str(e)}") return False @staticmethod def load_json(filename: str) -> Optional[Dict[str, Any]]: try: with open(filename, 'r', encoding='utf-8') as f: return json.load(f) except Exception as e: logging.error(f"Error loading JSON: {str(e)}") return None @staticmethod def extract_topics(analysis: str) -> Tuple[List[str], Dict[str, List[str]]]: # Simple topic extraction logic - could be enhanced topics = ["Main Topic", "Subtopic 1", "Subtopic 2"] subtopics = { "Main Topic": ["Detail 1", "Detail 2"], "Subtopic 1": ["Point 1", "Point 2"], "Subtopic 2": ["Item 1", "Item 2"] } return topics, subtopics # models.py from transformers import pipeline import torch from typing import Dict, Any import logging from config import Config class ModelManager: def __init__(self): self.logger = logging.getLogger("ModelManager") self.models: Dict[str, Any] = {} self._initialize_models() def _initialize_models(self): try: device = 0 if torch.cuda.is_available() else -1 self.models["transcriber"] = pipeline( "automatic-speech-recognition", model=Config.MODEL_TRANSCRIBER, device=device ) self.models["generator"] = pipeline( "text-generation", model=Config.MODEL_GENERATOR, device=device ) except Exception as e: self.logger.error(f"Error initializing models: {str(e)}") raise def get_model(self, name: str) -> Any: return self.models.get(name) # main.py import gradio as gr from typing import Dict, Any import logging from config import Config from utils import Utils from models import ModelManager from visualization import Visualizer from datetime import datetime class LearningPathGenerator: def __init__(self): self.logger = Utils.setup_logging() self.model_manager = ModelManager() self.history_file = Config.HISTORY_FILE if not os.path.exists(self.history_file): Utils.save_json([], self.history_file) def process_audio(self, audio_path: str, path_name: str = "", difficulty: str = "intermediate", include_resources: bool = True) -> Dict[str, Any]: try: transcriber = self.model_manager.get_model("transcriber") transcription = transcriber(audio_path)["text"] generator = self.model_manager.get_model("generator") analysis = self._generate_analysis(generator, transcription, difficulty, include_resources) topics, subtopics = Utils.extract_topics(analysis) mind_map = Visualizer.create_mind_map(topics, subtopics) if path_name: self._save_to_history(transcription, analysis, path_name) return { "transcription": transcription, "analysis": analysis, "mind_map": mind_map } except Exception as e: self.logger.error(f"Processing error: {str(e)}") return self._error_response(str(e)) def _generate_analysis(self, generator: Any, text: str, difficulty: str, include_resources: bool) -> str: prompt = f""" Based on the following text, create a detailed learning path for {difficulty} level: {text[:Config.MAX_TEXT_LENGTH]} Learning path: """ response = generator( prompt, max_length=300, num_return_sequences=1 )[0]["generated_text"] if include_resources: response += self._generate_resources() return response def _generate_resources(self) -> str: return """ Recommended Resources: 1. Books: - "Essential Guide" - "Advanced Techniques" 2. Online Courses: - Coursera: "Topic Specialization" - edX: "Advanced Course" 3. Practical Resources: - Interactive tutorials - Practice exercises - Real-world projects """ def _save_to_history(self, transcription: str, analysis: str, path_name: str): history = Utils.load_json(self.history_file) or [] history.append({ "date": datetime.now().isoformat(), "name": path_name, "transcription": transcription, "analysis": analysis }) Utils.save_json(history, self.history_file) def _error_response(self, error_msg: str) -> Dict[str, Any]: return { "transcription": f"Error: {error_msg}", "analysis": "Could not generate analysis due to an error.", "mind_map": None } def create_interface(self): with gr.Blocks(theme=gr.themes.Soft()) as app: gr.Markdown(""" # 🎓 Learning Path Generator Upload an audio file describing your learning goals and receive a personalized learning path with resources! """) with gr.Tab("Generate Path"): with gr.Row(): with gr.Column(scale=2): audio_input = gr.Audio( type="filepath", label="Audio Upload", description="Record or upload an audio describing your goals" ) with gr.Row(): path_name = gr.Textbox( label="Path Name", placeholder="Give your learning path a name (optional)" ) difficulty = gr.Dropdown( choices=["beginner", "intermediate", "advanced"], value="intermediate", label="Difficulty Level" ) include_resources = gr.Checkbox( label="Include Recommended Resources", value=True ) process_btn = gr.Button( "Generate Learning Path", variant="primary" ) text_output = gr.Textbox( label="Audio Transcription", lines=4 ) analysis_output = gr.Textbox( label="Analysis and Learning Path", lines=10 ) mind_map_output = gr.Image( label="Learning Path Mind Map" ) process_btn.click( fn=self.process_audio, inputs=[audio_input, path_name, difficulty, include_resources], outputs={ "transcription": text_output, "analysis": analysis_output, "mind_map": mind_map_output } ) return app if __name__ == "__main__": try: generator = LearningPathGenerator() app = generator.create_interface() app.launch(debug=Config.DEBUG) except Exception as e: logging.error(f"Application error: {str(e)}") raise