nhentairs/src/utils.rs

79 lines
2.6 KiB
Rust

use crate::structs;
use std::env;
use std::fs::File;
use std::io::Write;
use tokio::stream::StreamExt;
extern crate serde_json;
extern crate reqwest;
fn fix_gallery(body: &mut serde_json::Value) -> Result<(), serde_json::Error> {
if body["id"].is_string() {
body["id"] = serde_json::json!(
body["id"].as_str().unwrap().parse::<usize>().unwrap()
);
}
for title in ["english", "japanese", "pretty"].iter() {
if body["title"][title].is_null() {
body["title"][title] = serde_json::json!("")
}
}
Ok(())
}
pub async fn get_sauce_info(client: reqwest::Client, sauce: usize) -> Result<structs::GalleryInfo, reqwest::Error> {
let mut uri = String::from("https://nhentai.net/api/gallery/");
uri.push_str(&sauce.to_string());
let resp = client.get(&uri)
.send()
.await?;
assert_eq!(resp.status().is_success(), true);
let body = resp.text().await?;
let mut body: serde_json::Value = serde_json::from_str(&body).unwrap();
fix_gallery(&mut body).unwrap();
Ok(serde_json::from_str(&serde_json::to_string(&body).unwrap()).unwrap())
}
pub async fn get_search_info(client: reqwest::Client, search_query: &str) -> Result<structs::SearchInfo, reqwest::Error> {
let uri = "https://nhentai.net/api/galleries/search";
let resp = client.get(uri)
.query(&[("query", search_query)])
.send()
.await?;
assert_eq!(resp.status().is_success(), true);
let body = resp.text().await?;
let mut body: serde_json::Value = serde_json::from_str(&body).unwrap();
for i in 0..body["result"].as_array().unwrap().len() {
fix_gallery(&mut body["result"][i]).unwrap();
}
Ok(serde_json::from_str(&serde_json::to_string(&body).unwrap()).unwrap())
}
pub async fn download_file(client: reqwest::Client, url: &str, file_name: &str) -> Result<(), reqwest::Error> {
let resp = client.get(url)
.send()
.await?;
let mut file = File::create(&file_name).unwrap();
let mut stream = resp.bytes_stream();
while let Some(item) = stream.next().await {
file.write(&item?).unwrap();
}
Ok(())
}
pub fn get_arg_sauces(args: env::Args) -> Result<Vec<usize>, String> {
let mut sauces: Vec<usize> = Vec::new();
for sauce in args {
let sauce: usize = match sauce.parse() {
Ok(sauce) => sauce,
Err(_) => {
return Err(format!("{} is not a number/sauce", sauce));
}
};
if !sauces.contains(&sauce) {
sauces.push(sauce);
}
}
Ok(sauces)
}