Add related

This commit is contained in:
blankie 2023-10-28 13:09:17 +11:00
parent 13c365c3a7
commit 8f75ac0b45
Signed by: blankie
GPG Key ID: CC15FC822C7F61F5
4 changed files with 112 additions and 12 deletions

View File

@ -31,9 +31,20 @@ pub async fn get_sauce_info(
client: reqwest::Client,
sauce: i32,
) -> Result<structs::GalleryInfo, structs::Error> {
let mut uri = String::from("https://nhentai.net/api/gallery/");
uri.push_str(&sauce.to_string());
let resp = client.get(&uri).send().await?;
let mut url = String::from("https://nhentai.net/api/gallery/");
url.push_str(&sauce.to_string());
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?)?)
}

View File

@ -1,4 +1,5 @@
mod download;
mod related;
mod search;
mod view;
@ -20,12 +21,14 @@ pub async fn run() {
match operation.as_str() {
"search" => search::run(args).await,
"view" | "show" | "info" => view::run(args).await,
"related" => related::run(args).await,
"download" | "dl" => download::run(args).await,
"help" => println!(
r#"Usage: {} search QUERY
or {} info/view/show SAUCE [SAUCE]...
or {} download/dl SAUCE [SAUCE]..."#,
path, path, path
r#"Usage: {} search <query>
or {} info/view/show <sauce>...
or {} related <sauce>...
or {} download/dl <sauce>..."#,
path, path, path, path
),
_ => {
eprintln!("Unknown operation, run `{} help`", path);

74
src/commands/related.rs Normal file
View File

@ -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);
}
}

View File

@ -5,6 +5,11 @@ use std::fmt;
use std::marker::PhantomData;
use std::num::ParseIntError;
#[derive(Deserialize, Debug)]
pub struct APIError {
pub error: String,
}
#[derive(Deserialize, Debug)]
pub struct GalleryTitleInfo {
pub english: Option<String>,
@ -50,15 +55,22 @@ pub struct GalleryInfoSuccess {
}
#[derive(Deserialize, Debug)]
pub struct GalleryInfoError {
pub error: String,
#[serde(untagged)]
pub enum GalleryInfo {
Info(GalleryInfoSuccess),
Error(APIError),
}
#[derive(Deserialize, Debug)]
pub struct RelatedGalleriesSuccess {
pub result: Vec<GalleryInfoSuccess>,
}
#[derive(Deserialize, Debug)]
#[serde(untagged)]
pub enum GalleryInfo {
Info(GalleryInfoSuccess),
Error(GalleryInfoError),
pub enum RelatedGalleries {
Galleries(RelatedGalleriesSuccess),
Error(APIError),
}
#[derive(Debug)]