import logging import os try: from groq import Groq except ImportError: Groq = None try: import google.generativeai as genai except ImportError: genai = None logger = logging.getLogger(__name__) groq_client = None genai_client = None try: GROQ_API_KEY = os.environ.get("GROQ_API_KEY") if GROQ_API_KEY and Groq: groq_client = Groq(api_key=GROQ_API_KEY) except Exception as e: logger.warning(f"Groq client not available: {e}") try: GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY") if GEMINI_API_KEY and genai: genai.configure(api_key=GEMINI_API_KEY) genai_client = genai except Exception as e: logger.warning(f"Gemini client not available: {e}") def generate_study_plan(user_data): """Gera um plano de estudos estruturado a partir dos dados do usuΓ‘rio (sem IA).""" from datetime import timedelta current_level = user_data.get('english_level', 'B1') target_level = user_data.get('target_level', 'B2') weekly_hours = user_data.get('weekly_hours', 5) interests = user_data.get('interests', {}) context_focus = user_data.get('context_focus', 'General/Social') study_goals = user_data.get('study_goals', []) # ProgressΓ£o de nΓ­veis level_progression = { 'A1': {'next': 'A2', 'weeks': 12}, 'A2': {'next': 'B1', 'weeks': 16}, 'B1': {'next': 'B2', 'weeks': 20}, 'B2': {'next': 'C1', 'weeks': 24}, 'C1': {'next': 'C2', 'weeks': 28}, 'C2': {'next': 'C2', 'weeks': 32} } # Timeline base_weeks = level_progression.get(current_level, level_progression['B1'])['weeks'] hour_multiplier = 5 / max(weekly_hours, 1) adjusted_weeks = int(base_weeks * hour_multiplier) from datetime import datetime completion_date = (datetime.now() + timedelta(weeks=adjusted_weeks)).date().isoformat() # Estrutura semanal distributions = { 'A1': {'reading': 0.25, 'flashcards': 0.30, 'conversation': 0.20, 'writing': 0.15, 'grammar': 0.10}, 'A2': {'reading': 0.30, 'flashcards': 0.25, 'conversation': 0.20, 'writing': 0.15, 'grammar': 0.10}, 'B1': {'reading': 0.30, 'flashcards': 0.20, 'conversation': 0.25, 'writing': 0.20, 'listening': 0.05}, 'B2': {'reading': 0.25, 'flashcards': 0.15, 'conversation': 0.25, 'writing': 0.25, 'listening': 0.10}, 'C1': {'reading': 0.30, 'flashcards': 0.10, 'conversation': 0.25, 'writing': 0.25, 'listening': 0.10}, 'C2': {'reading': 0.35, 'flashcards': 0.05, 'conversation': 0.25, 'writing': 0.25, 'listening': 0.10} } base_dist = distributions.get(current_level, distributions['B1']) total_minutes = weekly_hours * 60 weekly_structure = {} for activity, percentage in base_dist.items(): minutes = int(total_minutes * percentage) if minutes >= 10: weekly_structure[activity] = { 'minutes_per_week': minutes, 'sessions_per_week': max(1, minutes // 30), 'minutes_per_session': minutes // max(1, minutes // 30) } # Dicas de estudo (IA se disponΓ­vel) def get_default_tips(level): tips_by_level = { 'A1': [ "πŸ“š Start with basic vocabulary - 10 new words daily", "🎯 Focus on present tense in daily conversations", "πŸ’‘ Use picture dictionaries for visual learning", "⭐ Practice pronunciation with simple audio materials", "πŸš€ Don't worry about mistakes - communication is key!" ], 'A2': [ "πŸ“š Read simple news articles and stories", "🎯 Practice past and future tenses regularly", "πŸ’‘ Join basic English conversation groups", "⭐ Use language learning apps for daily practice", "πŸš€ Watch movies with subtitles in your language" ], 'B1': [ "πŸ“š Read intermediate articles on topics you enjoy", "🎯 Practice expressing opinions and preferences", "πŸ’‘ Start writing short paragraphs daily", "⭐ Listen to podcasts at normal speed", "πŸš€ Try to think in English for simple tasks" ], 'B2': [ "πŸ“š Read longer articles and opinion pieces", "🎯 Practice formal and informal writing styles", "πŸ’‘ Engage in debates and discussions", "⭐ Watch news programs without subtitles", "πŸš€ Set specific goals for each study session" ], 'C1': [ "πŸ“š Read academic and professional texts", "🎯 Practice nuanced expressions and idioms", "πŸ’‘ Write formal reports and presentations", "⭐ Listen to academic lectures and conferences", "πŸš€ Focus on specialized vocabulary for your field" ], 'C2': [ "πŸ“š Read literature and complex analytical texts", "🎯 Master subtle language differences", "πŸ’‘ Write with stylistic sophistication", "⭐ Engage with native speakers in professional contexts", "πŸš€ Aim for native-like fluency in all skills" ] } return tips_by_level.get(level, tips_by_level['B1']) def generate_ai_tips(user_data): prompt = f""" Generate 5 personalized English study tips for a user with these characteristics: - Current Level: {user_data.get('english_level', 'B1')} - Target Level: {user_data.get('target_level', 'B2')} - Weekly Study Time: {user_data.get('weekly_hours', 5)} hours - Context Focus: {user_data.get('context_focus', 'General/Social')} - Interests: {', '.join(user_data.get('interests', {}).keys())} Provide practical, actionable tips that are specific to their level and interests. Format as a simple list of tips, each starting with an emoji. """ try: if groq_client: response = groq_client.chat.completions.create( model="llama-3.1-8b-instant", messages=[{"role": "user", "content": prompt}], temperature=0.7 ) response_text = response.choices[0].message.content elif genai_client: model = genai_client.GenerativeModel('gemini-2.5-flash-latest') response = model.generate_content(prompt) response_text = response.text else: return get_default_tips(user_data.get('english_level', 'B1')) tips = [line.strip() for line in response_text.split('\n') if line.strip() and any(e in line for e in ['πŸ“š','πŸ’‘','🎯','⭐','πŸš€'])] return tips[:5] if tips else get_default_tips(user_data.get('english_level', 'B1')) except Exception as e: logger.warning(f"AI study tips error: {e}") return get_default_tips(user_data.get('english_level', 'B1')) study_tips = generate_ai_tips(user_data) # Milestones milestones = [] milestone_intervals = max(2, adjusted_weeks // 4) for i in range(1, 5): week = milestone_intervals * i if week <= adjusted_weeks: milestones.append({ 'week': week, 'title': f"Milestone {i}", 'description': f"Progress checkpoint {i}", 'target_date': (datetime.now() + timedelta(weeks=week)).date().isoformat(), 'completed': False }) plan = { 'id': f"plan_{datetime.now().strftime('%Y%m%d_%H%M%S')}", 'created_at': datetime.now().isoformat(), 'current_level': current_level, 'target_level': target_level, 'weekly_hours': weekly_hours, 'estimated_weeks': adjusted_weeks, 'completion_date': completion_date, 'weekly_structure': weekly_structure, 'study_tips': study_tips, 'milestones': milestones, 'interests': interests, 'context_focus': context_focus, 'study_goals': study_goals } return plan import json from datetime import datetime # In-memory study plan storage (testing only) _MEM_STUDY_PLAN = None def save_study_plan(plan_data): """Store the study plan in memory (no disk IO).""" global _MEM_STUDY_PLAN try: if isinstance(plan_data, dict): plan_data = dict(plan_data) plan_data['saved_at'] = datetime.now().isoformat() _MEM_STUDY_PLAN = plan_data return True except Exception as e: logger.warning(f"Failed to save study plan in-memory: {e}") return False def load_study_plan(): """Load the study plan from in-memory storage.""" return _MEM_STUDY_PLAN