diff --git a/Cargo.lock b/Cargo.lock index 4102864..567591b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -123,6 +123,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + [[package]] name = "bytes" version = "1.5.0" @@ -187,6 +193,22 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + [[package]] name = "crc32fast" version = "1.3.2" @@ -202,6 +224,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "fastrand" version = "2.0.1" @@ -224,6 +256,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -489,6 +536,12 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + [[package]] name = "lock_api" version = "0.4.11" @@ -550,6 +603,24 @@ dependencies = [ "tokio", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "num_cpus" version = "1.16.0" @@ -575,6 +646,50 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "openssl" +version = "0.10.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -616,6 +731,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -676,7 +797,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -728,6 +849,19 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustix" +version = "0.38.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + [[package]] name = "rustls" version = "0.22.2" @@ -765,12 +899,44 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.196" @@ -883,6 +1049,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "thiserror" version = "1.0.56" @@ -1030,6 +1208,7 @@ dependencies = [ "flate2", "hootbin", "log", + "native-tls", "once_cell", "rustls", "rustls-pki-types", @@ -1057,6 +1236,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "want" version = "0.3.1" @@ -1215,11 +1400,12 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "xgt" -version = "0.1.0" +version = "0.3.0" dependencies = [ "anyhow", "clap", "mockito", + "native-tls", "serde", "serde_json", "ureq", diff --git a/Cargo.toml b/Cargo.toml index ddad48e..ea00ad9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "xgt" -version = "0.1.0" +version = "0.3.0" edition = "2021" authors = ["Anicet Ebou "] description = "xgt enables efficient querying and parsing of GTDB data" @@ -14,7 +14,8 @@ anyhow = "1.0.69" clap = "4.1.8" serde = { version ="1.0.153", features = ["derive"] } serde_json = "1.0.94" -ureq = { version = "2.6.2", features = ["json"] } +ureq = { version = "2.6.2", features = ["json", "native-tls"] } +native-tls = "0.2" [dev-dependencies] mockito = "1.0.2" diff --git a/README.md b/README.md index 8be748d..e61d50d 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,12 @@ xgt taxon --search --partial g__Escherichia Full help is available from `xgt --help`. +## Certificate verification + +`xgt` through `ureq` performs peer SSL certificate verification by default. +To tell `xgt` to _not_ verify the peer, use `-k/--insecure` option. +Currently (as of Apr 28, 2024), you should add this options to your command to get the desired result as the GTDB API have a certificate issue. + ### Minimum supported Rust version `xgt` minimum [Rust](https://www.rust-lang.org/) version is 1.70.0. diff --git a/src/app.rs b/src/app.rs index 42ac3f1..6757b6b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -85,6 +85,13 @@ pub fn build_app() -> Command { .long("type") .action(ArgAction::SetTrue) .help("Search NCBI type material only"), + ) + .arg( + Arg::new("insecure") + .short('k') + .long("insecure") + .help("Disable SSL certificate verification") + .action(ArgAction::SetTrue), ), ) .subcommand( @@ -131,6 +138,13 @@ pub fn build_app() -> Command { .help("Output raw JSON") .value_name("FILE") .value_parser(is_existing), + ) + .arg( + Arg::new("insecure") + .short('k') + .long("insecure") + .help("Disable SSL certificate verification") + .action(ArgAction::SetTrue), ), ) .subcommand( @@ -198,6 +212,13 @@ pub fn build_app() -> Command { .long("reps") .action(ArgAction::SetTrue) .help("Set taxon V genomes search to lookup reps seqs only"), + ) + .arg( + Arg::new("insecure") + .short('k') + .long("insecure") + .help("Disable SSL certificate verification") + .action(ArgAction::SetTrue), ), ) } diff --git a/src/cmd/genome.rs b/src/cmd/genome.rs index 16b95a9..a95f37c 100644 --- a/src/cmd/genome.rs +++ b/src/cmd/genome.rs @@ -1,3 +1,4 @@ +use super::utils; use super::utils::GenomeArgs; use crate::api::genome_api::GenomeAPI; use crate::api::genome_api::GenomeRequestType; @@ -179,7 +180,7 @@ pub fn get_genome_metadata(args: GenomeArgs) -> Result<()> { .collect(); let raw = args.get_raw(); - let agent: Agent = ureq::AgentBuilder::new().build(); + let agent: Agent = utils::get_agent(args.get_disable_certificate_verification())?; for accession in genome_api { let request_url = accession.request(GenomeRequestType::Metadata); @@ -243,7 +244,7 @@ pub fn get_genome_card(args: GenomeArgs) -> Result<()> { .collect(); let raw = args.get_raw(); - let agent: Agent = ureq::AgentBuilder::new().build(); + let agent: Agent = utils::get_agent(args.get_disable_certificate_verification())?; for accession in genome_api { let request_url = accession.request(GenomeRequestType::Card); @@ -254,7 +255,7 @@ pub fn get_genome_card(args: GenomeArgs) -> Result<()> { bail!("The server returned an unexpected status code ({})", code); } Err(_) => { - bail!("There was an error making the request or receiving the response."); + bail!("There was an error making the request or receiving the response"); } }; @@ -307,7 +308,7 @@ pub fn get_genome_taxon_history(args: GenomeArgs) -> Result<()> { .collect(); let raw = args.get_raw(); - let agent: Agent = ureq::AgentBuilder::new().build(); + let agent: Agent = utils::get_agent(args.get_disable_certificate_verification())?; for accession in genome_api { let request_url = accession.request(GenomeRequestType::TaxonHistory); @@ -375,8 +376,10 @@ mod tests { accession: vec!["GCA_001512625.1".to_owned()], raw: false, output: None, + disable_certificate_verification: true, }; - assert!(get_genome_card(args).is_ok()); + println!("{:?}", get_genome_card(args.clone())); + assert!(get_genome_card(args.clone()).is_ok()); } #[test] @@ -385,6 +388,7 @@ mod tests { accession: vec!["GCA_001512625.1".to_owned()], raw: true, output: None, + disable_certificate_verification: true, }; assert!(get_genome_card(args).is_ok()); } @@ -395,6 +399,7 @@ mod tests { accession: vec!["GCA_001512625.1".to_owned()], raw: false, output: None, + disable_certificate_verification: true, }; assert!(get_genome_metadata(args).is_ok()); } @@ -405,6 +410,7 @@ mod tests { accession: vec!["GCA_001512625.1".to_owned()], raw: false, output: Some(String::from("genome")), + disable_certificate_verification: true, }; assert!(get_genome_metadata(args).is_ok()); std::fs::remove_file(Path::new("genome")).unwrap(); @@ -416,6 +422,7 @@ mod tests { accession: vec!["GCA_001512625.1".to_owned()], raw: true, output: Some(String::from("genome1")), + disable_certificate_verification: true, }; assert!(get_genome_metadata(args).is_ok()); std::fs::remove_file(Path::new("genome1")).unwrap(); @@ -427,6 +434,7 @@ mod tests { accession: vec!["GCA_001512625.1".to_owned()], raw: true, output: Some(String::from("genome2")), + disable_certificate_verification: true, }; assert!(get_genome_card(args).is_ok()); std::fs::remove_file(Path::new("genome2")).unwrap(); @@ -438,6 +446,7 @@ mod tests { accession: vec!["GCA_001512625.1".to_owned()], raw: false, output: Some(String::from("genome3")), + disable_certificate_verification: true, }; assert!(get_genome_card(args).is_ok()); std::fs::remove_file(Path::new("genome3")).unwrap(); @@ -449,6 +458,7 @@ mod tests { accession: vec!["GCA_001512625.1".to_owned()], raw: true, output: Some(String::from("genome4")), + disable_certificate_verification: true, }; assert!(get_genome_taxon_history(args).is_ok()); std::fs::remove_file(Path::new("genome4")).unwrap(); @@ -460,6 +470,7 @@ mod tests { accession: vec!["GCA_001512625.1".to_owned()], raw: false, output: Some(String::from("genome5")), + disable_certificate_verification: true, }; assert!(get_genome_taxon_history(args).is_ok()); std::fs::remove_file(Path::new("genome5")).unwrap(); @@ -471,6 +482,7 @@ mod tests { accession: vec!["GCA_001512625.1".to_owned()], raw: true, output: None, + disable_certificate_verification: true, }; assert!(get_genome_metadata(args).is_ok()); } @@ -481,6 +493,7 @@ mod tests { accession: vec!["GCA_001512625.1".to_owned()], raw: false, output: None, + disable_certificate_verification: true, }; assert!(get_genome_taxon_history(args).is_ok()); } @@ -491,6 +504,7 @@ mod tests { accession: vec!["GCA_001512625.1".to_owned()], raw: true, output: None, + disable_certificate_verification: true, }; assert!(get_genome_taxon_history(args).is_ok()); } @@ -501,6 +515,7 @@ mod tests { accession: vec!["".to_owned()], raw: true, output: None, + disable_certificate_verification: true, }; assert!(get_genome_card(args).is_err()) @@ -512,6 +527,7 @@ mod tests { accession: vec!["&&&&^^^^^||||".to_owned()], raw: true, output: None, + disable_certificate_verification: true, }; assert!( get_genome_card(args).is_err(), diff --git a/src/cmd/search.rs b/src/cmd/search.rs index 6e52e07..5b680f4 100644 --- a/src/cmd/search.rs +++ b/src/cmd/search.rs @@ -24,52 +24,27 @@ impl SearchResult { anyhow!("Failed to perform exact match as gtdb taxonomy is a null field") })?; - let res = match level { - "domain" => tax - .replace("d__", "") - .split("; ") - .next() - .unwrap_or("") - .to_string(), - "phylum" => tax - .replace("p__", "") - .split("; ") - .nth(1) - .unwrap_or("") - .to_string(), - "class" => tax - .replace("c__", "") - .split("; ") - .nth(2) - .unwrap_or("") - .to_string(), - "order" => tax - .replace("o__", "") - .split("; ") - .nth(3) - .unwrap_or("") - .to_string(), - "family" => tax - .replace("f__", "") - .split("; ") - .nth(4) - .unwrap_or("") - .to_string(), - "genus" => tax - .replace("g__", "") - .split("; ") - .nth(5) - .unwrap_or("") - .to_string(), - "species" => tax - .replace("s__", "") - .split("; ") - .nth(6) - .unwrap_or("") - .to_string(), - &_ => unreachable!("all fields have been taken into account"), + let index = match level { + "domain" => 0, + "phylum" => 1, + "class" => 2, + "order" => 3, + "family" => 4, + "genus" => 5, + "species" => 6, + _ => return Err(anyhow!("Invalid level specified")), }; + let res = tax + .split("; ") + .nth(index) + .unwrap_or("") + .split("__") + .nth(1) + .unwrap_or("") + .trim_start_matches(char::is_whitespace) + .to_string(); + Ok(res) } } @@ -103,7 +78,7 @@ pub fn partial_search(args: utils::SearchArgs) -> Result<()> { let needles = args.get_needle(); - let agent: Agent = ureq::AgentBuilder::new().build(); + let agent: Agent = utils::get_agent(args.get_disable_certificate_verification())?; for needle in needles { let search_api = SearchAPI::from(&needle, &args); @@ -178,7 +153,7 @@ pub fn exact_search(args: utils::SearchArgs) -> Result<()> { let needles = args.get_needle(); - let agent: Agent = ureq::AgentBuilder::new().build(); + let agent: Agent = utils::get_agent(args.get_disable_certificate_verification())?; for needle in needles { let oneedle = needle.clone(); @@ -332,6 +307,7 @@ mod tests { let mut args = utils::SearchArgs::new(); args.set_needle(vec!["Azorhizobium".to_string()]); args.set_count(true); + args.set_disable_certificate_verification(true); args.set_out(Some("test.txt".to_string())); let res = exact_search(args.clone()); assert!(res.is_ok()); @@ -345,6 +321,7 @@ mod tests { let mut args = utils::SearchArgs::new(); args.set_needle(vec!["Azorhizobium".to_string()]); args.set_count(true); + args.set_disable_certificate_verification(true); args.set_out(Some("test1.txt".to_string())); let res = partial_search(args.clone()); assert!(res.is_ok()); @@ -358,6 +335,7 @@ mod tests { let mut args = utils::SearchArgs::new(); args.set_needle(vec!["Azorhizobium".to_string()]); args.set_id(true); + args.set_disable_certificate_verification(true); args.set_out(Some("test2.txt".to_string())); let res = exact_search(args.clone()); assert!(res.is_ok()); @@ -372,6 +350,7 @@ mod tests { args.set_needle(vec!["Azorhizobium".to_string()]); args.set_id(true); args.set_out(Some("test3.txt".to_string())); + args.set_disable_certificate_verification(true); let res = partial_search(args.clone()); assert!(res.is_ok()); let expected = std::fs::read_to_string("test3.txt").unwrap(); @@ -386,6 +365,7 @@ mod tests { args.set_raw(true); args.set_id(true); args.set_out(Some("test4.txt".to_string())); + args.set_disable_certificate_verification(true); let res = exact_search(args.clone()); assert!(res.is_ok()); let expected = std::fs::read_to_string("test4.txt").unwrap(); @@ -400,6 +380,7 @@ mod tests { args.set_raw(true); args.set_id(true); args.set_out(Some("test5.txt".to_string())); + args.set_disable_certificate_verification(true); let res = partial_search(args.clone()); assert!(res.is_ok()); let expected = std::fs::read_to_string("test5.txt").unwrap(); @@ -413,10 +394,11 @@ mod tests { args.set_needle(vec!["Azorhizobium".to_string()]); args.set_raw(true); args.set_out(Some("test6.txt".to_string())); + args.set_disable_certificate_verification(true); let res = exact_search(args.clone()); assert!(res.is_ok()); let expected = std::fs::read_to_string("test6.txt").unwrap(); - let actual = r#"{"gid":"GCA_023405075.1","accession":"GCA_023405075.1","ncbiOrgName":"Proteobacteria bacterium","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__; o__; f__; g__; s__","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":false}{"gid":"GCA_023448105.1","accession":"GCA_023448105.1","ncbiOrgName":"Proteobacteria bacterium","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__; o__; f__; g__; s__","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":false}{"gid":"GCF_000010525.1","accession":"GCF_000010525.1","ncbiOrgName":"Azorhizobium caulinodans ORS 571","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","isGtdbSpeciesRep":true,"isNcbiTypeMaterial":true}{"gid":"GCF_000473085.1","accession":"GCF_000473085.1","ncbiOrgName":"Azorhizobium doebereinerae UFLA1-100","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium doebereinerae","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium doebereinerae","isGtdbSpeciesRep":true,"isNcbiTypeMaterial":true}{"gid":"GCF_004364705.1","accession":"GCF_004364705.1","ncbiOrgName":"Azorhizobium sp. AG788","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":false}{"gid":"GCF_014635325.1","accession":"GCF_014635325.1","ncbiOrgName":"Azorhizobium oxalatiphilum","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium oxalatiphilum","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium oxalatiphilum","isGtdbSpeciesRep":true,"isNcbiTypeMaterial":true}"#; + let actual = r#"{"gid":"GCA_023405075.1","accession":"GCA_023405075.1","ncbiOrgName":"Pseudomonadota bacterium","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__; o__; f__; g__; s__","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":true}{"gid":"GCA_023448105.1","accession":"GCA_023448105.1","ncbiOrgName":"Pseudomonadota bacterium","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__; o__; f__; g__; s__","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":true}{"gid":"GCF_000010525.1","accession":"GCF_000010525.1","ncbiOrgName":"Azorhizobium caulinodans ORS 571","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","isGtdbSpeciesRep":true,"isNcbiTypeMaterial":true}{"gid":"GCF_000473085.1","accession":"GCF_000473085.1","ncbiOrgName":"Azorhizobium doebereinerae UFLA1-100","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium doebereinerae","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium doebereinerae","isGtdbSpeciesRep":true,"isNcbiTypeMaterial":true}{"gid":"GCF_004364705.1","accession":"GCF_004364705.1","ncbiOrgName":"Azorhizobium sp. AG788","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":true}{"gid":"GCF_014635325.1","accession":"GCF_014635325.1","ncbiOrgName":"Azorhizobium oxalatiphilum","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium oxalatiphilum","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium oxalatiphilum","isGtdbSpeciesRep":true,"isNcbiTypeMaterial":true}"#; assert_eq!(actual, expected); std::fs::remove_file("test6.txt").unwrap(); } @@ -427,10 +409,11 @@ mod tests { args.set_needle(vec!["Azorhizobium".to_string()]); args.set_raw(true); args.set_out(Some("test7.txt".to_string())); + args.set_disable_certificate_verification(true); let res = partial_search(args.clone()); assert!(res.is_ok()); let expected = std::fs::read_to_string("test7.txt").unwrap(); - let actual = r#"{"gid":"GCA_002279595.1","accession":"GCA_002279595.1","ncbiOrgName":"Azorhizobium sp. 12-66-6","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__","gtdbTaxonomy":"Undefined (Failed Quality Check)","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":false}{"gid":"GCA_002280795.1","accession":"GCA_002280795.1","ncbiOrgName":"Azorhizobium sp. 32-67-21","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Aquabacter; s__Aquabacter sp002279855","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":false}{"gid":"GCA_002280945.1","accession":"GCA_002280945.1","ncbiOrgName":"Azorhizobium sp. 35-67-5","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__","gtdbTaxonomy":"Undefined (Failed Quality Check)","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":false}{"gid":"GCA_002281175.1","accession":"GCA_002281175.1","ncbiOrgName":"Azorhizobium sp. 35-67-15","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__","gtdbTaxonomy":"Undefined (Failed Quality Check)","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":false}{"gid":"GCA_002282175.1","accession":"GCA_002282175.1","ncbiOrgName":"Azorhizobium sp. 39-67-5","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__","gtdbTaxonomy":"Undefined (Failed Quality Check)","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":false}{"gid":"GCA_023405075.1","accession":"GCA_023405075.1","ncbiOrgName":"Proteobacteria bacterium","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__; o__; f__; g__; s__","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":false}{"gid":"GCA_023448105.1","accession":"GCA_023448105.1","ncbiOrgName":"Proteobacteria bacterium","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__; o__; f__; g__; s__","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":false}{"gid":"GCF_000010525.1","accession":"GCF_000010525.1","ncbiOrgName":"Azorhizobium caulinodans ORS 571","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","isGtdbSpeciesRep":true,"isNcbiTypeMaterial":true}{"gid":"GCF_000473085.1","accession":"GCF_000473085.1","ncbiOrgName":"Azorhizobium doebereinerae UFLA1-100","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium doebereinerae","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium doebereinerae","isGtdbSpeciesRep":true,"isNcbiTypeMaterial":true}{"gid":"GCF_004364705.1","accession":"GCF_004364705.1","ncbiOrgName":"Azorhizobium sp. AG788","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":false}{"gid":"GCF_014635325.1","accession":"GCF_014635325.1","ncbiOrgName":"Azorhizobium oxalatiphilum","ncbiTaxonomy":"d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium oxalatiphilum","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium oxalatiphilum","isGtdbSpeciesRep":true,"isNcbiTypeMaterial":true}"#; + let actual = r#"{"gid":"GCA_002279595.1","accession":"GCA_002279595.1","ncbiOrgName":"Azorhizobium sp. 12-66-6","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__","gtdbTaxonomy":"Undefined (Failed Quality Check)","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":true}{"gid":"GCA_002280795.1","accession":"GCA_002280795.1","ncbiOrgName":"Azorhizobium sp. 32-67-21","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Aquabacter; s__Aquabacter sp002279855","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":true}{"gid":"GCA_002280945.1","accession":"GCA_002280945.1","ncbiOrgName":"Azorhizobium sp. 35-67-5","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__","gtdbTaxonomy":"Undefined (Failed Quality Check)","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":true}{"gid":"GCA_002281175.1","accession":"GCA_002281175.1","ncbiOrgName":"Azorhizobium sp. 35-67-15","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__","gtdbTaxonomy":"Undefined (Failed Quality Check)","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":true}{"gid":"GCA_002282175.1","accession":"GCA_002282175.1","ncbiOrgName":"Azorhizobium sp. 39-67-5","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__","gtdbTaxonomy":"Undefined (Failed Quality Check)","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":true}{"gid":"GCA_023405075.1","accession":"GCA_023405075.1","ncbiOrgName":"Pseudomonadota bacterium","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__; o__; f__; g__; s__","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":true}{"gid":"GCA_023448105.1","accession":"GCA_023448105.1","ncbiOrgName":"Pseudomonadota bacterium","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__; o__; f__; g__; s__","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":true}{"gid":"GCF_000010525.1","accession":"GCF_000010525.1","ncbiOrgName":"Azorhizobium caulinodans ORS 571","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","isGtdbSpeciesRep":true,"isNcbiTypeMaterial":true}{"gid":"GCF_000473085.1","accession":"GCF_000473085.1","ncbiOrgName":"Azorhizobium doebereinerae UFLA1-100","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium doebereinerae","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium doebereinerae","isGtdbSpeciesRep":true,"isNcbiTypeMaterial":true}{"gid":"GCF_004364705.1","accession":"GCF_004364705.1","ncbiOrgName":"Azorhizobium sp. AG788","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans","isGtdbSpeciesRep":false,"isNcbiTypeMaterial":true}{"gid":"GCF_014635325.1","accession":"GCF_014635325.1","ncbiOrgName":"Azorhizobium oxalatiphilum","ncbiTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium oxalatiphilum","gtdbTaxonomy":"d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium oxalatiphilum","isGtdbSpeciesRep":true,"isNcbiTypeMaterial":true}"#; assert_eq!(actual, expected); std::fs::remove_file("test7.txt").unwrap(); } @@ -441,6 +424,7 @@ mod tests { args.set_needle(vec!["Azorhizobium doebereinerae".to_string()]); args.set_level("species".to_string()); args.set_out(Some("test8.txt".to_string())); + args.set_disable_certificate_verification(true); let res = exact_search(args.clone()); assert!(res.is_ok()); let expected = std::fs::read_to_string("test8.txt").unwrap(); @@ -448,7 +432,7 @@ mod tests { "gid": "GCF_000473085.1", "accession": "GCF_000473085.1", "ncbiOrgName": "Azorhizobium doebereinerae UFLA1-100", - "ncbiTaxonomy": "d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium doebereinerae", + "ncbiTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium doebereinerae", "gtdbTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium doebereinerae", "isGtdbSpeciesRep": true, "isNcbiTypeMaterial": true @@ -463,6 +447,7 @@ mod tests { args.set_needle(vec!["Azorhizobium doebereinerae".to_string()]); args.set_level("species".to_string()); args.set_out(Some("test9.txt".to_string())); + args.set_disable_certificate_verification(true); let res = partial_search(args.clone()); assert!(res.is_ok()); let expected = std::fs::read_to_string("test9.txt").unwrap(); @@ -470,63 +455,63 @@ mod tests { "gid": "GCA_002279595.1", "accession": "GCA_002279595.1", "ncbiOrgName": "Azorhizobium sp. 12-66-6", - "ncbiTaxonomy": "d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__", + "ncbiTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__", "gtdbTaxonomy": "Undefined (Failed Quality Check)", "isGtdbSpeciesRep": false, - "isNcbiTypeMaterial": false + "isNcbiTypeMaterial": true }{ "gid": "GCA_002280795.1", "accession": "GCA_002280795.1", "ncbiOrgName": "Azorhizobium sp. 32-67-21", - "ncbiTaxonomy": "d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__", + "ncbiTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__", "gtdbTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Aquabacter; s__Aquabacter sp002279855", "isGtdbSpeciesRep": false, - "isNcbiTypeMaterial": false + "isNcbiTypeMaterial": true }{ "gid": "GCA_002280945.1", "accession": "GCA_002280945.1", "ncbiOrgName": "Azorhizobium sp. 35-67-5", - "ncbiTaxonomy": "d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__", + "ncbiTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__", "gtdbTaxonomy": "Undefined (Failed Quality Check)", "isGtdbSpeciesRep": false, - "isNcbiTypeMaterial": false + "isNcbiTypeMaterial": true }{ "gid": "GCA_002281175.1", "accession": "GCA_002281175.1", "ncbiOrgName": "Azorhizobium sp. 35-67-15", - "ncbiTaxonomy": "d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__", + "ncbiTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__", "gtdbTaxonomy": "Undefined (Failed Quality Check)", "isGtdbSpeciesRep": false, - "isNcbiTypeMaterial": false + "isNcbiTypeMaterial": true }{ "gid": "GCA_002282175.1", "accession": "GCA_002282175.1", "ncbiOrgName": "Azorhizobium sp. 39-67-5", - "ncbiTaxonomy": "d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__", + "ncbiTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__", "gtdbTaxonomy": "Undefined (Failed Quality Check)", "isGtdbSpeciesRep": false, - "isNcbiTypeMaterial": false + "isNcbiTypeMaterial": true }{ "gid": "GCA_023405075.1", "accession": "GCA_023405075.1", - "ncbiOrgName": "Proteobacteria bacterium", - "ncbiTaxonomy": "d__Bacteria; p__Proteobacteria; c__; o__; f__; g__; s__", + "ncbiOrgName": "Pseudomonadota bacterium", + "ncbiTaxonomy": "d__Bacteria; p__Pseudomonadota; c__; o__; f__; g__; s__", "gtdbTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans", "isGtdbSpeciesRep": false, - "isNcbiTypeMaterial": false + "isNcbiTypeMaterial": true }{ "gid": "GCA_023448105.1", "accession": "GCA_023448105.1", - "ncbiOrgName": "Proteobacteria bacterium", - "ncbiTaxonomy": "d__Bacteria; p__Proteobacteria; c__; o__; f__; g__; s__", + "ncbiOrgName": "Pseudomonadota bacterium", + "ncbiTaxonomy": "d__Bacteria; p__Pseudomonadota; c__; o__; f__; g__; s__", "gtdbTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans", "isGtdbSpeciesRep": false, - "isNcbiTypeMaterial": false + "isNcbiTypeMaterial": true }{ "gid": "GCF_000010525.1", "accession": "GCF_000010525.1", "ncbiOrgName": "Azorhizobium caulinodans ORS 571", - "ncbiTaxonomy": "d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans", + "ncbiTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans", "gtdbTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans", "isGtdbSpeciesRep": true, "isNcbiTypeMaterial": true @@ -534,7 +519,7 @@ mod tests { "gid": "GCF_000473085.1", "accession": "GCF_000473085.1", "ncbiOrgName": "Azorhizobium doebereinerae UFLA1-100", - "ncbiTaxonomy": "d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium doebereinerae", + "ncbiTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium doebereinerae", "gtdbTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium doebereinerae", "isGtdbSpeciesRep": true, "isNcbiTypeMaterial": true @@ -542,7 +527,7 @@ mod tests { "gid": "GCF_003989665.1", "accession": "GCF_003989665.1", "ncbiOrgName": "Azospirillum doebereinerae", - "ncbiTaxonomy": "d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Rhodospirillales; f__Azospirillaceae; g__Azospirillum; s__Azospirillum doebereinerae", + "ncbiTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhodospirillales; f__Azospirillaceae; g__Azospirillum; s__Azospirillum doebereinerae", "gtdbTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Azospirillales; f__Azospirillaceae; g__Azospirillum; s__Azospirillum doebereinerae", "isGtdbSpeciesRep": true, "isNcbiTypeMaterial": true @@ -550,15 +535,15 @@ mod tests { "gid": "GCF_004364705.1", "accession": "GCF_004364705.1", "ncbiOrgName": "Azorhizobium sp. AG788", - "ncbiTaxonomy": "d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__", + "ncbiTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__", "gtdbTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium caulinodans", "isGtdbSpeciesRep": false, - "isNcbiTypeMaterial": false + "isNcbiTypeMaterial": true }{ "gid": "GCF_014635325.1", "accession": "GCF_014635325.1", "ncbiOrgName": "Azorhizobium oxalatiphilum", - "ncbiTaxonomy": "d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium oxalatiphilum", + "ncbiTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Hyphomicrobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium oxalatiphilum", "gtdbTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhizobiales; f__Xanthobacteraceae; g__Azorhizobium; s__Azorhizobium oxalatiphilum", "isGtdbSpeciesRep": true, "isNcbiTypeMaterial": true @@ -566,10 +551,10 @@ mod tests { "gid": "GCF_022214805.1", "accession": "GCF_022214805.1", "ncbiOrgName": "Azospirillum doebereinerae", - "ncbiTaxonomy": "d__Bacteria; p__Proteobacteria; c__Alphaproteobacteria; o__Rhodospirillales; f__Azospirillaceae; g__Azospirillum; s__Azospirillum doebereinerae", + "ncbiTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Rhodospirillales; f__Azospirillaceae; g__Azospirillum; s__Azospirillum doebereinerae", "gtdbTaxonomy": "d__Bacteria; p__Pseudomonadota; c__Alphaproteobacteria; o__Azospirillales; f__Azospirillaceae; g__Azospirillum; s__Azospirillum doebereinerae", "isGtdbSpeciesRep": false, - "isNcbiTypeMaterial": false + "isNcbiTypeMaterial": true }"#; assert_eq!(actual, expected); std::fs::remove_file("test9.txt").unwrap(); diff --git a/src/cmd/taxon.rs b/src/cmd/taxon.rs index f047eb9..b6db217 100644 --- a/src/cmd/taxon.rs +++ b/src/cmd/taxon.rs @@ -67,7 +67,7 @@ pub fn get_taxon_name(args: TaxonArgs) -> Result<()> { .collect(); let raw = args.get_raw(); - let agent: Agent = ureq::AgentBuilder::new().build(); + let agent: Agent = utils::get_agent(args.get_disable_certificate_verification())?; for name in taxon_api { let request_url = name.get_name_request(); @@ -111,7 +111,7 @@ pub fn search_taxon(args: TaxonArgs) -> Result<()> { let raw = args.get_raw(); let partial = args.get_partial(); - let agent: Agent = ureq::AgentBuilder::new().build(); + let agent: Agent = utils::get_agent(args.get_disable_certificate_verification())?; for search in taxon_api { let request_url: String = if args.is_search_all() { @@ -164,7 +164,7 @@ pub fn get_taxon_genomes(args: TaxonArgs) -> Result<()> { let raw = args.get_raw(); let sp_reps_only = args.is_reps_only(); - let agent: Agent = ureq::AgentBuilder::new().build(); + let agent: Agent = utils::get_agent(args.get_disable_certificate_verification())?; for search in taxon_api { let request_url = search.get_genomes_request(sp_reps_only); @@ -218,6 +218,7 @@ mod tests { search_all: false, genomes: false, reps_only: false, + disable_certificate_verification: true, }; get_taxon_name(args.clone())?; @@ -248,6 +249,7 @@ mod tests { search_all: false, genomes: false, reps_only: false, + disable_certificate_verification: true, }; get_taxon_name(args)?; @@ -266,6 +268,7 @@ mod tests { search_all: false, genomes: false, reps_only: false, + disable_certificate_verification: true, }; get_taxon_name(args)?; @@ -284,6 +287,7 @@ mod tests { search_all: false, genomes: false, reps_only: false, + disable_certificate_verification: true, }; let result = get_taxon_name(taxon_args); assert!(result.is_err()); @@ -306,6 +310,7 @@ mod tests { search_all: false, genomes: false, reps_only: false, + disable_certificate_verification: true, }; let result = get_taxon_name(taxon_args); assert!(result.is_err()); @@ -350,6 +355,7 @@ mod tests { search_all: false, genomes: false, reps_only: false, + disable_certificate_verification: true, }; let result = search_taxon(args); assert!(result.is_err()); @@ -370,6 +376,7 @@ mod tests { search_all: false, genomes: false, reps_only: false, + disable_certificate_verification: true, }; let result = search_taxon(args); assert!(result.is_ok()); @@ -386,6 +393,7 @@ mod tests { search_all: false, genomes: false, reps_only: false, + disable_certificate_verification: true, }; let result = search_taxon(args); assert!(result.is_ok()); @@ -402,6 +410,7 @@ mod tests { search_all: false, genomes: false, reps_only: false, + disable_certificate_verification: true, }; let result = search_taxon(args); assert!(result.is_ok()); @@ -423,6 +432,7 @@ mod tests { search_all: false, genomes: true, reps_only: false, + disable_certificate_verification: true, }; let actual_output = args.get_output().unwrap(); diff --git a/src/cmd/utils.rs b/src/cmd/utils.rs index 252c4a3..eec29ec 100644 --- a/src/cmd/utils.rs +++ b/src/cmd/utils.rs @@ -3,6 +3,7 @@ use clap::ArgMatches; use std::fs::OpenOptions; +use std::sync::Arc; use std::{ fs::File, io::{self, BufRead, BufReader, Write}, @@ -18,6 +19,7 @@ pub struct SearchArgs { pub(crate) rep: bool, pub(crate) type_material: bool, pub(crate) out: Option, + pub(crate) disable_certificate_verification: bool, } impl Default for SearchArgs { @@ -31,6 +33,7 @@ impl Default for SearchArgs { rep: false, type_material: false, out: None, + disable_certificate_verification: false, } } } @@ -80,6 +83,10 @@ impl SearchArgs { self.type_material } + pub fn get_disable_certificate_verification(&self) -> bool { + self.disable_certificate_verification + } + fn set_type_material(&mut self, b: bool) { self.type_material = b; } @@ -100,57 +107,49 @@ impl SearchArgs { self.out = s; } + pub fn set_disable_certificate_verification(&mut self, b: bool) { + self.disable_certificate_verification = b; + } + pub fn new() -> Self { SearchArgs::default() } pub fn from_arg_matches(args: &ArgMatches) -> Self { let mut search_args = SearchArgs::new(); - let mut needles: Vec = Vec::new(); - if args.contains_id("file") { - let file = File::open(args.get_one::("file").unwrap()) - .expect("file should be well-formatted"); - - needles.extend( - BufReader::new(file) - .lines() - .map(|l| l.expect("Cannot parse line")), - ); - } else { - needles.extend(vec![args.get_one::("name").unwrap().to_string()]); + if let Some(file_path) = args.get_one::("file") { + let file = File::open(file_path) + .unwrap_or_else(|_| panic!("Failed to open file: {}", file_path)); + let needles: Vec<_> = BufReader::new(file) + .lines() + .map(|l| l.unwrap_or_else(|e| panic!("Failed to read line: {}", e))) + .collect(); + search_args.set_needle(needles); + } else if let Some(name) = args.get_one::("name") { + search_args.set_needle(vec![name.to_string()]); } - search_args.set_needle(needles); - if args.contains_id("level") { search_args.set_level(args.get_one::("level").unwrap().to_string()); } - if args.get_flag("id") { - search_args.set_id(true); - } + search_args.set_id(args.get_flag("id")); - if args.get_flag("count") { - search_args.set_count(true); - } + search_args.set_count(args.get_flag("count")); - if args.get_flag("raw") { - search_args.set_raw(true); - } + search_args.set_raw(args.get_flag("raw")); - if args.get_flag("rep") { - search_args.set_rep(true); - } + search_args.set_rep(args.get_flag("rep")); - if args.get_flag("type") { - search_args.set_type_material(true); - } + search_args.set_type_material(args.get_flag("type")); if args.contains_id("out") { search_args.set_out(args.get_one::("out").cloned()); } + search_args.set_disable_certificate_verification(args.get_flag("insecure")); + search_args } } @@ -160,6 +159,7 @@ pub struct GenomeArgs { pub(crate) accession: Vec, pub(crate) raw: bool, pub(crate) output: Option, + pub(crate) disable_certificate_verification: bool, } impl GenomeArgs { @@ -175,6 +175,10 @@ impl GenomeArgs { self.output.clone() } + pub fn get_disable_certificate_verification(&self) -> bool { + self.disable_certificate_verification + } + pub fn from_arg_matches(arg_matches: &ArgMatches) -> Self { let mut accession = Vec::new(); @@ -203,6 +207,7 @@ impl GenomeArgs { } else { None }, + disable_certificate_verification: arg_matches.get_flag("insecure"), } } } @@ -217,6 +222,7 @@ pub struct TaxonArgs { pub(crate) search_all: bool, pub(crate) genomes: bool, pub(crate) reps_only: bool, + pub(crate) disable_certificate_verification: bool, } impl TaxonArgs { @@ -236,6 +242,10 @@ impl TaxonArgs { self.partial } + pub fn get_disable_certificate_verification(&self) -> bool { + self.disable_certificate_verification + } + pub fn is_search(&self) -> bool { self.search } @@ -280,6 +290,7 @@ impl TaxonArgs { search_all: arg_matches.get_flag("all"), genomes: arg_matches.get_flag("genomes"), reps_only: arg_matches.get_flag("reps"), + disable_certificate_verification: arg_matches.get_flag("insecure"), } } } @@ -295,6 +306,22 @@ pub fn write_to_output(s: String, output: Option) -> Result<()> { Ok(()) } +pub fn get_agent(disable_certificate_verification: bool) -> anyhow::Result { + match disable_certificate_verification { + true => { + let tls_connector = Arc::new( + native_tls::TlsConnector::builder() + .danger_accept_invalid_certs(true) + .build()?, + ); + Ok(ureq::AgentBuilder::new() + .tls_connector(tls_connector) + .build()) + } + false => Ok(ureq::AgentBuilder::new().build()), + } +} + #[cfg(test)] mod tests { @@ -308,6 +335,7 @@ mod tests { accession: vec![String::from("NC_000001.11")], raw: false, output: None, + disable_certificate_verification: true, }; assert_eq!(genome_args.get_accession(), vec!["NC_000001.11"]); @@ -319,6 +347,7 @@ mod tests { accession: vec![String::from("NC_000001.11")], raw: true, output: None, + disable_certificate_verification: true, }; assert!(genome_args.get_raw()); @@ -330,6 +359,7 @@ mod tests { accession: vec![String::from("NC_000001.11")], raw: false, output: Some(String::from("output4.txt")), + disable_certificate_verification: true, }; assert_eq!(genome_args.get_output(), Some(String::from("output4.txt"))); @@ -346,6 +376,7 @@ mod tests { rep: false, type_material: false, out: Some(String::from("test1")), + disable_certificate_verification: true, }; assert_eq!(args.get_needle(), vec!["needle".to_string()]); assert_eq!(args.get_level(), "level".to_string()); @@ -368,6 +399,7 @@ mod tests { search_all: false, genomes: false, reps_only: false, + disable_certificate_verification: true, }; assert_eq!(args.get_name(), vec!["name1", "name2"]); @@ -384,6 +416,7 @@ mod tests { search_all: false, genomes: false, reps_only: false, + disable_certificate_verification: true, }; assert_eq!(args.get_partial(), true); @@ -400,6 +433,7 @@ mod tests { search_all: false, genomes: false, reps_only: false, + disable_certificate_verification: true, }; assert_eq!(args.is_search(), true); diff --git a/src/main.rs b/src/main.rs index 20a8905..5f77462 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,3 @@ -extern crate anyhow; - mod api; mod app; mod cmd; @@ -11,8 +9,9 @@ use cmd::{genome, search, taxon, utils}; fn main() -> Result<()> { let matches = app::build_app().get_matches_from(env::args_os()); + let subcommand = matches.subcommand(); - match matches.subcommand() { + match subcommand { Some(("search", sub_matches)) => { let args = utils::SearchArgs::from_arg_matches(sub_matches); if sub_matches.get_flag("partial") { @@ -21,32 +20,38 @@ fn main() -> Result<()> { search::exact_search(args)?; } } - Some(("genome", sub_matches)) => { - let args = utils::GenomeArgs::from_arg_matches(sub_matches); - if sub_matches.get_flag("history") { - genome::get_genome_taxon_history(args)?; - } else if sub_matches.get_flag("metadata") { - genome::get_genome_metadata(args)?; - } else { - genome::get_genome_card(args)? - } - } - Some(("taxon", sub_matches)) => { - let args = utils::TaxonArgs::from_arg_matches(sub_matches); - if args.is_search() || args.is_search_all() { - taxon::search_taxon(args)?; - } else if args.is_genome() { - taxon::get_taxon_genomes(args)?; - } else { - taxon::get_taxon_name(args)?; - } - } + Some(("genome", sub_matches)) => handle_genome_command(sub_matches)?, + Some(("taxon", sub_matches)) => handle_taxon_command(sub_matches)?, _ => unreachable!("Implemented correctly"), }; Ok(()) } +fn handle_genome_command(sub_matches: &clap::ArgMatches) -> Result<()> { + let args = utils::GenomeArgs::from_arg_matches(sub_matches); + if sub_matches.get_flag("history") { + genome::get_genome_taxon_history(args)?; + } else if sub_matches.get_flag("metadata") { + genome::get_genome_metadata(args)?; + } else { + genome::get_genome_card(args)? + } + Ok(()) +} + +fn handle_taxon_command(sub_matches: &clap::ArgMatches) -> Result<()> { + let args = utils::TaxonArgs::from_arg_matches(sub_matches); + if args.is_search() || args.is_search_all() { + taxon::search_taxon(args)?; + } else if args.is_genome() { + taxon::get_taxon_genomes(args)?; + } else { + taxon::get_taxon_name(args)?; + } + Ok(()) +} + #[cfg(test)] mod tests { use super::*;