mirror of
https://github.com/danbulant/Portfolio
synced 2026-07-05 11:00:56 +00:00
refactor: export csv in core/
- feat: export candidate's application id
This commit is contained in:
parent
b2cd902e98
commit
be61af2b05
7 changed files with 29 additions and 27 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -2040,7 +2040,6 @@ name = "portfolio-cli"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 4.0.23",
|
"clap 4.0.23",
|
||||||
"csv",
|
|
||||||
"portfolio-core",
|
"portfolio-core",
|
||||||
"portfolio-entity",
|
"portfolio-entity",
|
||||||
"sea-orm",
|
"sea-orm",
|
||||||
|
|
@ -2060,6 +2059,7 @@ dependencies = [
|
||||||
"async_zip",
|
"async_zip",
|
||||||
"base64",
|
"base64",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"csv",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"futures",
|
"futures",
|
||||||
"infer",
|
"infer",
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
url = "^2.3"
|
url = "^2.3"
|
||||||
csv = "^1.1"
|
|
||||||
clap = { version = "^4.0", features = ["cargo"] }
|
clap = { version = "^4.0", features = ["cargo"] }
|
||||||
|
|
||||||
portfolio-entity = { path = "../entity" }
|
portfolio-entity = { path = "../entity" }
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::error::Error;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use clap::{arg, ArgAction, command, Command, value_parser};
|
use clap::{arg, ArgAction, command, Command, value_parser};
|
||||||
|
|
@ -138,10 +139,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
key.to_string()
|
key.to_string()
|
||||||
},
|
},
|
||||||
(_, Some(password)) => {
|
(_, Some(password)) => {
|
||||||
let admin_id = sub_matches.get_one::<String>("id").unwrap().parse::<i32>().unwrap();
|
let admin_id = if let Some(s) = sub_matches.get_one::<String>("admin_id") {
|
||||||
|
s.parse::<i32>().unwrap()
|
||||||
|
} else {
|
||||||
|
return Err("Admin ID required")?;
|
||||||
|
};
|
||||||
let admin = Query::find_admin_by_id(&db, admin_id)
|
let admin = Query::find_admin_by_id(&db, admin_id)
|
||||||
.await
|
.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")?;
|
.ok_or("Admin not found")?;
|
||||||
crypto::decrypt_password(
|
crypto::decrypt_password(
|
||||||
admin.private_key,
|
admin.private_key,
|
||||||
|
|
@ -150,25 +155,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!("Either key or password must be provided");
|
return Err("Either key or password must be provided")?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let output = sub_matches.get_one::<PathBuf>("output").unwrap();
|
let output = sub_matches.get_one::<PathBuf>("output").unwrap();
|
||||||
let mut csv = csv::Writer::from_path(output)?;
|
let csv = portfolio_core::utils::csv::export(&db, key).await?;
|
||||||
|
tokio::fs::write(output, csv).await?;
|
||||||
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()?;
|
|
||||||
},
|
},
|
||||||
Some(("portfolio", sub_matches)) => {
|
Some(("portfolio", sub_matches)) => {
|
||||||
todo!()
|
todo!()
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ portfolio-entity = { path = "../entity" }
|
||||||
# serde
|
# serde
|
||||||
serde = { version = "^1.0", features = ["derive"] }
|
serde = { version = "^1.0", features = ["derive"] }
|
||||||
|
|
||||||
|
# csv
|
||||||
|
csv = "1.1"
|
||||||
|
|
||||||
# error
|
# error
|
||||||
|
|
||||||
thiserror = "^1.0"
|
thiserror = "^1.0"
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,11 @@ pub struct CandidateParentResult {
|
||||||
pub parent_surname: Option<String>,
|
pub parent_surname: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromQueryResult, Serialize)]
|
#[derive(FromQueryResult, Serialize, Default)]
|
||||||
pub struct CandidateWithParent { // TODO: use this instead of (Candidate, Parent)???
|
pub struct CandidateWithParent { // TODO: use this instead of (Candidate, Parent)???
|
||||||
pub application: i32,
|
pub application: i32,
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub surname: Option<String>,
|
pub surname: Option<String>,
|
||||||
pub birth_surname: Option<String>,
|
|
||||||
pub birthplace: Option<String>,
|
pub birthplace: Option<String>,
|
||||||
pub birthdate: Option<String>,
|
pub birthdate: Option<String>,
|
||||||
pub address: Option<String>,
|
pub address: Option<String>,
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,11 @@ pub enum ServiceError {
|
||||||
#[error("Portfolio is incomplete")]
|
#[error("Portfolio is incomplete")]
|
||||||
IncompletePortfolio,
|
IncompletePortfolio,
|
||||||
#[error("Zip error")]
|
#[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 {
|
impl ServiceError {
|
||||||
|
|
@ -94,6 +98,8 @@ impl ServiceError {
|
||||||
//TODO: Correct code
|
//TODO: Correct code
|
||||||
ServiceError::IncompletePortfolio => 406,
|
ServiceError::IncompletePortfolio => 406,
|
||||||
ServiceError::ZipError(_) => 500,
|
ServiceError::ZipError(_) => 500,
|
||||||
|
ServiceError::CsvError(_) => 500,
|
||||||
|
ServiceError::CsvIntoInnerError => 500,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
pub use sea_orm;
|
||||||
|
|
||||||
|
pub use database::mutation::*;
|
||||||
|
pub use database::query::*;
|
||||||
|
|
||||||
pub mod database;
|
pub mod database;
|
||||||
pub mod crypto;
|
pub mod crypto;
|
||||||
pub mod filetype;
|
pub mod filetype;
|
||||||
|
|
@ -6,8 +11,5 @@ pub mod error;
|
||||||
pub mod candidate_details;
|
pub mod candidate_details;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
pub mod responses;
|
pub mod responses;
|
||||||
|
pub mod utils;
|
||||||
|
|
||||||
pub use database::mutation::*;
|
|
||||||
pub use database::query::*;
|
|
||||||
|
|
||||||
pub use sea_orm;
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue