use std::fs; use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm}; use actix_web::{post, HttpResponse}; use lettre::{ message::{header::ContentType, Attachment, MultiPart}, transport::smtp::authentication::{Credentials, Mechanism}, Message, SmtpTransport, Transport, }; #[derive(Debug, MultipartForm, Default)] struct HealthForm { #[multipart(rename = "firstname")] first_name: Option>, #[multipart(rename = "lastname")] last_name: Option>, #[multipart(rename = "parentfirstname")] parent_first_name: Option>, #[multipart(rename = "parentlastname")] parent_last_name: Option>, birthdate: Option>, gender: Option>, street: Option>, city: Option>, state: Option>, zip: Option>, #[multipart(rename = "cellphone")] parent_cellphone: Option>, homephone: Option>, #[multipart(rename = "add-emergency-contact")] contact: Option>, #[multipart(rename = "add-emergency-contact-phone")] contact_phone: Option>, doctorname: Option>, doctorcity: Option>, doctorphone: Option>, #[multipart(rename = "medical-coverage")] medical: Option>, #[multipart(rename = "insurance-name")] insurance: Option>, #[multipart(rename = "policy-number")] policy_number: Option>, allergies: Option>, #[multipart(rename = "allergies-other")] allergies_other: Option>, #[multipart(rename = "specific-allergies")] specific_allergies: Option>, #[multipart(rename = "allergic-treatment")] treatment: Option>, conditions: Option>, #[multipart(rename = "tetanus-shot")] tetanus: Option>, #[multipart(rename = "swimming-ability")] swimming: Option>, #[multipart(rename = "medication-schedule")] medication: Option>, #[multipart(rename = "other-notes")] notes: Option>, agreement: Option>, #[multipart(rename = "image")] file: Option, } #[post("/health-form")] pub async fn health_form(MultipartForm(form): MultipartForm) -> HttpResponse { let first = form .first_name .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let last = form .last_name .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let email_subject = format!("{} {} filled out a health form!", first, last); let filename_noext = String::from(format!("{}_{}", first, last)); let parent = format!( "{} {}", form.parent_first_name .as_ref() .unwrap_or(&Text { 0: String::from("") }) .0 .clone(), form.parent_last_name .as_ref() .unwrap_or(&Text { 0: String::from("") }) .0 .clone() ); let birthdate = form .birthdate .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let gender = form .gender .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let street = form .street .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let city = form .city .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let state = form .state .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let zip = form.zip.as_ref().unwrap_or(&Text { 0: 0 }).0.clone(); let parent_cellphone = form .parent_cellphone .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let homephone = form .homephone .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let contact = form .contact .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let contact_phone = form .contact_phone .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let doctorname = form .doctorname .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let doctorcity = form .doctorcity .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let doctorphone = form .doctorphone .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let medical = form .medical .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let insurance = form .insurance .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let policy_number = form .policy_number .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let agreement = form .agreement .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let allergies = form .allergies .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let allergies_other = form .allergies_other .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let specific_allergies = form .specific_allergies .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let treatment = form .treatment .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let conditions = form .conditions .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let tetanus = form .tetanus .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let swimming = form .swimming .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let medication = form .medication .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let notes = form .notes .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); log::info!("{first} {last} filled out a health form!"); let email = markup::new! { @markup::doctype() html { head { title { @format!("{} {} filled out a health form!", first, last) } style { "table { border-collapse: collapse; width: 100% }" "td, th { padding: 8px }" "td { text-align: left; width: 70%; word-wrap: break-word }" "th { text-align: right; border-right: 1px solid #ddd }" "tr { border-bottom: 1px solid #ddd }" "h1 { text-align: center }" } } body { h1 { @format!("Health form for {} {}!", first, last) } hr; table { tr { th { "Name" } td { @format!("{} {}", first, last) } } tr { th { "Parent" } td { @parent } } tr { th { "Birthdate" } td { @birthdate } } tr { th { "Gender" } td { @gender } } tr { th { "Street" } td { @street } } tr { th { "City" } td { @city } } tr { th { "State" } td { @state } } tr { th { "Zip" } td { @zip } } tr { th { "Phone" } td { @parent_cellphone } } tr { th { "Home Phone" } td { @homephone } } tr { th { "Additional Emergency Contact" } td { @contact } } tr { th { "Contact Phone" } td { @contact_phone } } tr { th { "Doctor" } td { @doctorname } } tr { th { "Doctor City" } td { @doctorcity } } tr { th { "Doctor Phone" } td { @doctorphone } } tr { th { "Medical Coverage" } td { @medical } } tr { th { "Insurance Provider" } td { @insurance } } tr { th { "Policy Number" } td { @policy_number } } tr { th { "Allergies" } td { @allergies } } tr { th { "Other Allergies" } td { @allergies_other } } tr { th { "Specific Allergies" } td { @specific_allergies } } tr { th { "Treatments" } td { @treatment } } tr { th { "Physical or mental conditions" } td { @conditions } } tr { th { "Last tetanus shot" } td { @tetanus } } tr { th { "Swimming Ability" } td { @swimming } } tr { th { "Medication Schedule" } td { @medication } } tr { th { "Other Relevant Info" } td { @notes } } tr { th { "Final Agreement" } td { @agreement } } } } } }; let mut path: Option = Some(String::from("")); let mut file_exists = false; let mut filename = String::from(""); log::info!("{:?}", form); log::info!("{:?}", file_exists); if let Some(f) = form.file { if let Some(file) = f.file_name { if let Some(ext) = file.rsplit(".").next() { filename = format!("{}.{}", filename_noext, ext); path = Some(format!("./tmp/{}.{}", filename_noext, ext)); } else { path = Some(format!("./tmp/{}", file)); } // let path = format!("./tmp/{}", file); log::info!("saving to {}", path.clone().unwrap()); match f.file.persist(path.clone().unwrap()) { Ok(f) => { log::info!("{:?}", f); if f.metadata().unwrap().len() > 0 { file_exists = true; } } Err(e) => log::info!("{:?}: Probably a missing image", e), } } } let multi = if file_exists { let filebody = fs::read(path.clone().unwrap_or_default()); let content_type = ContentType::parse("image/jpg").unwrap(); let attachment = Attachment::new(filename).body(filebody.unwrap(), content_type); log::info!("{:?}", attachment); MultiPart::alternative_plain_html(String::from("Testing"), email.to_string()) .singlepart(attachment) } else { MultiPart::alternative_plain_html(String::from("Testing"), email.to_string()) }; if let Ok(m) = Message::builder() .from( "TFC ADMIN " .parse() .unwrap(), ) .to("Chris Cochrun ".parse().unwrap()) .to("Ethan Rose ".parse().unwrap()) .subject(email_subject) .multipart(multi) { let sender = SmtpTransport::relay("mail.tfcconnection.org") .ok() .unwrap() .credentials(Credentials::new( "no-reply@mail.tfcconnection.org".to_owned(), "r9f36mNZFtiW4f".to_owned(), )) .authentication(vec![Mechanism::Plain]) .build(); match sender.send(&m) { Ok(res) => log::info!("{:?}", res), Err(e) => log::info!("{e}"), } } else { log::info!("Email incorrect"); } HttpResponse::Ok().body("hi") }