import os import json import firebase_admin from firebase_admin import credentials, firestore from flask import Flask, request, jsonify from transformers import pipeline app = Flask(__name__) # ====== CONFIGURAÇÃO FIREBASE ====== try: firebase_key = os.getenv("FIREBASE_KEY") if firebase_key: cred_dict = json.loads(firebase_key) cred = credentials.Certificate(cred_dict) firebase_admin.initialize_app(cred) db = firestore.client() print("✅ Firebase conectado com sucesso.") else: print("⚠️ FIREBASE_KEY não encontrada nos secrets do Space.") except Exception as e: print(f"❌ Erro ao inicializar Firebase: {e}") # ====== MODELO ====== try: model_pipeline = pipeline("text-classification", model="pysentimiento/robertuito-emotion-analysis") print("✅ Modelo carregado com sucesso!") except Exception as e: print(f"❌ Erro ao carregar modelo: {e}") model_pipeline = None # ====== MAPEAMENTO DE EMOÇÕES ====== emotion_labels = { "sadness": "tristeza", "joy": "alegria", "anger": "raiva", "fear": "ansiedade", "disgust": "insegurança", "surprise": "alegria", "others": "neutro" } # ====== SUGESTÕES ====== def gerar_sugestao(emotion_pt): sugestoes = { "tristeza": "Procure fazer algo que te acalme e traga conforto emocional.", "depressão": "Você não está sozinho. Considere conversar com alguém de confiança ou buscar apoio profissional.", "alegria": "Continue aproveitando esse momento positivo e compartilhe boas energias!", "raiva": "Afaste-se da situação e respire antes de reagir. Canalize essa energia em algo produtivo.", "ansiedade": "Tente identificar o que está te causando ansiedade e dê pequenos passos para enfrentá-la.", "insegurança": "Analise os pontos que causam insegurança e busque soluções práticas.", "neutro": "Mantenha o equilíbrio emocional e cuide de si mesmo.", "desconhecido": "Emoção não identificada com precisão." } return sugestoes.get(emotion_pt, "Mantenha o equilíbrio emocional e cuide de você mesmo.") # ====== FALLBACK APRIMORADO COM PALAVRAS-CHAVE ====== EMOTION_KEYWORDS = { "tristeza": ["triste","desanimado","melancólico","chateado","solitário","deprimido","abatido","infeliz","desmotivado"], "ansiedade": ["ansioso","preocupado","nervoso","tenso","inquieto","aflito","alarmado","sobrecarregado","inseguro","apreensivo"], "insegurança": ["inseguro","incerto","receoso","hesitante","duvidoso","apreensivo","desconfiado"], "raiva": ["irritado","zangado","raiva","furioso","ódio","revoltado","frustrado","indignado","hostil","bravo","enfurecido","irado"], "alegria": ["feliz","animado","contente","alegre","satisfeito","entusiasmado","radiante","orgulhoso","euforia"], "depressão": ["sem esperança","vazio","desesperado","sem vontade","cansado da vida","desamparado"], "neutro": ["ok","normal","tranquilo","indiferente","equilibrado","estável"] } def fallback_emotion(text): text_lower = text.lower() match_counts = {k: sum(1 for w in v if w in text_lower) for k, v in EMOTION_KEYWORDS.items()} emotion = max(match_counts, key=match_counts.get) if match_counts[emotion] == 0: emotion = "neutro" return { "status": "fallback", "emotion": emotion, "emode": [emotion], "confidence": 0.6 if match_counts[emotion] > 0 else 0.0, "suggestion": gerar_sugestao(emotion), "debug": "Fallback ativado" } # ====== AJUSTE HÍBRIDO ====== def hybrid_emotion(text, result): text_lower = text.lower() detected = result.get("emotion", "neutro") max_matches = 0 for emo, keywords in EMOTION_KEYWORDS.items(): matches = sum(2 for w in keywords if w in text_lower) if matches > max_matches: max_matches = matches if emo != detected: detected = emo confidence = result.get("confidence", 0.0) if detected != result.get("emotion"): confidence = 0.7 + max_matches * 0.05 confidence = min(confidence, 1.0) return { "status": "ok", "emotion": detected, "emode": [detected], "confidence": round(confidence, 2), "probabilities": result.get("probabilities", {detected: 1.0}), "suggestion": result.get("suggestion", gerar_sugestao(detected)), "debug": result.get("debug", "Híbrido aplicado") } # ====== ROTA DE ANÁLISE ====== @app.route("/analyze", methods=["POST"]) def analyze(): try: data = request.get_json() if not data or "text" not in data: return jsonify({"error": "Campo 'text' é obrigatório."}), 400 text = data["text"] if not model_pipeline: return jsonify(fallback_emotion(text)) result = model_pipeline(text, return_all_scores=True) if not result or len(result) == 0: return jsonify(fallback_emotion(text)) scores = {r["label"]: r["score"] for r in result[0]} top_label = max(scores, key=scores.get) confidence = round(scores[top_label], 2) emotion_pt = emotion_labels.get(top_label, "desconhecido") # Ajuste especial para "tristeza" muito forte if emotion_pt == "tristeza" and confidence >= 0.9: emotion_pt = "depressão" base_result = { "status": "ok", "emotion": emotion_pt, "emode": [emotion_pt], "confidence": confidence, "probabilities": {emotion_labels.get(k, k): round(v,3) for k,v in scores.items()}, "suggestion": gerar_sugestao(emotion_pt) } # Aplica lógica híbrida com fallback de palavras-chave final_result = hybrid_emotion(text, base_result) return jsonify(final_result) except Exception as e: return jsonify({"error": str(e)}), 500 if __name__ == "__main__": app.run(host="0.0.0.0", port=7860)