#!/usr/bin/env python3 import sys import os import asyncio from datetime import datetime from typing import List, Dict, Any sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src')) from infrastructure.elasticsearch.client import ElasticsearchClient from domain.services.calculador_pontuacao import CalculadorPontuacao from domain.entities.consultor import Consultor, CoordenacaoCapes, Consultoria, Premiacao, Periodo ES_URL = os.getenv("ES_URL", "http://localhost:9200") ES_INDEX = os.getenv("ES_INDEX", "atuacapes") ES_USER = os.getenv("ES_USER", "") ES_PASSWORD = os.getenv("ES_PASSWORD", "") def parse_date(date_str): if not date_str: return None try: if '/' in date_str: return datetime.strptime(date_str[:10], '%d/%m/%Y') else: return datetime.strptime(date_str[:10], '%Y-%m-%d') except: return None def extrair_coordenacoes_capes(atuacoes: List[Dict]) -> List[CoordenacaoCapes]: coordenacoes_data = [ a for a in atuacoes if a.get("tipo") in [ "Coordenação de Área de Avaliação", "Histórico de Coordenação de Área de Avaliação", ] ] result = [] for coord in coordenacoes_data: dados = coord.get("dadosCoordenacaoArea") or coord.get("dadosHistoricoCoordenacaoArea") or {} nome = coord.get("nome", "") if "câmara" in nome.lower() or "camara" in nome.lower(): tipo = "CAM" elif "mestrado profissional" in nome.lower(): tipo = "CAJ-MP" elif "adjunt" in nome.lower(): tipo = "CAJ" else: tipo = "CA" inicio = parse_date(coord.get("inicio") or dados.get("inicio")) fim = parse_date(coord.get("fim") or dados.get("fim")) if not inicio: continue area = dados.get("areaAvaliacao", {}) if isinstance(area, dict): area_nome = area.get("nome", "N/A") else: area_nome = str(area) if area else "N/A" periodo = Periodo(inicio=inicio, fim=fim) result.append(CoordenacaoCapes( tipo=tipo, area_avaliacao=area_nome, periodo=periodo, areas_adicionais=[], ja_coordenou_antes=False )) return result def extrair_consultoria(atuacoes: List[Dict]) -> Consultoria: consultorias = [ a for a in atuacoes if a.get("tipo") in ["Consultor", "Histórico de Consultoria"] ] if not consultorias: return None datas = [] areas = set() total_eventos = len(consultorias) vezes_responsavel = 0 for cons in consultorias: dados = cons.get("dadosConsultoria", {}) inicio = parse_date(cons.get("inicio")) fim = parse_date(cons.get("fim")) if inicio: datas.append(inicio) if fim: datas.append(fim) area = dados.get("areaAvaliacao") if area: areas.add(area) if dados.get("responsavel"): vezes_responsavel += 1 if not datas: return None primeiro_evento = min(datas) ultimo_evento = max(datas) limite_recente = datetime.now().replace(year=datetime.now().year - 2) eventos_recentes = sum(1 for d in datas if d >= limite_recente) anos = (datetime.now() - primeiro_evento).days / 365.25 return Consultoria( total_eventos=total_eventos, eventos_recentes=eventos_recentes, primeiro_evento=primeiro_evento, ultimo_evento=ultimo_evento, areas=list(areas), situacao="Ativo" if eventos_recentes > 0 else "Histórico", anos_completos=int(anos), anos_consecutivos=int(anos), retornos=0 ) def extrair_premiacoes(atuacoes: List[Dict]) -> List[Premiacao]: premiacoes_data = [ a for a in atuacoes if a.get("tipo") in [ "Premiação Prêmio", "Avaliação Prêmio", "Inscrição Prêmio", ] ] result = [] mapa_pontos = { "Premiação Prêmio": 60, "Avaliação Prêmio": 40, "Inscrição Prêmio": 20, } for prem in premiacoes_data: tipo = prem.get("tipo", "") dados = prem.get("dadosPremiacaoPremio") or prem.get("dadosParticipacaoPremio") or prem.get("dadosParticipacaoInscricaoPremio") or {} nome_premio = dados.get("premio", "") or prem.get("descricao", "") ano_str = dados.get("ano") or prem.get("inicio", "") try: ano = int(ano_str) if isinstance(ano_str, (int, str)) and str(ano_str).isdigit() else 0 except: ano = 0 pontos = mapa_pontos.get(tipo, 0) result.append(Premiacao( tipo=tipo, nome_premio=nome_premio, ano=ano, pontos=pontos )) return result async def main(): print("Conectando ao Elasticsearch...") es_client = ElasticsearchClient(ES_URL, ES_INDEX, ES_USER, ES_PASSWORD) await es_client.connect() try: print("Buscando candidatos com boost...") docs = await es_client.buscar_candidatos_ranking(size=100) print(f"Encontrados {len(docs)} candidatos") calculador = CalculadorPontuacao() consultores = [] print("\nProcessando consultores...") for idx, doc in enumerate(docs, 1): id_pessoa = doc.get("id") dados_pessoais = doc.get("dadosPessoais", {}) nome = dados_pessoais.get("nome", "N/A") cpf = dados_pessoais.get("cpf", "") atuacoes = doc.get("atuacoes", []) coordenacoes_capes = extrair_coordenacoes_capes(atuacoes) consultoria = extrair_consultoria(atuacoes) premiacoes = extrair_premiacoes(atuacoes) consultor = Consultor( id_pessoa=id_pessoa, nome=nome, cpf=cpf, coordenacoes_capes=coordenacoes_capes, coordenacoes_programas=[], consultoria=consultoria, premiacoes=premiacoes ) pontuacao = calculador.calcular_pontuacao_completa(consultor) consultor.pontuacao = pontuacao consultores.append(consultor) if idx % 10 == 0: print(f" Processados {idx}/{len(docs)} consultores...") print("\nOrdenando por pontuação...") consultores.sort(key=lambda c: c.pontuacao_total, reverse=True) print("\n" + "="*100) print("TOP 10 CONSULTORES - RANKING CAPES") print("="*100) for rank, c in enumerate(consultores[:10], 1): print(f"\n{rank}º LUGAR - {c.nome}") print(f" ID: {c.id_pessoa}") print(f" PONTUAÇÃO TOTAL: {c.pontuacao_total:.2f} pontos") print(f" Componente A (Coordenação CAPES): {c.pontuacao.componente_a.total:.2f}") print(f" Base: {c.pontuacao.componente_a.base} | Tempo: {c.pontuacao.componente_a.tempo}") print(f" Extras: {c.pontuacao.componente_a.extras} | Bônus: {c.pontuacao.componente_a.bonus} | Retorno: {c.pontuacao.componente_a.retorno}") print(f" Componente B (Coordenação PPG): {c.pontuacao.componente_b.total:.2f}") print(f" Componente C (Consultoria): {c.pontuacao.componente_c.total:.2f}") if c.consultoria: print(f" Base: {c.pontuacao.componente_c.base} | Tempo: {c.pontuacao.componente_c.tempo}") print(f" Eventos: {c.consultoria.total_eventos} | Recentes: {c.consultoria.eventos_recentes}") print(f" Áreas: {', '.join(c.consultoria.areas[:3])}") print(f" Componente D (Premiações): {c.pontuacao.componente_d.total:.2f}") if c.premiacoes: print(f" Total de premiações: {len(c.premiacoes)}") print(f" Anos de atuação: {c.anos_atuacao}") print(f" Ativo: {'Sim' if c.ativo else 'Não'}") if c.coordenacoes_capes: print(f" Coordenações CAPES:") for coord in c.coordenacoes_capes[:3]: status = "ATIVA" if coord.periodo.ativo else "ENCERRADA" print(f" - {coord.tipo}: {coord.area_avaliacao} ({status})") print("\n" + "="*100) print(f"\nEstatísticas Gerais:") print(f" Total de candidatos processados: {len(consultores)}") print(f" Pontuação máxima: {consultores[0].pontuacao_total:.2f}") print(f" Pontuação mínima (top 10): {consultores[9].pontuacao_total:.2f}") print(f" Média de pontuação (top 10): {sum(c.pontuacao_total for c in consultores[:10])/10:.2f}") finally: await es_client.close() if __name__ == "__main__": asyncio.run(main())