From c1a3083fabc6681761d4ecae9858bc838af6bf44 Mon Sep 17 00:00:00 2001 From: Benjamyn Love Date: Fri, 22 Nov 2024 14:08:07 +1100 Subject: [PATCH] More wallhaven features Updated ABI slightly --- Cargo.lock | 7 +++ Cargo.toml | 1 + src/config.rs | 5 +- src/main.rs | 28 +++++++-- src/wallhaven.rs | 150 +++++++++++++++++++++++++++++++++-------------- 5 files changed, 140 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4b7a869..7fa896e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -661,6 +661,7 @@ dependencies = [ "serde", "serde_json", "untildify", + "urlencoding", ] [[package]] @@ -1279,6 +1280,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf16_iter" version = "1.0.5" diff --git a/Cargo.toml b/Cargo.toml index 26d47d3..86910f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,4 @@ reqwest = { version = "0.12.9", features = ["json", "blocking"] } serde = { version = "1.0.215", features = ["derive"] } serde_json = "1.0.133" untildify = { path = "../untildify" } +urlencoding = "2.1.3" diff --git a/src/config.rs b/src/config.rs index a2fc3da..df3a3d3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -61,6 +61,7 @@ pub struct Config { pub wallpaper_engine: WallpaperHandler, pub wallpaper_dir: WallpaperDir, pub monitors: Monitors, + pub wallhaven_api_key: String, } impl Config { @@ -100,13 +101,15 @@ impl Config { monitors.add(MonitorType::new(monitor.to_string())); } } - // + + let wallhaven_api_key = config.get("general", "wallhaven_api_key").unwrap(); Config { x_server: config.get("general", "x_server").unwrap(), wallpaper_engine, wallpaper_dir, monitors, + wallhaven_api_key, } } } diff --git a/src/main.rs b/src/main.rs index 599a7ca..13c2530 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,14 +11,32 @@ use wallhaven::*; use untildify::untildify; fn main() { - test_request(); + // test_request(); // Load the config file from the default path - // let path = untildify("~/.config/wallpaperctl/wallpaperctl.ini"); - // let config = Config::from_config(path); + let path = untildify("~/.config/wallpaperctl/wallpaperctl.ini"); + let config = Config::from_config(path); - // // Initialise the `Wallpapers` struct with a clone of the config - // let mut wallpapers = Wallpapers::new(config.clone()); + // Initialise the `Wallpapers` struct with a clone of the config + let mut wallpapers = Wallpapers::new(config.clone()); + let api = WallHavenAPI::new(config.wallhaven_api_key); + + let search_terms = vec![String::from("godzilla")]; + let purities = vec![Purity::Sfw]; + let categories = vec![Category::Anime, Category::General]; + + let query = WallHavenQuery::new( + api, + search_terms, + purities, + categories, + Ratio::Horizontal, + 1, + ); + + let results = query.run(); + + println!("{}", results); // // Load all wallpapers based on the config file specs // wallpapers.load_all(); diff --git a/src/wallhaven.rs b/src/wallhaven.rs index a2f663f..2d70b9c 100644 --- a/src/wallhaven.rs +++ b/src/wallhaven.rs @@ -1,7 +1,9 @@ use core::fmt; +use dbus::arg::RefArg; use reqwest::*; use serde::Deserialize; use serde::Serialize; +use urlencoding::encode; #[derive(Serialize, Deserialize)] struct Thumbs { @@ -20,23 +22,19 @@ impl fmt::Display for Thumbs { struct Meta { current_page: i32, last_page: i32, - per_page: i32, + per_page: String, total: i32, - query: String, + query: Option, seed: Option, } impl fmt::Display for Meta { fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result { - write!( - f, - "query: {}\ncurrent_page: {}", - &self.query, &self.current_page - ) + write!(f, "current_page: {}", &self.current_page) } } #[derive(Serialize, Deserialize)] -struct WallHavenResponse { +pub struct WallHavenResponse { data: Vec, meta: Meta, } @@ -75,7 +73,7 @@ struct WallHavenWallpaper { impl fmt::Display for WallHavenWallpaper { fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result { - write!(f, "ID: {}\nURL: {}", &self.id, &self.url) + write!(f, "ID: {}\nURL: {}", &self.id, &self.path) } } @@ -124,25 +122,25 @@ impl fmt::Display for WallHavenAPI { } } -enum Ratio { +pub enum Ratio { Ultrawide, Horizontal, Vertical, } -enum Purity { +pub enum Purity { Sfw, Sketchy, Nsfw, } -enum Category { +pub enum Category { General, People, Anime, } -struct WallHavenQuery { +pub struct WallHavenQuery { api: WallHavenAPI, search_terms: Vec, purity: String, @@ -155,29 +153,47 @@ impl WallHavenQuery { pub fn new( api: WallHavenAPI, search_terms: Vec, - purity: Purity, - category: Category, + purity: Vec, + category: Vec, ratio: Ratio, page: i32, ) -> WallHavenQuery { - let mut purity_value = String::new(); - match purity { - Purity::Sfw => purity_value = String::from("sfw"), - Purity::Nsfw => purity_value = String::from("nsfw"), - Purity::Sketchy => purity_value = String::from("sketchy"), - }; - let mut ratio_value = String::new(); + let mut purity_value = String::from("000"); + for p in purity { + match p { + Purity::Nsfw => { + purity_value.replace_range(2..3, "1"); + } + Purity::Sfw => { + purity_value.replace_range(0..1, "1"); + } + Purity::Sketchy => { + purity_value.replace_range(1..2, "1"); + } + } + } + + let ratio_value: String; match ratio { Ratio::Horizontal => ratio_value = String::from("16x9"), Ratio::Ultrawide => ratio_value = String::from("21x9"), Ratio::Vertical => ratio_value = String::from("9x16"), }; - let mut category_value = String::new(); - match category { - Category::Anime => category_value = String::from("anime"), - Category::People => category_value = String::from("people"), - Category::General => category_value = String::from("general"), - }; + let mut category_value = String::from("000"); + for c in category { + match c { + Category::Anime => { + category_value.replace_range(1..2, "1"); + } + Category::General => { + category_value.replace_range(0..1, "1"); + } + Category::People => { + category_value.replace_range(2..3, "1"); + } + } + } + WallHavenQuery { api: api, search_terms: search_terms, @@ -190,30 +206,74 @@ impl WallHavenQuery { pub fn run(&self) -> WallHavenResponse { // Build the query string, URL encode it then send off the request + let mut query_string = String::from("?q="); + let mut url = String::from("https://wallhaven.cc/api/v1/search"); + let mut search_terms = String::new(); + for term in &self.search_terms { + search_terms.push_str(term.as_str()); + search_terms.push_str("+"); + } + query_string.push_str(search_terms.as_str()); + query_string.push_str("&ratios="); + query_string.push_str(self.ratio.as_str()); + query_string.push_str("&purity="); + query_string.push_str(self.purity.as_str()); + query_string.push_str("&categories="); + query_string.push_str(self.category.as_str()); + query_string.push_str("&apikey="); + query_string.push_str(self.api.api_key.as_str()); + + url.push_str(query_string.as_str()); + // let encoded = encode(url.as_str()).into_owned(); + println!("{}", &url); + serde_json::from_str(blocking::get(url).unwrap().text().unwrap().as_str()).unwrap() // Return the WallHavenResponse object } } pub fn test_request() { - let mut wallhaven = WallHavenAPI::new(String::from("mhodnIcgcbrmqLgErE0YmfZnC13sj7hU")); - let body = - reqwest::blocking::get("https://wallhaven.cc/api/v1/search?q=anime+skirt&ratios=21x9"); + let wallhaven = WallHavenAPI::new(String::from("mhodnIcgcbrmqLgErE0YmfZnC13sj7hU")); + // let body = blocking::get("https://wallhaven.cc/api/v1/search?q=anime+skirt&ratios=21x9"); - // println!("{}", body.unwrap().json::>()); - let data: WallHavenResponse = - serde_json::from_str(body.unwrap().text().unwrap().as_str()).unwrap(); + // // println!("{}", body.unwrap().json::>()); + // let data: WallHavenResponse = + // serde_json::from_str(body.unwrap().text().unwrap().as_str()).unwrap(); - // for entry in data["data"] { - // let v: serde_json::Value = serde_json::from_str(entry.as_str().unwrap()).unwrap(); - // println!("{}", v); - // } + // // for entry in data["data"] { + // // let v: serde_jwson::Value = serde_json::from_str(entry.as_str().unwrap()).unwrap(); + // // println!("{}", v); + // // } - println!("{}", data); - wallhaven.add_tag(String::from("Anime")); - wallhaven.add_tag(String::from("Anime3")); - wallhaven.add_tag(String::from("Anime2")); - wallhaven.add_tag(String::from("Anime4")); - wallhaven.add_tag(String::from("Anime5")); - println!("{}", wallhaven) + // println!("{}", data); + // wallhaven.add_tag(String::from("Anime")); + // wallhaven.add_tag(String::from("Anime3")); + // wallhaven.add_tag(String::from("Anime2")); + // wallhaven.add_tag(String::from("Anime4")); + // wallhaven.add_tag(String::from("Anime5")); + // println!("{}", wallhaven) + + let mut search_terms = Vec::::new(); + // search_terms.push(String::from("sexy")); + search_terms.push(String::from("crab")); + + let mut purities = Vec::::new(); + purities.push(Purity::Nsfw); + purities.push(Purity::Sketchy); + + let mut categories = Vec::::new(); + categories.push(Category::Anime); + + let request = WallHavenQuery::new( + wallhaven, + search_terms, + purities, + categories, + Ratio::Horizontal, + 1, + ); + + let response = request.run(); + + print!("{}", response); }