diff --git a/Cargo.toml b/Cargo.toml index 20c4412..4ea2c91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,11 +12,11 @@ repository = "https://github.com/trivernis/hydrus-api-rs" [dependencies] serde = { version = "1.0.136", features = ["derive"] } -reqwest = { version = "0.11.9", features = ["json"] } -tracing = "0.1.31" +reqwest = { version = "0.11.10", features = ["json"] } +tracing = "0.1.32" mime = "0.3.16" chrono = "0.4.19" -regex = "1.5.4" +regex = "1.5.5" lazy_static = "1.4.0" [dev-dependencies] diff --git a/src/api_core/adding_notes.rs b/src/api_core/adding_notes.rs new file mode 100644 index 0000000..794d958 --- /dev/null +++ b/src/api_core/adding_notes.rs @@ -0,0 +1,73 @@ +use crate::api_core::common::FileIdentifier; +use crate::api_core::Endpoint; +use std::collections::HashMap; + +pub struct SetNotes; + +impl Endpoint for SetNotes { + type Request = SetNotesRequest; + type Response = (); + + fn path() -> String { + String::from("add_notes/set_notes") + } +} + +#[derive(Serialize, Clone, Debug, Default)] +pub struct SetNotesRequest { + notes: HashMap, + #[serde(skip_serializing_if = "Option::is_none")] + hash: Option, + #[serde(skip_serializing_if = "Option::is_none")] + file_id: Option, +} + +impl SetNotesRequest { + pub fn new(id: FileIdentifier, notes: HashMap) -> Self { + let mut request = Self { + notes, + ..Default::default() + }; + match id { + FileIdentifier::ID(id) => request.file_id = Some(id), + FileIdentifier::Hash(hash) => request.hash = Some(hash), + } + + request + } +} + +pub struct DeleteNotes; + +impl Endpoint for DeleteNotes { + type Request = DeleteNotesRequest; + type Response = (); + + fn path() -> String { + String::from("add_notes/delete_notes") + } +} + +#[derive(Serialize, Clone, Debug, Default)] +pub struct DeleteNotesRequest { + note_names: Vec, + #[serde(skip_serializing_if = "Option::is_none")] + hash: Option, + #[serde(skip_serializing_if = "Option::is_none")] + file_id: Option, +} + +impl DeleteNotesRequest { + pub fn new(id: FileIdentifier, note_names: Vec) -> Self { + let mut request = Self { + note_names, + ..Default::default() + }; + match id { + FileIdentifier::ID(id) => request.file_id = Some(id), + FileIdentifier::Hash(hash) => request.hash = Some(hash), + } + + request + } +} diff --git a/src/api_core/client.rs b/src/api_core/client.rs index 5c65472..ec4568b 100644 --- a/src/api_core/client.rs +++ b/src/api_core/client.rs @@ -6,6 +6,7 @@ use crate::api_core::adding_files::{ AddFile, AddFileRequest, AddFileResponse, ArchiveFiles, ArchiveFilesRequest, DeleteFiles, DeleteFilesRequest, UnarchiveFiles, UnarchiveFilesRequest, UndeleteFiles, UndeleteFilesRequest, }; +use crate::api_core::adding_notes::{DeleteNotes, DeleteNotesRequest, SetNotes, SetNotesRequest}; use crate::api_core::adding_tags::{AddTags, AddTagsRequest, CleanTags, CleanTagsResponse}; use crate::api_core::adding_urls::{ AddUrl, AddUrlRequest, AddUrlResponse, AssociateUrl, AssociateUrlRequest, GetUrlFiles, @@ -33,6 +34,7 @@ use crate::utils::{ use reqwest::Response; use serde::de::DeserializeOwned; use serde::Serialize; +use std::collections::HashMap; use std::fmt::Debug; static ACCESS_KEY_HEADER: &str = "Hydrus-Client-API-Access-Key"; @@ -375,6 +377,28 @@ impl Client { Ok(()) } + /// Sets the notes for the file + #[tracing::instrument(skip(self), level = "debug")] + pub async fn set_notes( + &self, + id: FileIdentifier, + notes: HashMap, + ) -> Result<()> { + self.post::(SetNotesRequest::new(id, notes)) + .await?; + + Ok(()) + } + + /// Deletes the notes of a file + #[tracing::instrument(skip(self), level = "debug")] + pub async fn delete_notes(&self, id: FileIdentifier, note_names: Vec) -> Result<()> { + self.post::(DeleteNotesRequest::new(id, note_names)) + .await?; + + Ok(()) + } + /// Returns all pages of the client #[tracing::instrument(skip(self), level = "debug")] pub async fn get_pages(&self) -> Result { diff --git a/src/api_core/common.rs b/src/api_core/common.rs index 3af1702..0d8937d 100644 --- a/src/api_core/common.rs +++ b/src/api_core/common.rs @@ -80,6 +80,22 @@ impl FileIdentifier { pub fn hash(hash: S) -> Self { Self::Hash(hash.to_string()) } + + pub fn as_hash(&self) -> Option<&String> { + if let Self::Hash(h) = &self { + Some(h) + } else { + None + } + } + + pub fn as_id(&self) -> Option { + if let Self::ID(id) = &self { + Some(*id) + } else { + None + } + } } #[derive(Clone)] diff --git a/src/api_core/mod.rs b/src/api_core/mod.rs index bf5b68c..b07f339 100644 --- a/src/api_core/mod.rs +++ b/src/api_core/mod.rs @@ -12,6 +12,7 @@ pub mod common; pub mod managing_cookies_and_http_headers; pub mod managing_pages; pub mod searching_and_fetching_files; +pub mod adding_notes; pub use searching_and_fetching_files::file_sort_type; diff --git a/tests/client/mod.rs b/tests/client/mod.rs index 8c61b9d..0ca13cf 100644 --- a/tests/client/mod.rs +++ b/tests/client/mod.rs @@ -5,3 +5,4 @@ mod test_adding_urls; mod test_managing_cookies_and_http_headers; mod test_managing_pages; mod test_searching_and_fetching_files; +mod test_deleting_notes; diff --git a/tests/client/test_deleting_notes.rs b/tests/client/test_deleting_notes.rs new file mode 100644 index 0000000..7cefad9 --- /dev/null +++ b/tests/client/test_deleting_notes.rs @@ -0,0 +1,27 @@ +use super::super::common; +use crate::common::test_data::TEST_HASH_1; +use hydrus_api::api_core::common::FileIdentifier; +use std::collections::HashMap; + +#[tokio::test] +async fn it_sets_notes() { + let client = common::get_client(); + common::create_testdata(&client).await; + let mut test_notes = HashMap::new(); + test_notes.insert("test".to_string(), "value".to_string()); + test_notes.insert("test2".to_string(), "value".to_string()); + + client + .set_notes(FileIdentifier::hash(TEST_HASH_1), test_notes) + .await + .unwrap(); +} + +#[tokio::test] +async fn it_deletes_notes() { + let client = common::get_client(); + client + .delete_notes(FileIdentifier::hash(TEST_HASH_1), vec!["test".to_string()]) + .await + .unwrap(); +}