#!/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 = "http://elastic-atuacapes.hom.capes.gov.br:9200" ES_INDEX = "atuacapes" ES_USER = "admin-atuacapes" ES_PASSWORD = "O}!S0bj%FhJ:" NOMES_BUSCAR = [ "Veronica Maria de Araujo Calado", "Manoel Damiao de Sousa Neto" ] 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 buscar_por_nome(es_client, nome): query = { "size": 5, "query": { "match": { "dadosPessoais.nome": { "query": nome, "fuzziness": "AUTO" } } }, "_source": ["id", "dadosPessoais", "atuacoes"] } response = await es_client.client.post( f"{es_client.url}/{es_client.index}/_search", json=query ) response.raise_for_status() result = response.json() return result.get("hits", {}).get("hits", []) async def main(): print("Conectando ao Elasticsearch...") es_client = ElasticsearchClient(ES_URL, ES_INDEX, ES_USER, ES_PASSWORD) await es_client.connect() calculador = CalculadorPontuacao() try: for nome_buscar in NOMES_BUSCAR: print(f"\n{'='*100}") print(f"BUSCANDO: {nome_buscar}") print(f"{'='*100}") hits = await buscar_por_nome(es_client, nome_buscar) if not hits: print(f" Nenhum resultado encontrado para '{nome_buscar}'") continue print(f" Encontrados {len(hits)} resultados") for hit in hits: doc = hit["_source"] 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", []) print(f"\n CONSULTOR ENCONTRADO: {nome}") print(f" ID: {id_pessoa}") tipos_atuacao = {} for a in atuacoes: tipo = a.get("tipo", "Desconhecido") tipos_atuacao[tipo] = tipos_atuacao.get(tipo, 0) + 1 print(f"\n TIPOS DE ATUAÇÃO:") for tipo, count in sorted(tipos_atuacao.items()): print(f" - {tipo}: {count}") 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 print(f"\n PONTUAÇÃO CALCULADA:") print(f" TOTAL: {consultor.pontuacao_total:.2f} pontos") print(f" Componente A (Coordenação CAPES): {consultor.pontuacao.componente_a.total:.2f}") print(f" Base: {consultor.pontuacao.componente_a.base} | Tempo: {consultor.pontuacao.componente_a.tempo}") print(f" Extras: {consultor.pontuacao.componente_a.extras} | Bônus: {consultor.pontuacao.componente_a.bonus} | Retorno: {consultor.pontuacao.componente_a.retorno}") print(f" Componente B (Coordenação PPG): {consultor.pontuacao.componente_b.total:.2f}") print(f" Componente C (Consultoria): {consultor.pontuacao.componente_c.total:.2f}") if consultoria: print(f" Base: {consultor.pontuacao.componente_c.base} | Tempo: {consultor.pontuacao.componente_c.tempo}") print(f" Extras: {consultor.pontuacao.componente_c.extras}") print(f" Eventos: {consultoria.total_eventos} | Recentes: {consultoria.eventos_recentes}") print(f" Situação: {consultoria.situacao}") print(f" Anos: {consultoria.anos_completos}") print(f" Componente D (Premiações): {consultor.pontuacao.componente_d.total:.2f}") if premiacoes: print(f" Total de premiações: {len(premiacoes)}") for p in premiacoes[:5]: print(f" - {p.tipo}: {p.nome_premio} ({p.ano}) = {p.pontos} pts") print(f"\n DETALHAMENTO COMPLETO:") if coordenacoes_capes: print(f" Coordenações CAPES ({len(coordenacoes_capes)}):") for coord in coordenacoes_capes: status = "ATIVA" if coord.periodo.ativo else "ENCERRADA" print(f" - {coord.tipo}: {coord.area_avaliacao}") print(f" Período: {coord.periodo.inicio} até {coord.periodo.fim or 'atual'} ({status})") print(f" Anos: {coord.periodo.anos_decorridos:.1f}") finally: await es_client.close() if __name__ == "__main__": asyncio.run(main())