Correção de bug + debug visual

This commit is contained in:
2026-02-23 08:46:08 -03:00
parent b95e3f87d1
commit 2f11fb1b1d

View File

@@ -5,9 +5,12 @@ use polars::prelude::*;
use reqwest; use reqwest;
use std::env; use std::env;
use std::time::Duration; use std::time::Duration;
use std::path::Path;
use csv; use csv;
use std::fs::metadata;
use std::io::Read;
pub mod send_mail_util; pub mod send_mail_util;
pub mod zip_directory_util; pub mod zip_directory_util;
@@ -19,12 +22,12 @@ struct CsvHeader {
#[derive(Debug, serde::Deserialize)] #[derive(Debug, serde::Deserialize)]
struct CsvEvaluation { struct CsvEvaluation {
APRESENTAÇÃO: u8, APRESENTACAO: u8,
CONFIRMAÇÃO_DE_EMAIL: u8, CONFIRMAÇÃO_DE_EMAIL: u8,
CONFIRMAÇÃO_DE_TELEFONE: u8, CONFIRMAÇÃO_DE_TELEFONE: u8,
PROTOCOLO: u8, PROTOCOLO: u8,
USO_DO_PORTUGUÊS: u8, USO_DO_PORTUGUES: u8,
PACIÊNCIA_E_EDUCAÇÃO: u8, PACIENCIA_E_EDUCACAO: u8,
DISPONIBILIDADE: u8, DISPONIBILIDADE: u8,
CONHECIMENTO_TÉCNICO: u8, CONHECIMENTO_TÉCNICO: u8,
DIDATISMO: u8, DIDATISMO: u8,
@@ -228,14 +231,93 @@ fn main() {
} }
}; };
}) })
.filter_map_ok(|(ai_repsonse, file_path_csv)| { .filter_map_ok(|(ai_response, file_path_csv)| {
let mut reader = csv::ReaderBuilder::new()
.has_headers(true) // ---------- LOG 1: mostra qual arquivo está sendo processado ----------
.delimiter(b';') // eprintln!("🔍 Processando arquivo: {:?}", file_path_csv);
.from_reader(ai_repsonse.as_bytes());
// Mostra o caminho absoluto
let path = file_path_csv.path();
// Caminho absoluto
if let Ok(abs_path) = std::fs::canonicalize(&path) {
eprintln!("📁 Caminho absoluto: {:?}", abs_path);
}
// Metadados
if let Ok(meta) = std::fs::metadata(&path) {
if let Ok(modified) = meta.modified() {
let datetime: chrono::DateTime<chrono::Local> = modified.into();
eprintln!("📅 Modificado (local): {}", datetime.format("%Y-%m-%d %H:%M:%S%.3f"));
//eprintln!("🕒 Modificado: {:?}", modified);
}
eprintln!("📏 Tamanho: {} bytes", meta.len());
}
// Opcional: mostrar as primeiras linhas do CSV
eprintln!("📄 Primeiras 200 caracteres do CSV antes de sanitizar:\n{}", &ai_response[..200.min(ai_response.len())]);
//
// --- SALVAR CSV SANITIZADO PARA INSPEÇÃO ---
//let sanitized_path = file_path_csv.path().with_extension("sanitized.csv");
// if let Err(e) = std::fs::write(&sanitized_path, &ai_response) {
// eprintln!("⚠️ Erro ao salvar CSV sanitizado: {}", e);
//} else {
// eprintln!("💾 CSV sanitizado salvo: {:?}", sanitized_path);
// }
// ---------------------------------------------
// --- SALVAR CSV SANITIZADO EM PASTA SEPARADA ---
// Define o diretório base para os arquivos sanitizados
let sanitized_base = Path::new("./evaluations_sanitized");
// Obtém o caminho relativo do arquivo original em relação a "./evaluations"
// Exemplo: "./evaluations/2026-02-09/arquivo.csv" -> "2026-02-09/arquivo.csv"
if let Ok(relative_path) = file_path_csv.path().strip_prefix("./evaluations") {
let dest_path = sanitized_base.join(relative_path);
// Cria o diretório de destino, se necessário
if let Some(parent) = dest_path.parent() {
std::fs::create_dir_all(parent).expect("Falha ao criar diretório para sanitizados");
}
// Altera a extensão para .sanitized.csv (ou mantém .csv, como preferir)
let dest_path = dest_path.with_extension("sanitized.csv");
// Escreve o arquivo
if let Err(e) = std::fs::write(&dest_path, &ai_response) {
eprintln!("⚠️ Erro ao salvar CSV sanitizado em {:?}: {}", dest_path, e);
} else {
eprintln!("💾 CSV sanitizado salvo em: {:?}", dest_path);
}
} else {
eprintln!("⚠️ Caminho do arquivo não está dentro de ./evaluations: {:?}", file_path_csv.path());
}
let mut reader = csv::ReaderBuilder::new()
.has_headers(true)
.delimiter(b';')
.from_reader(ai_response.as_bytes());
// ---------- LOG 2: tenta desserializar e conta os registros ----------
let deserialized = reader.deserialize::<CsvHeader>().collect::<Vec<_>>();
eprintln!("🧾 Total de linhas lidas (incluindo cabeçalho?): {}", deserialized.len());
for (i, result) in deserialized.iter().enumerate() {
match result {
Ok(record) => {
eprintln!("✅ Linha {}: CATEGORIA={}, PONTOS={:?}", i, record.CATEGORIA, record.PONTOS);
}
Err(e) => {
eprintln!("❌ Linha {} ERRO: {}", i, e);
}
}
}
/*
let mut deserialized_iter = reader.deserialize::<CsvHeader>(); let mut deserialized_iter = reader.deserialize::<CsvHeader>();
let mut columns = deserialized_iter let mut columns = deserialized_iter
.filter_ok(|value| value.PONTOS.is_some()) .filter_ok(|value| value.PONTOS.is_some())
.map_ok(|value| { .map_ok(|value| {
@@ -250,16 +332,38 @@ fn main() {
None None
}) })
.collect_vec(); .collect_vec();
*/
let mut columns = deserialized
.into_iter() // usa os registros já lidos
.filter_ok(|value| {
// Se PONTOS for None, considera como 0 e mantém a linha
true // sempre mantém
})
.map_ok(|value| {
let pontos = value.PONTOS.unwrap_or(0) as u32;
Column::new(value.CATEGORIA.into(), [pontos])
})
/*
.filter_ok(|value| value.PONTOS.is_some())
.map_ok(|value| {
let pontos = value.PONTOS.unwrap() as u32;
Column::new(value.CATEGORIA.into(), [pontos])
})
*/
.filter_map(|value| value.ok())
.collect_vec();
if columns.len() != 9 { if columns.len() != 9 {
return None; return None;
} }
// Parse id talk from file_path // Parse id talk from file_path
// filename example is: CC - Erraoander Quintana - 515578 - 20251020515578.csv // filename example is: FIN - Lais Mota - 515578 - 20251020515578.csv
// id talk is the last information, so in the example is: 20251020515578 // id talk is the last information, so in the example is: 20251020515578
let regex_filename = let regex_filename =
regex::Regex::new(r"(CC - |ATEND - )((\w+\s*)+) - (\d+) - (\d+).csv").unwrap(); //regex::Regex::new(r"(FIN - )((\s*\w+\s*)+) - (\d+) - (\d+).csv").unwrap();
regex::Regex::new(r"ATEND - (.+?) - (\d+) - (\d+)\.csv").unwrap();
let filename = file_path_csv let filename = file_path_csv
.file_name() .file_name()
@@ -270,10 +374,10 @@ fn main() {
.expect("Failed to do regex capture"); .expect("Failed to do regex capture");
let user_name = found_regex_groups_in_filename let user_name = found_regex_groups_in_filename
.get(2) .get(1)
.expect("Failed to get the id from regex maches"); .expect("Failed to get the id from regex maches");
let talk_id = found_regex_groups_in_filename let talk_id = found_regex_groups_in_filename
.get(5) .get(3)
.expect("Failed to get the id from regex maches"); .expect("Failed to get the id from regex maches");
let excelence_percentual = columns let excelence_percentual = columns
@@ -479,11 +583,11 @@ fn main() {
)), )),
); );
let recipients = "Wilson da Conceição Oliveira <wilson.oliveira@nova.net.br>, nicolas.borges@nova.net.br, Isadora G. Moura de Moura <isadora.moura@nova.net.br>"; let recipients = "Wilson da Conceição Oliveira <wilson.oliveira@nova.net.br>, nicolas.borges@nova.net.br, isadora.moura@nova.net.br";
println!("Trying to send mail... {recipients}"); println!("Trying to send mail... {recipients}");
send_mail_util::send_mail_util::send_email( send_mail_util::send_mail_util::send_email(
&format!( &format!(
"Relatório agrupado dos atendimentos semana {first_day_of_last_week} - {last_day_of_last_week}" "Relatório agrupado dos atendimentos da fila do Suporte - semana {first_day_of_last_week} - {last_day_of_last_week}"
), ),
&BOT_EMAIL, &BOT_EMAIL,
&BOT_EMAIL_PASSWORD, &BOT_EMAIL_PASSWORD,