diff --git a/src/api_core/client.rs b/src/api_core/client.rs index b714320..13cd91d 100644 --- a/src/api_core/client.rs +++ b/src/api_core/client.rs @@ -12,6 +12,9 @@ use crate::api_core::adding_urls::{ GetUrlFilesResponse, GetUrlInfo, GetUrlInfoResponse, }; use crate::api_core::common::{FileIdentifier, FileMetadataInfo, FileRecord}; +use crate::api_core::managing_pages::{ + FocusPage, FocusPageRequest, GetPageInfo, GetPageInfoResponse, GetPages, GetPagesResponse, +}; use crate::api_core::searching_and_fetching_files::{ FileMetadata, FileMetadataResponse, FileSearchLocation, GetFile, SearchFiles, SearchFilesResponse, @@ -307,4 +310,25 @@ impl Client { Ok(()) } + + /// Returns all pages of the client + pub async fn get_pages(&self) -> Result { + self.get_and_parse::(&()).await + } + + /// Returns information about a single page + pub async fn get_page_info>(&self, page_key: S) -> Result { + self.get_and_parse::(&[("page_key", page_key.as_ref())]) + .await + } + + /// Focuses a page in the client + pub async fn focus_page(&self, page_key: S) -> Result<()> { + self.post::(FocusPageRequest { + page_key: page_key.to_string(), + }) + .await?; + + Ok(()) + } } diff --git a/src/api_core/common.rs b/src/api_core/common.rs index 6160ee6..20c2c6c 100644 --- a/src/api_core/common.rs +++ b/src/api_core/common.rs @@ -49,3 +49,14 @@ pub struct FileRecord { pub bytes: Vec, pub mime_type: String, } + +#[derive(Clone, Debug, Deserialize)] +pub struct PageInformation { + pub name: String, + pub page_key: String, + pub page_type: u32, + #[serde(alias = "focused")] + pub selected: Option, + #[serde(default = "Vec::new")] + pub pages: Vec, +} diff --git a/src/api_core/managing_pages.rs b/src/api_core/managing_pages.rs new file mode 100644 index 0000000..49786e0 --- /dev/null +++ b/src/api_core/managing_pages.rs @@ -0,0 +1,51 @@ +use crate::api_core::common::PageInformation; +use crate::api_core::Endpoint; + +#[derive(Clone, Debug, Deserialize)] +pub struct GetPagesResponse { + /// The top level notebook page + pub pages: PageInformation, +} + +pub struct GetPages; + +impl Endpoint for GetPages { + type Request = (); + type Response = GetPagesResponse; + + fn path() -> String { + String::from("manage_pages/get_pages") + } +} + +#[derive(Clone, Debug, Deserialize)] +pub struct GetPageInfoResponse { + pub page_info: PageInformation, +} + +pub struct GetPageInfo; + +impl Endpoint for GetPageInfo { + type Request = (); + type Response = GetPageInfoResponse; + + fn path() -> String { + String::from("manage_pages/get_page_info") + } +} + +#[derive(Clone, Debug, Serialize)] +pub struct FocusPageRequest { + pub page_key: String, +} + +pub struct FocusPage; + +impl Endpoint for FocusPage { + type Request = FocusPageRequest; + type Response = (); + + fn path() -> String { + String::from("manage_pages/focus_page") + } +} diff --git a/src/api_core/mod.rs b/src/api_core/mod.rs index 222f522..f9e58a2 100644 --- a/src/api_core/mod.rs +++ b/src/api_core/mod.rs @@ -7,6 +7,7 @@ pub mod adding_tags; pub mod adding_urls; pub mod client; pub mod common; +pub mod managing_pages; pub mod searching_and_fetching_files; pub(crate) trait Endpoint { diff --git a/src/wrapper/hydrus.rs b/src/wrapper/hydrus.rs index 0cf58ab..33583b9 100644 --- a/src/wrapper/hydrus.rs +++ b/src/wrapper/hydrus.rs @@ -5,6 +5,7 @@ use crate::utils::tag_list_to_string_list; use crate::wrapper::builders::import_builder::ImportBuilder; 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; @@ -94,4 +95,24 @@ impl Hydrus { Ok(files) } + + /// Returns a hydrus page by page key + pub async fn page>(&self, page_key: S) -> Result { + let info_response = self.client.get_page_info(page_key).await?; + + Ok(HydrusPage::from_info( + self.client.clone(), + info_response.page_info, + )) + } + + /// Returns the root page in the client + pub async fn root_page(&self) -> Result { + let pages_response = self.client.get_pages().await?; + + Ok(HydrusPage::from_info( + self.client.clone(), + pages_response.pages, + )) + } } diff --git a/src/wrapper/page.rs b/src/wrapper/page.rs index de4e914..1338a49 100644 --- a/src/wrapper/page.rs +++ b/src/wrapper/page.rs @@ -1,6 +1,42 @@ +use crate::api_core::common::PageInformation; +use crate::error::Result; +use crate::Client; + #[derive(Clone)] pub struct HydrusPage { - pub id: PageIdentifier, + client: Client, + pub key: String, + pub name: String, + pub page_type: PageType, + pub children: Vec, +} + +impl HydrusPage { + pub(crate) fn from_info(client: Client, info: PageInformation) -> Self { + let children = info + .pages + .into_iter() + .map(|i| HydrusPage::from_info(client.clone(), i)) + .collect(); + + Self { + client, + key: info.page_key, + name: info.name, + page_type: PageType::from_raw_type(info.page_type), + children, + } + } + + /// Focuses the page + pub async fn focus(&self) -> Result<()> { + self.client.focus_page(&self.key).await + } + + /// Returns an identifier of the page + pub fn id(&self) -> PageIdentifier { + PageIdentifier::key(&self.key) + } } #[derive(Clone)] @@ -18,3 +54,34 @@ impl PageIdentifier { Self::Key(key.to_string()) } } + +#[derive(Clone, Debug, PartialOrd, PartialEq)] +pub enum PageType { + GalleryDownloader, + SimpleDownloader, + HardDriveImport, + Petitions, + FileSearch, + URLDownloader, + Duplicates, + ThreadWatcher, + PageOfPages, + Unknown, +} + +impl PageType { + pub(crate) fn from_raw_type(raw_type: u32) -> Self { + match raw_type { + 1 => Self::GalleryDownloader, + 2 => Self::SimpleDownloader, + 3 => Self::HardDriveImport, + 4 => Self::Petitions, + 5 => Self::FileSearch, + 6 => Self::URLDownloader, + 7 => Self::Duplicates, + 8 => Self::ThreadWatcher, + 9 => Self::PageOfPages, + _ => Self::Unknown, + } + } +} diff --git a/tests/client/mod.rs b/tests/client/mod.rs index 3c81da6..8f2f88c 100644 --- a/tests/client/mod.rs +++ b/tests/client/mod.rs @@ -2,4 +2,5 @@ mod test_access_management; mod test_adding_files; mod test_adding_tags; mod test_adding_urls; +mod test_managing_pages; mod test_searching_and_fetching_files; diff --git a/tests/client/test_managing_pages.rs b/tests/client/test_managing_pages.rs new file mode 100644 index 0000000..c787f9b --- /dev/null +++ b/tests/client/test_managing_pages.rs @@ -0,0 +1,26 @@ +use super::super::common; + +#[tokio::test] +async fn it_returns_all_pages() { + let client = common::get_client(); + client.get_pages().await.unwrap(); +} + +#[tokio::test] +async fn it_returns_page_info() { + let client = common::get_client(); + let result = client + .get_page_info("0c33d6599c22d5ec12a57b79d8c5a528ebdab7a8c2b462e6d76e2d0512e917fd") + .await; + assert!(result.is_err()); // page does not exist +} + +#[tokio::test] +async fn it_focuses_pages() { + let client = common::get_client(); + let result = client + .focus_page("0c33d6599c22d5ec12a57b79d8c5a528ebdab7a8c2b462e6d76e2d0512e917fd") + .await; + + assert!(result.is_err()); // page does not exist +} diff --git a/tests/wrapper/mod.rs b/tests/wrapper/mod.rs index 44e1c9a..2133569 100644 --- a/tests/wrapper/mod.rs +++ b/tests/wrapper/mod.rs @@ -2,3 +2,4 @@ mod test_files; mod test_hydrus; mod test_import; mod test_url; +mod test_page; diff --git a/tests/wrapper/test_page.rs b/tests/wrapper/test_page.rs new file mode 100644 index 0000000..9bcf39a --- /dev/null +++ b/tests/wrapper/test_page.rs @@ -0,0 +1,32 @@ +use super::super::common; +use hydrus_api::wrapper::page::HydrusPage; + +async fn get_page() -> HydrusPage { + let hydrus = common::get_hydrus(); + + hydrus.root_page().await.unwrap() +} + +#[tokio::test] +async fn it_can_be_focused() { + let page = get_page().await; + page.focus().await.unwrap(); +} + +#[tokio::test] +async fn it_has_a_name() { + let page = get_page().await; + assert!(page.name.len() > 0) +} + +#[tokio::test] +async fn it_has_a_key() { + let page = get_page().await; + assert!(page.key.len() > 0) +} + +#[tokio::test] +async fn it_has_a_id() { + let page = get_page().await; + page.id(); +}