fixing up the api to work better for nix and move the table format
This commit is contained in:
parent
774328aa5b
commit
ee252aec13
7 changed files with 305 additions and 96 deletions
|
@ -6,8 +6,8 @@ use color_eyre::eyre::{Context, Result};
|
|||
use futures::FutureExt;
|
||||
use lettre::{message::SinglePart, Message};
|
||||
use maud::{html, Markup, DOCTYPE};
|
||||
use reqwest::Client;
|
||||
use tracing::{error, info};
|
||||
use reqwest::{Client, Response};
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
#[derive(Debug, MultipartForm)]
|
||||
struct CampForm {
|
||||
|
@ -39,27 +39,30 @@ struct CampForm {
|
|||
health_form: Text<String>,
|
||||
}
|
||||
|
||||
impl From<&CampForm> for HashMap<i32, String> {
|
||||
impl From<&CampForm> for HashMap<&str, String> {
|
||||
fn from(form: &CampForm) -> Self {
|
||||
let mut map = HashMap::new();
|
||||
map.insert(63, format!("{} {}", form.first_name.0, form.last_name.0));
|
||||
map.insert(
|
||||
64,
|
||||
"Full_Name",
|
||||
format!("{} {}", form.first_name.0, form.last_name.0),
|
||||
);
|
||||
map.insert(
|
||||
"Parent_Name",
|
||||
format!("{} {}", form.parent_first_name.0, form.parent_last_name.0),
|
||||
);
|
||||
map.insert(65, form.parent_phone.0.clone());
|
||||
map.insert(66, form.parent_email.0.clone().clone());
|
||||
map.insert(67, form.birthdate.0.clone());
|
||||
map.insert(69, form.gender.0.clone());
|
||||
map.insert(70, form.street.0.clone());
|
||||
map.insert(71, form.city.0.clone());
|
||||
map.insert(72, form.state.0.clone());
|
||||
map.insert(73, form.zip.0.clone().to_string());
|
||||
map.insert(74, form.grade.0.clone());
|
||||
map.insert(75, form.week.0.clone());
|
||||
map.insert(76, form.shirt.0.clone());
|
||||
map.insert(77, form.registration.0.clone());
|
||||
map.insert(115, form.health_form.0.clone());
|
||||
map.insert("Parent_Phone", form.parent_phone.0.clone());
|
||||
map.insert("Parent_Email", form.parent_email.0.clone().clone());
|
||||
map.insert("Birth_Date", form.birthdate.0.clone());
|
||||
map.insert("Gender", form.gender.0.clone());
|
||||
map.insert("Street_Address", form.street.0.clone());
|
||||
map.insert("City", form.city.0.clone());
|
||||
map.insert("State", form.state.0.clone());
|
||||
map.insert("Zipcode", form.zip.0.clone().to_string());
|
||||
map.insert("Grade", form.grade.0.clone());
|
||||
map.insert("Week_Chosen", form.week.0.clone());
|
||||
map.insert("Shirt_Size", form.shirt.0.clone());
|
||||
map.insert("Registration", form.registration.0.clone());
|
||||
map.insert("Health_Form", form.health_form.0.clone());
|
||||
map
|
||||
}
|
||||
}
|
||||
|
@ -292,19 +295,21 @@ pub async fn camp_form(MultipartForm(form): MultipartForm<CampForm>) -> HttpResp
|
|||
}
|
||||
}
|
||||
|
||||
async fn store_camp_form(map: HashMap<i32, String>) -> Result<()> {
|
||||
async fn store_camp_form(map: HashMap<&str, String>) -> Result<Response> {
|
||||
let request = Client::new();
|
||||
let mut json = HashMap::new();
|
||||
json.insert("data", map);
|
||||
request
|
||||
.post("https://staff.tfcconnection.org/apps/tables/api/1/tables/5/rows")
|
||||
.basic_auth("chris", Some("2VHeGxeC^Zf9KqFK^G@Pt!zu2q^6@b"))
|
||||
.header("OCS-APIRequest", "true")
|
||||
let mut fields = HashMap::new();
|
||||
fields.insert("fields", map);
|
||||
json.insert("records", vec![fields]);
|
||||
let response = request
|
||||
.post("https://table.tfcconnection.org/api/docs/e8SFoTHpmJuFQsiMhRTXCi/tables/Camp_Data/records")
|
||||
.bearer_auth("b8189d1b315548aa610db2fd3a43177a967cd41f")
|
||||
.header("Content-Type", "application/json")
|
||||
.json(&json)
|
||||
.send()
|
||||
.await?;
|
||||
Ok(())
|
||||
debug!(?response);
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -329,7 +334,7 @@ mod test {
|
|||
grade: Text(String::from("junior")),
|
||||
shirt: Text(String::from("medium")),
|
||||
allergies: Text(String::from("Cool beans")),
|
||||
week: Text(String::from("1")),
|
||||
week: Text(String::from("week1")),
|
||||
registration: Text(String::from("later")),
|
||||
health_form: Text(String::from("I guess")),
|
||||
}
|
||||
|
@ -342,7 +347,7 @@ mod test {
|
|||
let map = HashMap::from(&form);
|
||||
let res = store_camp_form(map).await;
|
||||
match res {
|
||||
Ok(_) => assert!(true),
|
||||
Ok(r) => assert!(r.status().is_success(), "Failed to store: {:?}", r),
|
||||
Err(e) => assert!(false, "Failed storing test: {e}"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use lettre::{
|
|||
Message,
|
||||
};
|
||||
use maud::{html, Markup, DOCTYPE};
|
||||
use reqwest::Client;
|
||||
use reqwest::{Client, Response};
|
||||
use tracing::{error, info};
|
||||
|
||||
use crate::email::send_email;
|
||||
|
@ -75,40 +75,46 @@ struct HealthForm {
|
|||
registration: Text<String>,
|
||||
}
|
||||
|
||||
impl From<&HealthForm> for HashMap<i32, String> {
|
||||
impl From<&HealthForm> for HashMap<&str, String> {
|
||||
fn from(form: &HealthForm) -> Self {
|
||||
let mut map = HashMap::new();
|
||||
map.insert(37, format!("{} {}", form.first_name.0, form.last_name.0));
|
||||
map.insert(
|
||||
38,
|
||||
"Student_Name",
|
||||
format!("{} {}", form.first_name.0, form.last_name.0),
|
||||
);
|
||||
map.insert(
|
||||
"Parent_Name",
|
||||
format!("{} {}", form.parent_first_name.0, form.parent_last_name.0),
|
||||
);
|
||||
map.insert(39, form.birthdate.0.clone());
|
||||
map.insert(40, form.street.0.clone());
|
||||
map.insert(41, form.city.0.clone());
|
||||
map.insert(42, form.state.0.clone());
|
||||
map.insert(43, form.zip.0.clone());
|
||||
map.insert(44, form.parent_cellphone.0.clone());
|
||||
map.insert(45, form.homephone.0.clone());
|
||||
map.insert(46, format!("{} {}", form.contact.0, form.contact_phone.0));
|
||||
map.insert(47, form.doctorname.0.clone());
|
||||
map.insert(48, form.doctorcity.0.clone());
|
||||
map.insert(49, form.doctorphone.0.clone());
|
||||
map.insert(50, form.medical.0.clone());
|
||||
map.insert(51, form.insurance.0.clone());
|
||||
map.insert(52, form.policy_number.0.clone());
|
||||
map.insert(54, form.agreement.0.clone());
|
||||
map.insert("Birthdate", form.birthdate.0.clone());
|
||||
map.insert("Street", form.street.0.clone());
|
||||
map.insert("City", form.city.0.clone());
|
||||
map.insert("State", form.state.0.clone());
|
||||
map.insert("Zipcode", form.zip.0.clone());
|
||||
map.insert("Parent_Phone", form.parent_cellphone.0.clone());
|
||||
map.insert("Homephone", form.homephone.0.clone());
|
||||
map.insert(
|
||||
55,
|
||||
"Emergency_Contact",
|
||||
format!("{} {}", form.contact.0, form.contact_phone.0),
|
||||
);
|
||||
map.insert("Doctor", form.doctorname.0.clone());
|
||||
map.insert("Doctor_City", form.doctorcity.0.clone());
|
||||
map.insert("Doctor_Phone", form.doctorphone.0.clone());
|
||||
map.insert("Medical_Coverage", form.medical.0.clone());
|
||||
map.insert("Insurance_Name", form.insurance.0.clone());
|
||||
map.insert("Policy_Number", form.policy_number.0.clone());
|
||||
map.insert("Agreement", form.agreement.0.clone());
|
||||
map.insert(
|
||||
"Allergies",
|
||||
format!("{} \n {}", form.allergies.0, form.allergies_other.0),
|
||||
);
|
||||
map.insert(56, form.specific_allergies.0.clone());
|
||||
map.insert(57, form.treatment.0.clone());
|
||||
map.insert(58, form.conditions.0.clone());
|
||||
map.insert(59, form.tetanus.0.clone());
|
||||
map.insert(60, form.medication.0.clone());
|
||||
map.insert(61, form.notes.0.clone());
|
||||
map.insert(62, form.swimming.0.clone());
|
||||
map.insert("Specific_Allergies", form.specific_allergies.0.clone());
|
||||
map.insert("Allergic_Treatments", form.treatment.0.clone());
|
||||
map.insert("Conditions", form.conditions.0.clone());
|
||||
map.insert("Tetanus_Shot_Date", form.tetanus.0.clone());
|
||||
map.insert("Medication_Schedule", form.medication.0.clone());
|
||||
map.insert("Other_Notes", form.notes.0.clone());
|
||||
map.insert("Swimming_Ability", form.swimming.0.clone());
|
||||
map
|
||||
}
|
||||
}
|
||||
|
@ -431,22 +437,22 @@ pub async fn health_form(MultipartForm(mut form): MultipartForm<HealthForm>) ->
|
|||
// HttpResponse::Ok().body("hi")
|
||||
}
|
||||
|
||||
async fn store_form(map: HashMap<i32, String>) -> Result<()> {
|
||||
async fn store_form(map: HashMap<&str, String>) -> Result<Response> {
|
||||
let client = Client::new();
|
||||
let mut json = HashMap::new();
|
||||
json.insert("data", map);
|
||||
let mut fields = HashMap::new();
|
||||
fields.insert("fields", map);
|
||||
json.insert("records", vec![fields]);
|
||||
|
||||
let res = client
|
||||
.post("https://staff.tfcconnection.org/ocs/v2.php/apps/tables/api/2/tables/4/rows")
|
||||
.basic_auth("chris", Some("2VHeGxeC^Zf9KqFK^G@Pt!zu2q^6@b"))
|
||||
.header("OCS-APIRequest", "true")
|
||||
.post("https://table.tfcconnection.org/api/docs/e8SFoTHpmJuFQsiMhRTXCi/tables/Health_Data/records")
|
||||
.bearer_auth("b8189d1b315548aa610db2fd3a43177a967cd41f")
|
||||
.header("Content-Type", "application/json")
|
||||
.json(&json)
|
||||
.send()
|
||||
.await?;
|
||||
if res.status().is_success() {
|
||||
let res = res.text().await.unwrap();
|
||||
Ok(())
|
||||
Ok(res)
|
||||
} else {
|
||||
Err(eyre!(
|
||||
"Problem in storing data: {:?}",
|
||||
|
@ -454,3 +460,69 @@ async fn store_form(map: HashMap<i32, String>) -> Result<()> {
|
|||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use actix_web::test;
|
||||
|
||||
fn form() -> HealthForm {
|
||||
HealthForm {
|
||||
first_name: Text("Frodo".into()),
|
||||
last_name: Text("Braggins".into()),
|
||||
parent_first_name: Text("Bilbo".into()),
|
||||
parent_last_name: Text("Braggins".into()),
|
||||
birthdate: Text(String::from("1845-09-12")),
|
||||
street: Text(String::from("1234 Bag End")),
|
||||
city: Text(String::from("The Shire")),
|
||||
state: Text(String::from("Hobbiton")),
|
||||
zip: Text(String::from("88888")),
|
||||
allergies: Text(String::from("Cool beans")),
|
||||
registration: Text(String::from("later")),
|
||||
parent_cellphone: Text(String::from("later")),
|
||||
homephone: Text("test".into()),
|
||||
contact: Text("test".into()),
|
||||
contact_phone: Text("test".into()),
|
||||
doctorname: Text("test".into()),
|
||||
doctorcity: Text("test".into()),
|
||||
doctorphone: Text("test".into()),
|
||||
medical: Text("test".into()),
|
||||
insurance: Text("test".into()),
|
||||
policy_number: Text("test".into()),
|
||||
allergies_other: Text("test".into()),
|
||||
specific_allergies: Text("test".into()),
|
||||
treatment: Text("test".into()),
|
||||
conditions: Text("test".into()),
|
||||
tetanus: Text("test".into()),
|
||||
swimming: Text("test".into()),
|
||||
medication: Text("test".into()),
|
||||
notes: Text("test".into()),
|
||||
agreement: Text("test".into()),
|
||||
file: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn test_nc_post() {
|
||||
let form = form();
|
||||
assert!(!form.first_name.is_empty());
|
||||
let map = HashMap::from(&form);
|
||||
let res = store_form(map).await;
|
||||
match res {
|
||||
Ok(r) => assert!(r.status().is_success(), "Failed to store: {:?}", r),
|
||||
Err(e) => assert!(false, "Failed storing test: {e}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn test_email() {
|
||||
let mut form = form();
|
||||
assert!(!form.first_name.is_empty());
|
||||
match form.send_email() {
|
||||
Ok(m) => {
|
||||
assert!(crate::email::send_email(m).await.is_ok())
|
||||
}
|
||||
Err(e) => assert!(false, "Failed emailing test: {e}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
62
src/main.rs
62
src/main.rs
|
@ -7,7 +7,7 @@ use actix_web::body::MessageBody;
|
|||
use actix_web::dev::{ServiceRequest, ServiceResponse};
|
||||
use actix_web::{web, App, Error, HttpServer};
|
||||
use api::camp_form::camp_form;
|
||||
use api::contact::{self, contact_form};
|
||||
use api::contact::contact_form;
|
||||
use api::health_form::health_form;
|
||||
use api::local_trip_form::local_form;
|
||||
use api::mt_form::mt_form;
|
||||
|
@ -15,6 +15,7 @@ use api::{
|
|||
mt_church_form::mt_church_form, mt_parent_form::mt_parent_form,
|
||||
mt_teacher_form::mt_teacher_form,
|
||||
};
|
||||
use clap::Parser;
|
||||
use color_eyre::eyre::Context;
|
||||
use color_eyre::Result;
|
||||
use sqlx::{Connection, SqliteConnection};
|
||||
|
@ -45,45 +46,64 @@ impl RootSpanBuilder for DomainRootSpanBuilder {
|
|||
fn on_request_end<B: MessageBody>(_span: Span, _outcome: &Result<ServiceResponse<B>, Error>) {}
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(name = "tfcsite", version, about)]
|
||||
struct Cli {
|
||||
#[arg(short, long)]
|
||||
dev: bool,
|
||||
}
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
let site;
|
||||
let temp;
|
||||
let logs;
|
||||
if Cli::parse().dev {
|
||||
site = "./public";
|
||||
logs = "/tmp/tfcsite";
|
||||
temp = "/tmp/tfcsite";
|
||||
} else {
|
||||
site = "../public";
|
||||
logs = "/storage/logs/tfcsite";
|
||||
temp = "/tmp/tfcsite";
|
||||
}
|
||||
|
||||
std::fs::create_dir_all(&logs)?;
|
||||
std::fs::create_dir_all(&temp)?;
|
||||
|
||||
let timer =
|
||||
tracing_subscriber::fmt::time::ChronoLocal::new("%Y-%m-%d_%I:%M:%S%.6f %P".to_owned());
|
||||
let logfile = RollingFileAppender::builder()
|
||||
.rotation(Rotation::DAILY)
|
||||
.filename_prefix("api")
|
||||
.filename_suffix("log")
|
||||
.build(if DEV_MODE {
|
||||
"/tmp/tfcsite"
|
||||
} else {
|
||||
"/storage/logs/tfcsite"
|
||||
})
|
||||
.build(&logs)
|
||||
.expect("Shouldn't");
|
||||
|
||||
let filter = EnvFilter::builder()
|
||||
let file_filter = EnvFilter::builder()
|
||||
.with_default_directive(LevelFilter::WARN.into())
|
||||
.parse_lossy("tfcapi=debug");
|
||||
.parse_lossy("tfcsite=debug");
|
||||
let logfile_layer = tracing_subscriber::fmt::layer()
|
||||
.with_writer(logfile)
|
||||
.with_line_number(true)
|
||||
.with_level(true)
|
||||
.with_target(true)
|
||||
.with_ansi(false)
|
||||
.with_timer(timer.clone());
|
||||
.with_timer(timer.clone())
|
||||
.with_filter(file_filter);
|
||||
|
||||
let stdout_filter = EnvFilter::builder()
|
||||
.with_default_directive(LevelFilter::WARN.into())
|
||||
.parse_lossy("tfcsite=debug");
|
||||
let stdout_layer = tracing_subscriber::fmt::layer()
|
||||
.pretty()
|
||||
.with_line_number(true)
|
||||
.with_target(true)
|
||||
.with_timer(timer)
|
||||
.with_filter(filter);
|
||||
let filter = EnvFilter::builder()
|
||||
.with_default_directive(LevelFilter::WARN.into())
|
||||
.parse_lossy("tfcapi=debug");
|
||||
let subscriber = tracing_subscriber::registry()
|
||||
.with(logfile_layer.with_filter(filter).and_then(stdout_layer));
|
||||
let _ = tracing::subscriber::set_global_default(subscriber).wrap_err("Tracing broked");
|
||||
.with_filter(stdout_filter);
|
||||
|
||||
std::fs::create_dir_all("/tmp/tfcsite")?;
|
||||
let subscriber = tracing_subscriber::registry().with(logfile_layer.and_then(stdout_layer));
|
||||
let _ = tracing::subscriber::set_global_default(subscriber).wrap_err("Tracing broked");
|
||||
|
||||
info!("starting HTTP server at http://localhost:4242");
|
||||
|
||||
|
@ -96,11 +116,7 @@ async fn main() -> std::io::Result<()> {
|
|||
App::new()
|
||||
.app_data(data.clone())
|
||||
.wrap(TracingLogger::<DomainRootSpanBuilder>::new())
|
||||
.app_data(TempFileConfig::default().directory(if DEV_MODE {
|
||||
"/tmp/tfcsite"
|
||||
} else {
|
||||
"/storage/logs/tfcsite"
|
||||
}))
|
||||
.app_data(TempFileConfig::default().directory(&temp))
|
||||
.service(mt_form)
|
||||
.service(health_form)
|
||||
.service(mt_parent_form)
|
||||
|
@ -109,7 +125,7 @@ async fn main() -> std::io::Result<()> {
|
|||
.service(local_form)
|
||||
.service(camp_form)
|
||||
.service(contact_form)
|
||||
.service(Files::new("/", "./public").index_file("index.html"))
|
||||
.service(Files::new("/", &site).index_file("index.html"))
|
||||
})
|
||||
.bind(("localhost", 4242))?
|
||||
.workers(4)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue