Files
ranking/backend/scripts/buscar_consultores_especificos.py
2025-12-14 23:57:06 -03:00

297 lines
9.8 KiB
Python

#!/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", "")
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())