From 1ba0510a3e9a38c33ab7a7d2c6daf6df15508785 Mon Sep 17 00:00:00 2001 From: Jelson Rodrigues Date: Wed, 5 Nov 2025 09:35:17 -0300 Subject: [PATCH] refactor: extract zip and mail sending to other module --- src/main.rs | 142 +++++----------------------------------------------- 1 file changed, 12 insertions(+), 130 deletions(-) diff --git a/src/main.rs b/src/main.rs index da1753e..5cc0c52 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,17 @@ -use std::ffi::OsStr; use std::{any::Any, env, fmt::format, iter, time::Duration}; use chrono::{self, Timelike}; use dotenv; use ipaddress; use itertools::{self, Itertools}; -use lettre::message::Mailboxes; use lettre::{self, message}; use reqwest; use serde_json::{self, json}; -use zip; + +use std::io::prelude::*; + +pub mod zip_directory_util; +pub mod send_mail_util; fn main() -> anyhow::Result<()> { match dotenv::dotenv().ok() { @@ -519,21 +521,16 @@ fn main() -> anyhow::Result<()> { // Compress folder into zip let source_dir_str = format!("./evaluations/{formatted_day_before}"); let output_zip_file_str = format!("./evaluations/{formatted_day_before}.zip"); - let source_dir = Path::new(source_dir_str.as_str()); - let output_zip_file = Path::new(output_zip_file_str.as_str()); - doit(source_dir, output_zip_file, zip::CompressionMethod::Stored); - + let source_dir = std::path::Path::new(source_dir_str.as_str()); + let output_zip_file = std::path::Path::new(output_zip_file_str.as_str()); + zip_directory_util::zip_directory_util::zip_source_dir_to_dst_file(source_dir, output_zip_file); + // Send folder to email let recipients = "Wilson da Conceição Oliveira , Isadora G. Moura de Moura "; println!("Trying to send email... Recipients {recipients}"); - send_email( - &formatted_day_before, - &BOT_EMAIL, - &BOT_EMAIL_PASSWORD, - recipients, - &output_zip_file_str, - ); + send_mail_util::send_mail_util::send_email(&format!("Avaliacao atendimentos {formatted_day_before}"), &BOT_EMAIL, &BOT_EMAIL_PASSWORD, recipients, &output_zip_file_str); + return Ok(()); } @@ -659,119 +656,4 @@ fn get_piperun_chats_on_date( aggregated_talks.append(&mut all_other_messages); aggregated_talks -} - -use std::io::prelude::*; -use zip::{result::ZipError, write::SimpleFileOptions}; - -use std::fs::File; -use std::path::{Path, PathBuf}; -use walkdir::{DirEntry, WalkDir}; - -fn zip_dir( - it: &mut dyn Iterator, - prefix: &Path, - writer: T, - method: zip::CompressionMethod, -) where - T: Write + Seek, -{ - let mut zip = zip::ZipWriter::new(writer); - let options = SimpleFileOptions::default() - .compression_method(method) - .unix_permissions(0o755); - - let prefix = Path::new(prefix); - let mut buffer = Vec::new(); - for entry in it { - let path = entry.path(); - let name = path.strip_prefix(prefix).unwrap(); - let path_as_string = name - .to_str() - .map(str::to_owned) - .expect("Failed to parse path"); - - // Write file or directory explicitly - // Some unzip tools unzip files with directory paths correctly, some do not! - if path.is_file() { - println!("adding file {path:?} as {name:?} ..."); - zip.start_file(path_as_string, options) - .expect("Failed to add file"); - let mut f = File::open(path).unwrap(); - - f.read_to_end(&mut buffer).expect("Failed to read file"); - zip.write_all(&buffer).expect("Failed to write file"); - buffer.clear(); - } else if !name.as_os_str().is_empty() { - // Only if not root! Avoids path spec / warning - // and mapname conversion failed error on unzip - println!("adding dir {path_as_string:?} as {name:?} ..."); - zip.add_directory(path_as_string, options) - .expect("Failed to add directory"); - } - } - zip.finish().expect("Failed to ZIP"); -} - -fn doit(src_dir: &Path, dst_file: &Path, method: zip::CompressionMethod) { - if !Path::new(src_dir).is_dir() { - panic!("src_dir must be a directory"); - } - - let path = Path::new(dst_file); - let file = File::create(path).unwrap(); - - let walkdir = WalkDir::new(src_dir); - let it = walkdir.into_iter(); - - zip_dir(&mut it.filter_map(|e| e.ok()), src_dir, file, method); -} - -use lettre::{ - Message, SmtpTransport, Transport, - message::Attachment, - message::MultiPart, - message::SinglePart, - message::header::ContentType, - transport::smtp::authentication::{Credentials, Mechanism}, -}; - -fn send_email( - day_before: &str, - bot_email: &str, - bot_email_password: &str, - to: &str, - zip_file_name: &str, -) { - let filebody = std::fs::read(zip_file_name).unwrap(); - let content_type = ContentType::parse("application/zip").unwrap(); - let attachment = Attachment::new(zip_file_name.to_string()).body(filebody, content_type); - let mailboxes: Mailboxes = to.parse().unwrap(); - let to_header: message::header::To = mailboxes.into(); - - let email = Message::builder() - .from(format!("PipeRUN bot <{bot_email}>").parse().unwrap()) - .reply_to(format!("PipeRUN bot <{bot_email}>").parse().unwrap()) - .mailbox(to_header) - .subject(format!("Avaliacao atendimentos {day_before}")) - .multipart( - MultiPart::mixed() - .singlepart( - SinglePart::builder() - .header(ContentType::TEXT_PLAIN) - .body(String::from("Avaliacao dos atendimentos")), - ) - .singlepart(attachment), - ) - .unwrap(); - - // Create the SMTPS transport - let sender = SmtpTransport::from_url(&format!( - "smtps://{bot_email}:{bot_email_password}@mail.nova.net.br" - )) - .unwrap() - .build(); - - // Send the email via remote relay - sender.send(&email).unwrap(); -} +} \ No newline at end of file