Add related
This commit is contained in:
		
							parent
							
								
									13c365c3a7
								
							
						
					
					
						commit
						8f75ac0b45
					
				
							
								
								
									
										17
									
								
								src/api.rs
								
								
								
								
							
							
						
						
									
										17
									
								
								src/api.rs
								
								
								
								
							| 
						 | 
					@ -31,9 +31,20 @@ pub async fn get_sauce_info(
 | 
				
			||||||
    client: reqwest::Client,
 | 
					    client: reqwest::Client,
 | 
				
			||||||
    sauce: i32,
 | 
					    sauce: i32,
 | 
				
			||||||
) -> Result<structs::GalleryInfo, structs::Error> {
 | 
					) -> Result<structs::GalleryInfo, structs::Error> {
 | 
				
			||||||
    let mut uri = String::from("https://nhentai.net/api/gallery/");
 | 
					    let mut url = String::from("https://nhentai.net/api/gallery/");
 | 
				
			||||||
    uri.push_str(&sauce.to_string());
 | 
					    url.push_str(&sauce.to_string());
 | 
				
			||||||
    let resp = client.get(&uri).send().await?;
 | 
					    let resp = client.get(&url).send().await?;
 | 
				
			||||||
 | 
					    Ok(serde_json::from_str(&resp.text().await?)?)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub async fn get_related_galleries(
 | 
				
			||||||
 | 
					    client: &reqwest::Client,
 | 
				
			||||||
 | 
					    sauce: i32,
 | 
				
			||||||
 | 
					) -> Result<structs::RelatedGalleries, structs::Error> {
 | 
				
			||||||
 | 
					    let mut url = String::from("https://nhentai.net/api/gallery/");
 | 
				
			||||||
 | 
					    url.push_str(&sauce.to_string());
 | 
				
			||||||
 | 
					    url.push_str("/related");
 | 
				
			||||||
 | 
					    let resp = client.get(&url).send().await?;
 | 
				
			||||||
    Ok(serde_json::from_str(&resp.text().await?)?)
 | 
					    Ok(serde_json::from_str(&resp.text().await?)?)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
mod download;
 | 
					mod download;
 | 
				
			||||||
 | 
					mod related;
 | 
				
			||||||
mod search;
 | 
					mod search;
 | 
				
			||||||
mod view;
 | 
					mod view;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,12 +21,14 @@ pub async fn run() {
 | 
				
			||||||
    match operation.as_str() {
 | 
					    match operation.as_str() {
 | 
				
			||||||
        "search" => search::run(args).await,
 | 
					        "search" => search::run(args).await,
 | 
				
			||||||
        "view" | "show" | "info" => view::run(args).await,
 | 
					        "view" | "show" | "info" => view::run(args).await,
 | 
				
			||||||
 | 
					        "related" => related::run(args).await,
 | 
				
			||||||
        "download" | "dl" => download::run(args).await,
 | 
					        "download" | "dl" => download::run(args).await,
 | 
				
			||||||
        "help" => println!(
 | 
					        "help" => println!(
 | 
				
			||||||
            r#"Usage: {} search QUERY
 | 
					            r#"Usage: {} search <query>
 | 
				
			||||||
  or   {} info/view/show SAUCE [SAUCE]...
 | 
					  or   {} info/view/show <sauce>...
 | 
				
			||||||
  or   {} download/dl SAUCE [SAUCE]..."#,
 | 
					  or   {} related <sauce>...
 | 
				
			||||||
            path, path, path
 | 
					  or   {} download/dl <sauce>..."#,
 | 
				
			||||||
 | 
					            path, path, path, path
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        _ => {
 | 
					        _ => {
 | 
				
			||||||
            eprintln!("Unknown operation, run `{} help`", path);
 | 
					            eprintln!("Unknown operation, run `{} help`", path);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,74 @@
 | 
				
			||||||
 | 
					use crate::api;
 | 
				
			||||||
 | 
					use crate::structs;
 | 
				
			||||||
 | 
					use crate::utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use std::env;
 | 
				
			||||||
 | 
					use std::process::exit;
 | 
				
			||||||
 | 
					extern crate reqwest;
 | 
				
			||||||
 | 
					extern crate tokio;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub async fn run(args: env::Args) {
 | 
				
			||||||
 | 
					    let sauces = utils::get_arg_sauces(args);
 | 
				
			||||||
 | 
					    let is_multi = sauces.len() > 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let client = api::get_client();
 | 
				
			||||||
 | 
					    let mut failures = 0;
 | 
				
			||||||
 | 
					    let mut one_done = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for sauce in sauces {
 | 
				
			||||||
 | 
					        let sauce_info = api::get_related_galleries(&client, sauce).await;
 | 
				
			||||||
 | 
					        match sauce_info {
 | 
				
			||||||
 | 
					            Ok(structs::RelatedGalleries::Galleries(related_galleries)) => {
 | 
				
			||||||
 | 
					                show_related_galleries(sauce, &related_galleries, one_done, is_multi)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            Ok(structs::RelatedGalleries::Error(err)) => {
 | 
				
			||||||
 | 
					                show_error(sauce, &err.error, one_done, true);
 | 
				
			||||||
 | 
					                failures += 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            Err(err) => {
 | 
				
			||||||
 | 
					                show_error(sauce, &err, one_done, is_multi);
 | 
				
			||||||
 | 
					                failures += 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        one_done = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    exit(failures);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn show_related_galleries(
 | 
				
			||||||
 | 
					    sauce: i32,
 | 
				
			||||||
 | 
					    related_galleries: &structs::RelatedGalleriesSuccess,
 | 
				
			||||||
 | 
					    prepend_newline: bool,
 | 
				
			||||||
 | 
					    is_multi: bool,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    if prepend_newline {
 | 
				
			||||||
 | 
					        println!("");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut prefix = "";
 | 
				
			||||||
 | 
					    if is_multi {
 | 
				
			||||||
 | 
					        println!("{}:", sauce);
 | 
				
			||||||
 | 
					        prefix = "- ";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    for i in &related_galleries.result {
 | 
				
			||||||
 | 
					        let title = i.title.english.as_deref().or(i.title.japanese.as_deref());
 | 
				
			||||||
 | 
					        println!("{}{}: {}", prefix, i.id, title.unwrap_or("<unknown title>"));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn show_error<T: std::fmt::Display>(
 | 
				
			||||||
 | 
					    sauce: i32,
 | 
				
			||||||
 | 
					    error: &T,
 | 
				
			||||||
 | 
					    prepend_newline: bool,
 | 
				
			||||||
 | 
					    prepend_sauce: bool,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    if prepend_newline {
 | 
				
			||||||
 | 
					        eprintln!("");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if !prepend_sauce {
 | 
				
			||||||
 | 
					        eprintln!("{}", error);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        eprintln!("{}: {}", sauce, error);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,11 @@ use std::fmt;
 | 
				
			||||||
use std::marker::PhantomData;
 | 
					use std::marker::PhantomData;
 | 
				
			||||||
use std::num::ParseIntError;
 | 
					use std::num::ParseIntError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Deserialize, Debug)]
 | 
				
			||||||
 | 
					pub struct APIError {
 | 
				
			||||||
 | 
					    pub error: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Deserialize, Debug)]
 | 
					#[derive(Deserialize, Debug)]
 | 
				
			||||||
pub struct GalleryTitleInfo {
 | 
					pub struct GalleryTitleInfo {
 | 
				
			||||||
    pub english: Option<String>,
 | 
					    pub english: Option<String>,
 | 
				
			||||||
| 
						 | 
					@ -50,15 +55,22 @@ pub struct GalleryInfoSuccess {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Deserialize, Debug)]
 | 
					#[derive(Deserialize, Debug)]
 | 
				
			||||||
pub struct GalleryInfoError {
 | 
					#[serde(untagged)]
 | 
				
			||||||
    pub error: String,
 | 
					pub enum GalleryInfo {
 | 
				
			||||||
 | 
					    Info(GalleryInfoSuccess),
 | 
				
			||||||
 | 
					    Error(APIError),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Deserialize, Debug)]
 | 
				
			||||||
 | 
					pub struct RelatedGalleriesSuccess {
 | 
				
			||||||
 | 
					    pub result: Vec<GalleryInfoSuccess>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Deserialize, Debug)]
 | 
					#[derive(Deserialize, Debug)]
 | 
				
			||||||
#[serde(untagged)]
 | 
					#[serde(untagged)]
 | 
				
			||||||
pub enum GalleryInfo {
 | 
					pub enum RelatedGalleries {
 | 
				
			||||||
    Info(GalleryInfoSuccess),
 | 
					    Galleries(RelatedGalleriesSuccess),
 | 
				
			||||||
    Error(GalleryInfoError),
 | 
					    Error(APIError),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue