From 5ffae110442b8d99f85ae12b041832e15d48a333 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sat, 14 Aug 2021 12:36:01 +0200 Subject: [PATCH 1/7] Refactor hydrus page Signed-off-by: trivernis --- src/lib.rs | 2 +- src/utils.rs | 24 ++++++++++++++++++++---- src/wrapper/page.rs | 36 ++++++++++++++++++------------------ 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index cbf98e5..e42b011 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,5 +74,5 @@ pub use wrapper::hydrus::Hydrus; pub mod api_core; pub mod error; -pub(crate) mod utils; +pub mod utils; pub mod wrapper; diff --git a/src/utils.rs b/src/utils.rs index e615d37..2fa9107 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,11 +1,12 @@ +use crate::api_core::common::FileIdentifier; use crate::wrapper::tag::Tag; use chrono::{Datelike, Duration}; -pub fn string_list_to_json_array(l: Vec) -> String { +pub(crate) fn string_list_to_json_array(l: Vec) -> String { format!("[\"{}\"]", l.join("\",\"")) } -pub fn number_list_to_json_array(l: Vec) -> String { +pub(crate) fn number_list_to_json_array(l: Vec) -> String { format!( "[{}]", l.into_iter() @@ -23,7 +24,7 @@ pub fn tag_list_to_string_list(tags: Vec) -> Vec { tags.into_iter().map(|t| t.to_string()).collect() } -pub fn format_datetime(datetime: D) -> String { +pub(crate) fn format_datetime(datetime: D) -> String { format!( "{:04}-{:02}-{:02}", datetime.year(), @@ -32,7 +33,7 @@ pub fn format_datetime(datetime: D) -> String { ) } -pub fn format_duration(duration: Duration) -> String { +pub(crate) fn format_duration(duration: Duration) -> String { let mut expression = String::new(); let days = duration.num_days(); let hours = duration.num_hours() % 24; @@ -56,3 +57,18 @@ pub fn format_duration(duration: Duration) -> String { expression } + +pub(crate) fn split_file_identifiers_into_hashes_and_ids( + files: Vec, +) -> (Vec, Vec) { + let mut ids = Vec::new(); + let mut hashes = Vec::new(); + + for file in files { + match file { + FileIdentifier::ID(id) => ids.push(id), + FileIdentifier::Hash(hash) => hashes.push(hash), + } + } + (ids, hashes) +} diff --git a/src/wrapper/page.rs b/src/wrapper/page.rs index 93669a2..48f37ea 100644 --- a/src/wrapper/page.rs +++ b/src/wrapper/page.rs @@ -1,5 +1,6 @@ use crate::api_core::common::{FileIdentifier, PageInformation}; use crate::error::Result; +use crate::utils::split_file_identifiers_into_hashes_and_ids; use crate::Client; #[derive(Clone)] @@ -40,27 +41,26 @@ impl HydrusPage { /// Adds files to a page pub async fn add_files(&self, files: Vec) -> Result<()> { - let mut hashes = Vec::new(); - let mut ids = Vec::new(); + let (ids, mut hashes) = split_file_identifiers_into_hashes_and_ids(files); - for file in files { - match file { - FileIdentifier::ID(id) => ids.push(id), - FileIdentifier::Hash(hash) => hashes.push(hash), - } - } // resolve file ids to hashes - if ids.len() > 0 && hashes.len() > 0 { - while let Some(id) = ids.pop() { - let metadata = self - .client - .get_file_metadata_by_identifier(FileIdentifier::ID(id)) - .await?; - hashes.push(metadata.hash); - } - } + hashes.append(&mut self.resolve_file_ids_to_hashes(ids).await?); - self.client.add_files_to_page(&self.key, ids, hashes).await + self.client + .add_files_to_page(&self.key, [].to_vec(), hashes) + .await + } + + async fn resolve_file_ids_to_hashes(&self, ids: Vec) -> Result> { + let mut hashes = Vec::new(); + for id in ids { + let metadata = self + .client + .get_file_metadata_by_identifier(FileIdentifier::ID(id)) + .await?; + hashes.push(metadata.hash); + } + Ok(hashes) } } From 27ec3b98f0dc6a4c742e6cfea633104196e8303c Mon Sep 17 00:00:00 2001 From: trivernis Date: Sat, 14 Aug 2021 12:41:22 +0200 Subject: [PATCH 2/7] Refactor hydrus file Signed-off-by: trivernis --- src/wrapper/hydrus_file.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/wrapper/hydrus_file.rs b/src/wrapper/hydrus_file.rs index 12036cc..a0312ea 100644 --- a/src/wrapper/hydrus_file.rs +++ b/src/wrapper/hydrus_file.rs @@ -18,6 +18,16 @@ pub enum FileStatus { impl Eq for FileStatus {} +impl From for FileStatus { + fn from(v: u8) -> FileStatus { + match v { + 3 => FileStatus::Deleted, + 0 => FileStatus::ReadyForImport, + _ => FileStatus::InDatabase, + } + } +} + #[derive(Clone)] pub struct HydrusFile { pub(crate) client: Client, @@ -41,17 +51,10 @@ impl HydrusFile { status: u8, hash: S, ) -> Self { - let status = if status == 3 { - FileStatus::Deleted - } else if status == 0 { - FileStatus::ReadyForImport - } else { - FileStatus::InDatabase - }; Self { client, id: FileIdentifier::Hash(hash.to_string()), - status, + status: status.into(), metadata: None, } } From 68a6d00c4ca68fec26f92b00c3913776c1082a88 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sat, 14 Aug 2021 12:46:06 +0200 Subject: [PATCH 3/7] Refactor hydrus service Signed-off-by: trivernis --- src/wrapper/service.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/wrapper/service.rs b/src/wrapper/service.rs index 0e0b36b..d2ed66e 100644 --- a/src/wrapper/service.rs +++ b/src/wrapper/service.rs @@ -4,6 +4,7 @@ use crate::api_core::access_management::{ SERVICE_TYPE_FILE_REPOSITORIES, SERVICE_TYPE_LOCAL_FILES, SERVICE_TYPE_LOCAL_TAGS, SERVICE_TYPE_TAG_REPOSITORIES, SERVICE_TYPE_TRASH, }; + use crate::error::Error; use crate::Client; use std::collections::HashMap; @@ -140,13 +141,9 @@ impl Services { /// Returns a list of all services of the given type pub fn get_services(&self, service_type: ServiceType) -> Vec<&Service> { if let Some(services) = self.inner.get(&service_type) { - let mut borrowed_services = Vec::with_capacity(services.len()); - for service in services { - borrowed_services.push(service) - } - borrowed_services + services.into_iter().collect() } else { - Vec::with_capacity(0) + Vec::new() } } } From ad30c14ddb5d25fb6cfd85430e47f70bd071016e Mon Sep 17 00:00:00 2001 From: trivernis Date: Sat, 14 Aug 2021 14:49:19 +0200 Subject: [PATCH 4/7] Add additional parameter to search requests With the new client api 19 there's options to sort results returned by search and filter by tag and file service. The FileSearchOptions struct allows using those extra parameters. Signed-off-by: trivernis --- src/api_core/client.rs | 18 ++-- src/api_core/mod.rs | 1 + src/api_core/searching_and_fetching_files.rs | 95 +++++++++++++++++++ src/wrapper/hydrus.rs | 3 +- .../test_searching_and_fetching_files.rs | 8 +- 5 files changed, 116 insertions(+), 9 deletions(-) diff --git a/src/api_core/client.rs b/src/api_core/client.rs index abe4391..f3b288f 100644 --- a/src/api_core/client.rs +++ b/src/api_core/client.rs @@ -21,7 +21,8 @@ use crate::api_core::managing_pages::{ GetPages, GetPagesResponse, }; use crate::api_core::searching_and_fetching_files::{ - FileMetadata, FileMetadataResponse, GetFile, SearchFiles, SearchFilesResponse, + FileMetadata, FileMetadataResponse, FileSearchOptions, GetFile, SearchFiles, + SearchFilesResponse, }; use crate::api_core::Endpoint; use crate::error::{Error, Result}; @@ -222,13 +223,16 @@ impl Client { } /// Searches for files in the inbox, the archive or both - pub async fn search_files(&self, tags: Vec) -> Result { + pub async fn search_files( + &self, + tags: Vec, + options: FileSearchOptions, + ) -> Result { log::trace!("Searching for files with tags {:?}", tags); - self.get_and_parse::(&[( - "tags", - string_list_to_json_array(tags), - )]) - .await + let mut args = options.into_query_args(); + args.push(("tags", string_list_to_json_array(tags))); + self.get_and_parse::(&args) + .await } /// Returns the metadata for a given list of file_ids or hashes diff --git a/src/api_core/mod.rs b/src/api_core/mod.rs index b046348..9f87869 100644 --- a/src/api_core/mod.rs +++ b/src/api_core/mod.rs @@ -10,6 +10,7 @@ pub mod common; pub mod managing_cookies_and_http_headers; pub mod managing_pages; pub mod searching_and_fetching_files; +pub use searching_and_fetching_files::file_sort_type; pub(crate) trait Endpoint { type Request: Serialize; diff --git a/src/api_core/searching_and_fetching_files.rs b/src/api_core/searching_and_fetching_files.rs index 9b47857..677858c 100644 --- a/src/api_core/searching_and_fetching_files.rs +++ b/src/api_core/searching_and_fetching_files.rs @@ -1,6 +1,101 @@ use crate::api_core::common::FileMetadataInfo; use crate::api_core::Endpoint; +pub mod file_sort_type { + pub const SORT_FILE_SIZE: u8 = 0; + pub const SORT_FILE_DURATION: u8 = 1; + pub const SORT_FILE_IMPORT_TIME: u8 = 2; + pub const SORT_FILE_TYPE: u8 = 3; + pub const SORT_FILE_RANDOM: u8 = 4; + pub const SORT_FILE_WIDTH: u8 = 5; + pub const SORT_FILE_HEIGHT: u8 = 6; + pub const SORT_FILE_RATIO: u8 = 7; + pub const SORT_FILE_PIXEL_COUNT: u8 = 8; + pub const SORT_FILE_TAG_COUNT: u8 = 9; + pub const SORT_FILE_MEDIA_VIEWS: u8 = 10; + pub const SORT_FILE_MEDIA_VIEWTIME: u8 = 11; + pub const SORT_FILE_BITRATE: u8 = 12; + pub const SORT_FILE_HAS_AUDIO: u8 = 13; + pub const SORT_FILE_MODIFIED_TIME: u8 = 14; + pub const SORT_FILE_FRAMERATE: u8 = 15; + pub const SORT_FILE_FRAME_COUNT: u8 = 16; +} + +#[derive(Clone, Debug, Default)] +pub struct FileSearchOptions { + file_service_name: Option, + file_service_key: Option, + tag_service_name: Option, + tag_service_key: Option, + file_sort_type: Option, + file_sort_asc: Option, +} + +impl FileSearchOptions { + pub fn new() -> Self { + Self::default() + } + + pub fn file_service_name(mut self, name: S) -> Self { + self.file_service_name = Some(name.to_string()); + self + } + + pub fn file_service_key(mut self, key: S) -> Self { + self.file_service_key = Some(key.to_string()); + self + } + + pub fn tag_service_name(mut self, name: S) -> Self { + self.tag_service_name = Some(name.to_string()); + self + } + + pub fn tag_service_key(mut self, key: S) -> Self { + self.tag_service_key = Some(key.to_string()); + self + } + + pub fn sort_type(mut self, sort_type: u8) -> Self { + self.file_sort_type = Some(sort_type); + self + } + + pub fn asc(mut self) -> Self { + self.file_sort_asc = Some(true); + self + } + + pub fn desc(mut self) -> Self { + self.file_sort_asc = Some(false); + self + } + + pub(crate) fn into_query_args(self) -> Vec<(&'static str, String)> { + let mut args = Vec::new(); + if let Some(sort) = self.file_sort_type { + args.push(("file_sort_type", sort.to_string())); + } + if let Some(file_service_name) = self.file_service_name { + args.push(("file_service_name", file_service_name)); + } + if let Some(file_service_key) = self.file_service_key { + args.push(("file_service_key", file_service_key)); + } + if let Some(tag_service_name) = self.tag_service_name { + args.push(("tag_service_name", tag_service_name)) + } + if let Some(tag_service_key) = self.tag_service_key { + args.push(("tag_service_key", tag_service_key)); + } + if let Some(sort_asc) = self.file_sort_asc { + args.push(("file_sort_asc", sort_asc.to_string())) + } + + args + } +} + #[derive(Debug, Clone, Deserialize)] pub struct SearchFilesResponse { pub file_ids: Vec, diff --git a/src/wrapper/hydrus.rs b/src/wrapper/hydrus.rs index 39dd6f9..390e92f 100644 --- a/src/wrapper/hydrus.rs +++ b/src/wrapper/hydrus.rs @@ -1,4 +1,5 @@ use crate::api_core::common::FileIdentifier; +use crate::api_core::searching_and_fetching_files::FileSearchOptions; use crate::error::Result; use crate::utils::tag_list_to_string_list; use crate::wrapper::address::Address; @@ -86,7 +87,7 @@ impl Hydrus { pub async fn search(&self, tags: Vec) -> Result> { let search_result = self .client - .search_files(tag_list_to_string_list(tags)) + .search_files(tag_list_to_string_list(tags), FileSearchOptions::new()) .await?; let files = search_result .file_ids diff --git a/tests/client/test_searching_and_fetching_files.rs b/tests/client/test_searching_and_fetching_files.rs index 4289443..9859b6b 100644 --- a/tests/client/test_searching_and_fetching_files.rs +++ b/tests/client/test_searching_and_fetching_files.rs @@ -1,11 +1,17 @@ use super::super::common; use hydrus_api::api_core::common::FileIdentifier; +use hydrus_api::api_core::file_sort_type::SORT_FILE_PIXEL_COUNT; +use hydrus_api::api_core::searching_and_fetching_files::FileSearchOptions; #[tokio::test] async fn is_searches_files() { let client = common::get_client(); + let options = FileSearchOptions::new() + .sort_type(SORT_FILE_PIXEL_COUNT) + .tag_service_name("public tag repository") + .file_service_name("all known files"); client - .search_files(vec!["beach".to_string()]) + .search_files(vec!["beach".to_string()], options) .await .unwrap(); } From 2a297c06365d52c8b8e607efd2fb53572895276b Mon Sep 17 00:00:00 2001 From: trivernis Date: Sat, 14 Aug 2021 15:19:32 +0200 Subject: [PATCH 5/7] Add hydrus search builder for complex searches Signed-off-by: trivernis --- src/wrapper/builders/mod.rs | 1 + src/wrapper/builders/search_builder.rs | 115 +++++++++++++++++++++++++ src/wrapper/hydrus.rs | 20 +---- tests/wrapper/test_hydrus.rs | 6 +- tests/wrapper/test_tags.rs | 2 +- 5 files changed, 126 insertions(+), 18 deletions(-) create mode 100644 src/wrapper/builders/search_builder.rs diff --git a/src/wrapper/builders/mod.rs b/src/wrapper/builders/mod.rs index 7ab8348..0584473 100644 --- a/src/wrapper/builders/mod.rs +++ b/src/wrapper/builders/mod.rs @@ -1,3 +1,4 @@ pub mod import_builder; pub mod tagging_builder; pub mod tag_builder; +pub mod search_builder; diff --git a/src/wrapper/builders/search_builder.rs b/src/wrapper/builders/search_builder.rs new file mode 100644 index 0000000..7c6c35f --- /dev/null +++ b/src/wrapper/builders/search_builder.rs @@ -0,0 +1,115 @@ +use crate::api_core::searching_and_fetching_files::FileSearchOptions; +use crate::error::Result; +use crate::utils::tag_list_to_string_list; +use crate::wrapper::hydrus_file::HydrusFile; +use crate::wrapper::service::ServiceName; +use crate::wrapper::tag::Tag; +use crate::Client; + +pub enum SortType { + FileSize, + Duration, + ImportTime, + FileType, + Random, + Width, + Height, + Ratio, + NumberOfPixels, + NumberOfTags, + NumberOfMediaViewers, + MediaViewTime, + Bitrate, + HasAudio, + ModifiedTime, + Framerate, + NumberOfFrames, +} + +#[derive(Clone, Debug)] +pub struct SearchBuilder { + client: Client, + tags: Vec, + options: FileSearchOptions, +} + +impl SearchBuilder { + pub(crate) fn new(client: Client) -> Self { + Self { + client, + tags: Vec::new(), + options: FileSearchOptions::new(), + } + } + + /// Add multiple tags to filter by + pub fn add_tags(mut self, mut tags: Vec) -> Self { + self.tags.append(&mut tags); + self + } + + /// Add a tag to filter by + pub fn add_tag(mut self, tag: Tag) -> Self { + self.tags.push(tag); + self + } + + /// Sets the sort type + pub fn sort_by(mut self, sort_type: SortType) -> Self { + self.options = self.options.sort_type(sort_type as u8); + self + } + + /// Sorts descending + pub fn sort_descending(mut self) -> Self { + self.options = self.options.desc(); + self + } + + /// Sorts ascending + pub fn sort_ascending(mut self) -> Self { + self.options = self.options.asc(); + self + } + + /// Sets the file service name to search in + pub fn file_service_name(mut self, service: ServiceName) -> Self { + self.options = self.options.file_service_name(service); + self + } + + /// Sets the tag service to search by + pub fn tag_service_name(mut self, service: ServiceName) -> Self { + self.options = self.options.tag_service_name(service); + self + } + + /// Sets the file service key. This option is preferred over + /// setting it by name because it's faster + pub fn file_service_key(mut self, key: S) -> Self { + self.options = self.options.file_service_key(key); + self + } + + /// Sets the tag service key. This option is preferred over + /// setting it by name because it's faster + pub fn tag_service_key(mut self, key: S) -> Self { + self.options = self.options.tag_service_key(key); + self + } + + /// Runs the search + pub async fn run(self) -> Result> { + let client = self.client.clone(); + let response = client + .search_files(tag_list_to_string_list(self.tags), self.options) + .await?; + let files = response + .file_ids + .into_iter() + .map(|id| HydrusFile::from_id(client.clone(), id)) + .collect(); + + Ok(files) + } +} diff --git a/src/wrapper/hydrus.rs b/src/wrapper/hydrus.rs index 390e92f..031ee28 100644 --- a/src/wrapper/hydrus.rs +++ b/src/wrapper/hydrus.rs @@ -1,14 +1,12 @@ use crate::api_core::common::FileIdentifier; -use crate::api_core::searching_and_fetching_files::FileSearchOptions; use crate::error::Result; -use crate::utils::tag_list_to_string_list; use crate::wrapper::address::Address; use crate::wrapper::builders::import_builder::ImportBuilder; +use crate::wrapper::builders::search_builder::SearchBuilder; use crate::wrapper::builders::tagging_builder::TaggingBuilder; use crate::wrapper::hydrus_file::HydrusFile; use crate::wrapper::page::HydrusPage; use crate::wrapper::service::Services; -use crate::wrapper::tag::Tag; use crate::wrapper::url::Url; use crate::wrapper::version::Version; use crate::Client; @@ -83,19 +81,9 @@ impl Hydrus { TaggingBuilder::new(self.client.clone()) } - /// Searches for files that have the given tags and returns a list of hydrus files as a result - pub async fn search(&self, tags: Vec) -> Result> { - let search_result = self - .client - .search_files(tag_list_to_string_list(tags), FileSearchOptions::new()) - .await?; - let files = search_result - .file_ids - .into_iter() - .map(|id| HydrusFile::from_id(self.client.clone(), id)) - .collect(); - - Ok(files) + /// Starts a request to search for files + pub fn search(&self) -> SearchBuilder { + SearchBuilder::new(self.client.clone()) } /// Returns a hydrus page by page key diff --git a/tests/wrapper/test_hydrus.rs b/tests/wrapper/test_hydrus.rs index 525c203..e4866b8 100644 --- a/tests/wrapper/test_hydrus.rs +++ b/tests/wrapper/test_hydrus.rs @@ -1,5 +1,6 @@ use super::super::common; use hydrus_api::api_core::adding_tags::TagAction; +use hydrus_api::wrapper::builders::search_builder::SortType; use hydrus_api::wrapper::service::{ServiceName, ServiceType}; use hydrus_api::wrapper::url::UrlType; @@ -36,7 +37,10 @@ async fn it_retrieves_url_information() { async fn it_searches() { let hydrus = common::get_hydrus(); hydrus - .search(vec!["character:megumin".into()]) + .search() + .add_tag("character:megumin".into()) + .sort_by(SortType::ModifiedTime) + .run() .await .unwrap(); } diff --git a/tests/wrapper/test_tags.rs b/tests/wrapper/test_tags.rs index e51e3a6..5d0580c 100644 --- a/tests/wrapper/test_tags.rs +++ b/tests/wrapper/test_tags.rs @@ -10,7 +10,7 @@ use hydrus_api::wrapper::tag::Tag; async fn retrieve_single_tag(tag: Tag) -> Result<()> { let hydrus = common::get_hydrus(); - hydrus.search(vec![tag]).await?; + hydrus.search().add_tag(tag).run().await?; Ok(()) } From 9d80486662020d4fbed6ee3451918966017bef58 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sat, 14 Aug 2021 15:28:09 +0200 Subject: [PATCH 6/7] Add search function to hydrus service Signed-off-by: trivernis --- src/wrapper/service.rs | 17 +++++++++++++++++ tests/wrapper/mod.rs | 5 +++-- tests/wrapper/test_service.rs | 27 +++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 tests/wrapper/test_service.rs diff --git a/src/wrapper/service.rs b/src/wrapper/service.rs index d2ed66e..f85998e 100644 --- a/src/wrapper/service.rs +++ b/src/wrapper/service.rs @@ -6,6 +6,7 @@ use crate::api_core::access_management::{ }; use crate::error::Error; +use crate::wrapper::builders::search_builder::SearchBuilder; use crate::Client; use std::collections::HashMap; use std::convert::TryFrom; @@ -103,6 +104,22 @@ pub struct Service { pub service_type: ServiceType, } +impl Service { + pub fn search(&self) -> SearchBuilder { + let builder = SearchBuilder::new(self.client.clone()); + match self.service_type { + ServiceType::LocalTags | ServiceType::TagRepositories | ServiceType::AllKnownTags => { + builder.tag_service_key(&self.key) + } + ServiceType::LocalFiles + | ServiceType::FileRepositories + | ServiceType::AllLocalFiles + | ServiceType::AllKnownFiles + | ServiceType::Trash => builder.file_service_key(&self.key), + } + } +} + #[derive(Clone)] pub struct Services { inner: HashMap>, diff --git a/tests/wrapper/mod.rs b/tests/wrapper/mod.rs index 9102ce3..dc843f3 100644 --- a/tests/wrapper/mod.rs +++ b/tests/wrapper/mod.rs @@ -1,7 +1,8 @@ +mod test_address; mod test_files; mod test_hydrus; mod test_import; -mod test_url; mod test_page; -mod test_address; +mod test_service; mod test_tags; +mod test_url; diff --git a/tests/wrapper/test_service.rs b/tests/wrapper/test_service.rs new file mode 100644 index 0000000..8949675 --- /dev/null +++ b/tests/wrapper/test_service.rs @@ -0,0 +1,27 @@ +use super::super::common; +use hydrus_api::wrapper::service::{Service, ServiceType, Services}; + +async fn get_services() -> Services { + let hydrus = common::get_hydrus(); + hydrus.services().await.unwrap() +} + +async fn get_file_service() -> Service { + let services = get_services().await; + services + .get_services(ServiceType::LocalFiles) + .pop() + .unwrap() + .clone() +} + +#[tokio::test] +async fn it_searches_for_files() { + let service = get_file_service().await; + service + .search() + .add_tag("character:rimuru tempest".into()) + .run() + .await + .unwrap(); +} From daffe24734e6b7b8a24ab6a2074d627012e1f84e Mon Sep 17 00:00:00 2001 From: trivernis Date: Sat, 14 Aug 2021 15:35:38 +0200 Subject: [PATCH 7/7] Increment version and update documentation Signed-off-by: trivernis --- Cargo.toml | 2 +- README.md | 12 +++++++----- src/lib.rs | 13 ++++++++----- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a4f09d6..6f3c35f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydrus-api" -version = "0.4.0" +version = "0.5.0" authors = ["trivernis "] edition = "2018" license = "Apache-2.0" diff --git a/README.md b/README.md index 9041978..04d2258 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ use hydrus_api::wrapper::tag::Tag; use hydrus_api::wrapper::service::ServiceName; use hydrus_api::wrapper::hydrus_file::FileStatus; use hydrus_api::wrapper::page::PageIdentifier; +use hydrus_api::wrapper::builders::search_builder::SortType; use hydrus_api::wrapper::builders::tag_builder::{ SystemTagBuilder, Comparator }; @@ -33,11 +34,12 @@ async fn main() { let access_key = env::var("HYDRUS_ACCESS_KEY").unwrap(); let hydrus = Hydrus::new(Client::new(hydrus_url, access_key)); - let files = hydrus.search(vec![ - Tag::from("character:megumin"), - SystemTagBuilder::new().archive().build(), - SystemTagBuilder::new().number_of_tags(Comparator::Greater, 12).build(), - ]).await.unwrap(); + let files = hydrus.search() + .add_tag(Tag::from("character:megumin")) + .add_tag(SystemTagBuilder::new().archive().build()) + .add_tag(SystemTagBuilder::new().number_of_tags(Comparator::Greater, 12).build()) + .sort(SortType::ModifiedTime) + .run().await.unwrap(); for mut file in files { file.add_tags(ServiceName::my_tags(), vec![Tag::from("ark mage")]).await.unwrap(); diff --git a/src/lib.rs b/src/lib.rs index e42b011..c9f8f5f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,17 +13,20 @@ //! use hydrus_api::wrapper::hydrus_file::FileStatus; //! use hydrus_api::wrapper::page::PageIdentifier; //! use hydrus_api::wrapper::builders::tag_builder::{SystemTagBuilder, Comparator}; +//! use hydrus_api::wrapper::builders::search_builder::SortType; //! //! # #[tokio::test] //! # async fn doctest() { //! let hydrus_url = env::var("HYDRUS_URL").unwrap(); //! let access_key = env::var("HYDRUS_ACCESS_KEY").unwrap(); //! let hydrus = Hydrus::new(Client::new(hydrus_url, access_key)); -//! let files = hydrus.search(vec![ -//! Tag::from("character:megumin"), -//! SystemTagBuilder::new().archive().build(), -//! SystemTagBuilder::new().tag_namespace_as_number("page", Comparator::Equal, 5).negate().build(), -//! ]).await.unwrap(); +//! let files = hydrus.search() +//! .add_tag(Tag::from("character:megumin")) +//! .add_tag(SystemTagBuilder::new().archive().build()) +//! .add_tag(SystemTagBuilder::new().tag_namespace_as_number("page", Comparator::Equal, 5).negate().build()) +//! .sort_by(SortType::NumberOfPixels) +//! .sort_descending() +//! .run().await.unwrap(); //! //! for mut file in files { //! file.add_tags(ServiceName::my_tags(), vec![Tag::from("ark mage")]).await.unwrap();