From 03b1f4f1d1351ade614f7e31af9b9bc7dc70a3e8 Mon Sep 17 00:00:00 2001 From: Jose Henrique Date: Mon, 2 Jun 2025 16:47:24 -0300 Subject: [PATCH] add apelido --- .../Repository/CandidatoRepository.cs | 16 +++++++-- OpenCand.API/jpg-normalize.sh | 33 +++++++++++++++++++ OpenCand.Core/Models/Candidato.cs | 3 ++ OpenCand.ETL/Parser/Models/CandidatoCSV.cs | 3 ++ .../Parser/Services/CsvParserService.cs | 2 ++ OpenCand.ETL/Program.cs | 3 -- .../Repository/CandidatoRepository.cs | 13 +++++--- db/db.sql | 4 +++ 8 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 OpenCand.API/jpg-normalize.sh diff --git a/OpenCand.API/Repository/CandidatoRepository.cs b/OpenCand.API/Repository/CandidatoRepository.cs index fb838ca..5983831 100644 --- a/OpenCand.API/Repository/CandidatoRepository.cs +++ b/OpenCand.API/Repository/CandidatoRepository.cs @@ -15,11 +15,21 @@ namespace OpenCand.Repository using (var connection = new NpgsqlConnection(ConnectionString)) { return (await connection.QueryAsync(@" - SELECT idcandidato, cpf, nome, datanascimento, email, sexo, estadocivil, escolaridade, ocupacao + SELECT * + CASE + WHEN lower(nome) = lower(@query) THEN 0 -- Exact match (case-insensitive) + WHEN lower(nome) LIKE lower(@query) || '%' THEN 1 -- Starts with match (case-insensitive) + WHEN lower(nome) LIKE '%' || lower(@query) THEN 2 -- Contains anywhere match (case-insensitive) + WHEN cpf = @query THEN 0 -- Exact match for CPF + WHEN cpf LIKE @query || '%' THEN 1 -- Starts with match for CPF + WHEN cpf LIKE '%' || @query THEN 2 -- Contains anywhere match for CPF + ELSE 3 + END AS name_rank FROM candidato WHERE nome ILIKE '%' || @query || '%' OR - cpf ILIKE '%' || @query || '%' OR - email ILIKE '%' || @query || '%' + cpf ILIKE '%' || @query || '%' + ORDER BY name_rank, + length(nome) ASC LIMIT 10;", new { query })).AsList(); } diff --git a/OpenCand.API/jpg-normalize.sh b/OpenCand.API/jpg-normalize.sh new file mode 100644 index 0000000..b0a5bc0 --- /dev/null +++ b/OpenCand.API/jpg-normalize.sh @@ -0,0 +1,33 @@ +#!/bin/bash +cd ./fotos_cand +COUNT=0 +shopt -s nocaseglob + +# Loop through all folders +for dir in */; do + # Change into the directory + cd "$dir" || continue + + # Loop over every “.jpeg” (or “.JPEG”): + for f in *.jpeg; do + # “${f%.[jJ][pP][eE][gG]}” strips off the .jpeg/.JPEG suffix + base="${f%.[jJ][pP][eE][gG]}" + newfile="${base}.jpg" + + # If there’s already a .jpg with the same “base,” decide what to do: + if [ -e "$newfile" ]; then + echo "Skipping $f → $newfile (target exists)" + # you could `rm "$f"` or move it to a backup folder here if you prefer + else + mv -v "$f" "$newfile" + fi + done + + # Change back to the parent directory + cd .. +done + +shopt -u nocaseglob + +# Print a message indicating completion +echo "Normalization complete. Processed $COUNT files." \ No newline at end of file diff --git a/OpenCand.Core/Models/Candidato.cs b/OpenCand.Core/Models/Candidato.cs index 5f91d5e..4cc9b9f 100644 --- a/OpenCand.Core/Models/Candidato.cs +++ b/OpenCand.Core/Models/Candidato.cs @@ -12,6 +12,8 @@ namespace OpenCand.Core.Models public string Nome { get; set; } + public string Apelido { get; set; } + public DateTime? DataNascimento { get; set; } public string Email { get; set; } @@ -35,6 +37,7 @@ namespace OpenCand.Core.Models public Guid IdCandidato { get; set; } public string Cpf { get; set; } public string Nome { get; set; } + public string Apelido { get; set; } public string SqCandidato { get; set; } public int Ano { get; set; } public string TipoEleicao { get; set; } diff --git a/OpenCand.ETL/Parser/Models/CandidatoCSV.cs b/OpenCand.ETL/Parser/Models/CandidatoCSV.cs index 61cc632..4ba07b6 100644 --- a/OpenCand.ETL/Parser/Models/CandidatoCSV.cs +++ b/OpenCand.ETL/Parser/Models/CandidatoCSV.cs @@ -29,6 +29,9 @@ namespace OpenCand.Parser.Models [Name("NM_CANDIDATO")] public string NomeCandidato { get; set; } + [Name("NM_URNA_CANDIDATO")] + public string Apelido { get; set; } + [Name("NR_CPF_CANDIDATO")] public string CPFCandidato { get; set; } diff --git a/OpenCand.ETL/Parser/Services/CsvParserService.cs b/OpenCand.ETL/Parser/Services/CsvParserService.cs index 7e3aeea..da28db1 100644 --- a/OpenCand.ETL/Parser/Services/CsvParserService.cs +++ b/OpenCand.ETL/Parser/Services/CsvParserService.cs @@ -92,6 +92,7 @@ namespace OpenCand.Parser.Services Cpf = record.CPFCandidato, SqCandidato = record.SequencialCandidato, Nome = record.NomeCandidato, + Apelido = record.Apelido, Email = record.Email.Contains("@") ? record.Email : null, Sexo = record.Genero, EstadoCivil = record.EstadoCivil, @@ -103,6 +104,7 @@ namespace OpenCand.Parser.Services { Cpf = record.CPFCandidato, Nome = record.NomeCandidato, + Apelido = record.Apelido, SqCandidato = record.SequencialCandidato, Ano = record.AnoEleicao, TipoEleicao = record.TipoAbrangencia, diff --git a/OpenCand.ETL/Program.cs b/OpenCand.ETL/Program.cs index 7a5317c..c24f25e 100644 --- a/OpenCand.ETL/Program.cs +++ b/OpenCand.ETL/Program.cs @@ -24,9 +24,6 @@ namespace OpenCand try { - logger.LogInformation("Initializing database"); - // make a test connection to the database - logger.LogInformation("Starting data parsing"); var parserManager = services.GetRequiredService(); await parserManager.ParseFullDataAsync(); diff --git a/OpenCand.ETL/Repository/CandidatoRepository.cs b/OpenCand.ETL/Repository/CandidatoRepository.cs index 6a63d81..bc12a02 100644 --- a/OpenCand.ETL/Repository/CandidatoRepository.cs +++ b/OpenCand.ETL/Repository/CandidatoRepository.cs @@ -16,8 +16,8 @@ namespace OpenCand.Repository using (var connection = new NpgsqlConnection(ConnectionString)) { await connection.ExecuteAsync(@" - INSERT INTO candidato (idcandidato, cpf, nome, datanascimento, email, sexo, estadocivil, escolaridade, ocupacao) - VALUES (@idcandidato, @cpf, @nome, @datanascimento, @email, @sexo, @estadocivil, @escolaridade, @ocupacao) + INSERT INTO candidato (idcandidato, cpf, nome, apelido, datanascimento, email, sexo, estadocivil, escolaridade, ocupacao) + VALUES (@idcandidato, @cpf, @nome, @apelido, @datanascimento, @email, @sexo, @estadocivil, @escolaridade, @ocupacao) ON CONFLICT (idcandidato) DO UPDATE SET cpf = EXCLUDED.cpf, nome = EXCLUDED.nome, @@ -26,12 +26,14 @@ namespace OpenCand.Repository sexo = EXCLUDED.sexo, estadocivil = EXCLUDED.estadocivil, escolaridade = EXCLUDED.escolaridade, - ocupacao = EXCLUDED.ocupacao;", + ocupacao = EXCLUDED.ocupacao, + apelido = EXCLUDED.apelido;", new { idcandidato = candidato.IdCandidato, cpf = candidato.Cpf, nome = candidato.Nome, + apelido = candidato.Apelido, datanascimento = candidato.DataNascimento, email = candidato.Email, sexo = candidato.Sexo, @@ -47,13 +49,14 @@ namespace OpenCand.Repository using (var connection = new NpgsqlConnection(ConnectionString)) { await connection.ExecuteAsync(@" - INSERT INTO candidato_mapping (idcandidato, cpf, nome, sqcandidato, ano, tipoeleicao, siglauf, nomeue, cargo, nrcandidato, sgpartido, resultado) - VALUES (@idcandidato, @cpf, @nome, @sqcandidato, @ano, @tipoeleicao, @siglauf, @nomeue, @cargo, @nrcandidato, @sgpartido, @resultado);", + INSERT INTO candidato_mapping (idcandidato, cpf, nome, apelido, sqcandidato, ano, tipoeleicao, siglauf, nomeue, cargo, nrcandidato, sgpartido, resultado) + VALUES (@idcandidato, @cpf, @nome, @apelido, @sqcandidato, @ano, @tipoeleicao, @siglauf, @nomeue, @cargo, @nrcandidato, @sgpartido, @resultado);", new { idcandidato = candidatoMapping.IdCandidato, cpf = candidatoMapping.Cpf, nome = candidatoMapping.Nome, + apelido = candidatoMapping.Apelido, sqcandidato = candidatoMapping.SqCandidato, ano = candidatoMapping.Ano, tipoeleicao = candidatoMapping.TipoEleicao, diff --git a/db/db.sql b/db/db.sql index d23ca6e..995f380 100644 --- a/db/db.sql +++ b/db/db.sql @@ -8,6 +8,7 @@ CREATE TABLE candidato ( idcandidato UUID NOT NULL PRIMARY KEY, cpf VARCHAR(11), nome VARCHAR(255) NOT NULL, + apelido VARCHAR(255), datanascimento TIMESTAMPTZ, email TEXT, sexo CHAR(15), @@ -16,12 +17,14 @@ CREATE TABLE candidato ( ocupacao VARCHAR(150) ); CREATE INDEX idx_candidato_nome ON candidato (nome); +CREATE INDEX idx_candidato_apelido ON candidato (apelido); -- Each candidato (idcandidato, cpf, nome) will be mapped to a (sqcandidato, ano, tipo_eleicao, sg_uf, cargo, resultado) CREATE TABLE candidato_mapping ( idcandidato UUID NOT NULL, cpf VARCHAR(11), nome VARCHAR(255) NOT NULL, + apelido VARCHAR(255), sqcandidato TEXT, ano INT NOT NULL, tipoeleicao VARCHAR(50), @@ -36,6 +39,7 @@ CREATE TABLE candidato_mapping ( ); CREATE INDEX idx_candidato_mapping_cpf ON candidato_mapping (cpf); CREATE INDEX idx_candidato_mapping_nome ON candidato_mapping (nome); +CREATE INDEX idx_candidato_mapping_apelido ON candidato_mapping (apelido); CREATE INDEX idx_candidato_mapping_ano ON candidato_mapping (ano); CREATE INDEX idx_candidato_mapping_sqcandidato ON candidato_mapping (sqcandidato);