From be61af2b05b66ce75157217f10a3f5e79324d91b Mon Sep 17 00:00:00 2001 From: Sebastian Pravda Date: Wed, 23 Nov 2022 16:07:55 +0100 Subject: [PATCH] refactor: export csv in core/ - feat: export candidate's application id --- Cargo.lock | 2 +- cli/Cargo.toml | 1 - cli/src/main.rs | 29 +++++++++++----------------- core/Cargo.toml | 3 +++ core/src/database/query/candidate.rs | 3 +-- core/src/error.rs | 8 +++++++- core/src/lib.rs | 10 ++++++---- 7 files changed, 29 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6397fad..17eda9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2040,7 +2040,6 @@ name = "portfolio-cli" version = "0.1.0" dependencies = [ "clap 4.0.23", - "csv", "portfolio-core", "portfolio-entity", "sea-orm", @@ -2060,6 +2059,7 @@ dependencies = [ "async_zip", "base64", "chrono", + "csv", "dotenv", "futures", "infer", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 7094fb6..2a327db 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -6,7 +6,6 @@ publish = false [dependencies] url = "^2.3" -csv = "^1.1" clap = { version = "^4.0", features = ["cargo"] } portfolio-entity = { path = "../entity" } diff --git a/cli/src/main.rs b/cli/src/main.rs index 8255e91..867a206 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,3 +1,4 @@ +use std::error::Error; use std::path::PathBuf; use clap::{arg, ArgAction, command, Command, value_parser}; @@ -138,10 +139,14 @@ async fn main() -> Result<(), Box> { key.to_string() }, (_, Some(password)) => { - let admin_id = sub_matches.get_one::("id").unwrap().parse::().unwrap(); + let admin_id = if let Some(s) = sub_matches.get_one::("admin_id") { + s.parse::().unwrap() + } else { + return Err("Admin ID required")?; + }; let admin = Query::find_admin_by_id(&db, admin_id) .await - .map_err(|e| format!("Admin {} not found", admin_id))? + .map_err(|e| format!("Admin {} not found: {}", admin_id, e))? .ok_or("Admin not found")?; crypto::decrypt_password( admin.private_key, @@ -150,25 +155,13 @@ async fn main() -> Result<(), Box> { }, _ => { - unreachable!("Either key or password must be provided"); + return Err("Either key or password must be provided")?; } }; - + let output = sub_matches.get_one::("output").unwrap(); - let mut csv = csv::Writer::from_path(output)?; - - let candidates_with_parents = Query::list_all_candidates_with_parents(&db).await?; - for candidate in candidates_with_parents { - let application = candidate.application; - - if let Ok(enc_details) = EncryptedApplicationDetails::try_from(candidate) { - let details = enc_details.decrypt(key.to_string()).await?; - csv.serialize(details)?; - } else { - println!("Failed to decrypt candidate {} (Candidate data not set)", application); - } - } - csv.flush()?; + let csv = portfolio_core::utils::csv::export(&db, key).await?; + tokio::fs::write(output, csv).await?; }, Some(("portfolio", sub_matches)) => { todo!() diff --git a/core/Cargo.toml b/core/Cargo.toml index b2f28bc..84a8895 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -12,6 +12,9 @@ portfolio-entity = { path = "../entity" } # serde serde = { version = "^1.0", features = ["derive"] } +# csv +csv = "1.1" + # error thiserror = "^1.0" diff --git a/core/src/database/query/candidate.rs b/core/src/database/query/candidate.rs index fd60071..ff5427f 100644 --- a/core/src/database/query/candidate.rs +++ b/core/src/database/query/candidate.rs @@ -19,12 +19,11 @@ pub struct CandidateParentResult { pub parent_surname: Option, } -#[derive(FromQueryResult, Serialize)] +#[derive(FromQueryResult, Serialize, Default)] pub struct CandidateWithParent { // TODO: use this instead of (Candidate, Parent)??? pub application: i32, pub name: Option, pub surname: Option, - pub birth_surname: Option, pub birthplace: Option, pub birthdate: Option, pub address: Option, diff --git a/core/src/error.rs b/core/src/error.rs index 8c34271..be230b0 100644 --- a/core/src/error.rs +++ b/core/src/error.rs @@ -59,7 +59,11 @@ pub enum ServiceError { #[error("Portfolio is incomplete")] IncompletePortfolio, #[error("Zip error")] - ZipError(#[from] async_zip::error::ZipError) + ZipError(#[from] async_zip::error::ZipError), + #[error("Csv error")] + CsvError(#[from] csv::Error), + #[error("Csv into inner error")] + CsvIntoInnerError, } impl ServiceError { @@ -94,6 +98,8 @@ impl ServiceError { //TODO: Correct code ServiceError::IncompletePortfolio => 406, ServiceError::ZipError(_) => 500, + ServiceError::CsvError(_) => 500, + ServiceError::CsvIntoInnerError => 500, } } } diff --git a/core/src/lib.rs b/core/src/lib.rs index 579ddcd..dd3e5c8 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -1,3 +1,8 @@ +pub use sea_orm; + +pub use database::mutation::*; +pub use database::query::*; + pub mod database; pub mod crypto; pub mod filetype; @@ -6,8 +11,5 @@ pub mod error; pub mod candidate_details; pub mod util; pub mod responses; +pub mod utils; -pub use database::mutation::*; -pub use database::query::*; - -pub use sea_orm;