This commit is contained in:
2024-08-12 02:16:58 +02:00
parent 692cb43e9f
commit 5905bd6b15
5 changed files with 161 additions and 24 deletions

View File

@@ -14,7 +14,7 @@ type Client = ClientWithMiddleware;
#[tokio::main]
async fn main() {
let input = util::get_input("Enter search query: ");
let config = util::args();
let retry_policy = ExponentialBackoff::builder().build_with_max_retries(3);
let client = ClientBuilder::new(
reqwest::Client::builder()
@@ -29,7 +29,13 @@ async fn main() {
//("status[]", "completed"),
// ("contentRating[]", "suggestive"),
];
let results = search(&client, &input, &filters).await;
let limit = config.result_limit;
let results = if let Some(query) = config.search {
search(&client, &query, &filters, limit).await
} else {
let input = util::get_input("Enter search query: ");
search(&client, &input, &filters, limit).await
};
let mut entries = vec![];
for result in results.data.iter() {
let mut entry = Entry::new(result.attributes.title.en.clone());
@@ -63,17 +69,27 @@ async fn main() {
.unwrap();
let result = util::convert_to_sixel(&data);
entry.add_image(result)
entry.set_image(result)
}
entries.push(entry);
}
let choice = select::select(&entries).unwrap();
let choice = match select::select(&entries) {
Ok(v) => v,
Err(e) => {
eprintln!("ERROR: Failed to select: {:?}", e);
std::process::exit(1);
}
};
let choice_id = &results.data[choice as usize].id;
let bonus = loop {
match util::get_input("Read bonus chapters? [y/n] : ").as_str() {
"y" | "yes" => break true,
"n" | "no" => break false,
_ => continue,
let bonus = if let Some(bonus) = config.bonus {
bonus
} else {
loop {
match util::get_input("Read bonus chapters? [y/n] : ").as_str() {
"y" | "yes" => break true,
"n" | "no" => break false,
_ => continue,
}
}
};
let mut chapters = match get_chapters(&client, choice_id).await {
@@ -217,8 +233,12 @@ async fn get_chapters(client: &Client, id: &Id) -> Result<Vec<Chapter>, reqwest_
Ok(result.data)
}
async fn search(client: &Client, query: &str, filters: &[(&str, &str)]) -> SearchResult {
let limit = 10;
async fn search(
client: &Client,
query: &str,
filters: &[(&str, &str)],
limit: u32,
) -> SearchResult {
let params = [
("title", query),
("limit", &limit.to_string()),

View File

@@ -14,6 +14,17 @@ pub enum ResponseResult {
#[derive(Debug)]
pub enum Language {
Tagalog,
SimplifiedChinese,
Greek,
Persian,
TraditionalChinese,
Ukranian,
Romanian,
Arabic,
German,
Vietnamese,
French,
Turkish,
Korean,
SpanishLatinAmerican,
@@ -412,6 +423,17 @@ impl TryInto<Language> for &str {
"eo" => Language::Esperanto,
"pl" => Language::Polish,
"ko" => Language::Korean,
"fr" => Language::French,
"vi" => Language::Vietnamese,
"de" => Language::German,
"ar" => Language::Arabic,
"ro" => Language::Romanian,
"uk" => Language::Ukranian,
"zh-hk" => Language::TraditionalChinese,
"fa" => Language::Persian,
"el" => Language::Greek,
"zh" => Language::SimplifiedChinese,
"tl" => Language::Tagalog,
_ => return Err(()),
})
}

View File

@@ -45,7 +45,7 @@ impl Entry {
self.info.push((key.to_owned(), value.to_string()));
}
pub fn add_image(&mut self, sixel_data: String) {
pub fn set_image(&mut self, sixel_data: String) {
self.image = Some(sixel_data);
}
}
@@ -64,7 +64,7 @@ fn get_input() -> Option<Action> {
}),
Err(e) => {
eprintln!("ERROR: {:#?}", e);
std::process::exit(1);
exit();
}
_ => None,
}
@@ -72,7 +72,7 @@ fn get_input() -> Option<Action> {
Ok(false) => None,
Err(e) => {
eprintln!("ERROR: {:#?}", e);
std::process::exit(1);
exit();
}
}
}
@@ -138,6 +138,9 @@ fn render(
selected: u16,
offset: u16,
) -> Result<(), io::Error> {
if entries.is_empty() {
return Ok(());
}
stdout.queue(MoveTo(0, 0))?.queue(Clear(ClearType::All))?;
for (i, entry) in entries.iter().enumerate() {
stdout

View File

@@ -1,5 +1,6 @@
use crate::Chapter;
use icy_sixel::{DiffusionMethod, MethodForLargest, MethodForRep, PixelFormat, Quality};
use image::DynamicImage;
use std::{io, io::Write};
pub struct Selection {
@@ -35,6 +36,12 @@ pub enum ChapterSelection {
Single(f32),
}
pub struct Config {
pub bonus: Option<bool>,
pub search: Option<String>,
pub result_limit: u32,
}
fn filter_bonus(bonus: bool, volume: Option<u32>, chapter: Option<f32>) -> bool {
if bonus {
return true;
@@ -231,18 +238,40 @@ pub fn get_input(msg: &str) -> String {
}
pub fn convert_to_sixel(data: &[u8]) -> String {
let a = image::load_from_memory(data).unwrap();
let a = a.as_rgb8().unwrap();
let mut pixels = vec![];
a.pixels().for_each(|m| {
pixels.push(m.0[0]);
pixels.push(m.0[1]);
pixels.push(m.0[2]);
});
let image = image::load_from_memory(data).unwrap();
let mut pixels = Vec::new();
match &image {
DynamicImage::ImageRgb8(image) => image.pixels().for_each(|m| {
pixels.push(m.0[0]);
pixels.push(m.0[1]);
pixels.push(m.0[2]);
}),
DynamicImage::ImageRgba8(image) => image.pixels().for_each(|m| {
pixels.push(m.0[0]);
pixels.push(m.0[1]);
pixels.push(m.0[2]);
}),
DynamicImage::ImageLuma8(image) => image.pixels().for_each(|m| {
pixels.push(m.0[0]);
pixels.push(m.0[0]);
pixels.push(m.0[0]);
}),
DynamicImage::ImageLumaA8(_) => println!("Found lumaa8 image"),
DynamicImage::ImageRgb16(_) => println!("Found rgb16 image"),
DynamicImage::ImageLuma16(_) => println!("Found luma16 image"),
DynamicImage::ImageRgba16(_) => println!("Found rgba16 image"),
_ => panic!(),
}
// let mut pixels = vec![];
// a.pixels().for_each(|m| {
// pixels.push(m.0[0]);
// pixels.push(m.0[1]);
// pixels.push(m.0[2]);
// });
icy_sixel::sixel_string(
&pixels,
a.width() as i32,
a.height() as i32,
image.width() as i32,
image.height() as i32,
PixelFormat::RGB888,
DiffusionMethod::Auto,
MethodForLargest::Auto,
@@ -253,3 +282,65 @@ pub fn convert_to_sixel(data: &[u8]) -> String {
}
// pub fn convert_to_/
//
impl Config {
fn new() -> Self {
Self {
bonus: None,
search: None,
result_limit: 5,
}
}
}
pub fn args() -> Config {
let mut args = std::env::args().skip(1);
let mut config = Config::new();
while args.len() != 0 {
match args.next().unwrap().as_ref() {
"-s" | "--search" => {
if let Some(query) = args.next() {
config.search = Some(query);
} else {
eprintln!("Missing query for search");
std::process::exit(1);
}
}
"-b" | "--bonus" => {
config.bonus = match args.next() {
Some(a) => Some(match a.as_str() {
"true" => true,
"false" => false,
_ => {
eprintln!("Invalid value for bonus, type: bool");
std::process::exit(1);
}
}),
None => {
eprintln!("Missing value for bonus, type: bool");
std::process::exit(1);
}
};
}
"-r" | "--result-limit" => {
config.result_limit = match args.next() {
Some(a) => match a.parse() {
Ok(v) => v,
Err(e) => {
eprintln!("Failed to parse value for result-limit: {:?}, type: u32", e);
std::process::exit(1);
}
},
None => {
eprintln!("Missing value for bonus, type: u32");
std::process::exit(1);
}
};
}
_ => (),
}
}
config
}