Control response content type via Accept header

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/16/head
trivernis 2 years ago
parent 843135f38c
commit d4c4d9465f
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -1,6 +1,6 @@
[package] [package]
name = "hydrus-api" name = "hydrus-api"
version = "0.9.0" version = "0.9.1"
authors = ["trivernis <trivernis@protonmail.com>"] authors = ["trivernis <trivernis@protonmail.com>"]
edition = "2018" edition = "2018"
license = "Apache-2.0" license = "Apache-2.0"
@ -12,7 +12,7 @@ repository = "https://github.com/trivernis/hydrus-api-rs"
[dependencies] [dependencies]
serde = { version = "1.0.136", features = ["derive"] } serde = { version = "1.0.136", features = ["derive"] }
reqwest = { version = "0.11.10", features = ["json"]} reqwest = { version = "0.11.10"}
tracing = "0.1.32" tracing = "0.1.32"
mime = "0.3.16" mime = "0.3.16"
chrono = "0.4.19" chrono = "0.4.19"

@ -43,6 +43,8 @@ use std::fmt::Debug;
const ACCESS_KEY_HEADER: &str = "Hydrus-Client-API-Access-Key"; const ACCESS_KEY_HEADER: &str = "Hydrus-Client-API-Access-Key";
const CONTENT_TYPE_HEADER: &str = "Content-Type"; const CONTENT_TYPE_HEADER: &str = "Content-Type";
const ACCEPT_HEADER: &str = "Accept";
#[cfg(feature = "cbor")] #[cfg(feature = "cbor")]
const CONTENT_TYPE_CBOR: &str = "application/cbor"; const CONTENT_TYPE_CBOR: &str = "application/cbor";
#[cfg(feature = "json")] #[cfg(feature = "json")]
@ -455,6 +457,7 @@ impl Client {
.get(format!("{}/{}", self.base_url, E::path())) .get(format!("{}/{}", self.base_url, E::path()))
.header(ACCESS_KEY_HEADER, &self.access_key) .header(ACCESS_KEY_HEADER, &self.access_key)
.header(CONTENT_TYPE_HEADER, content_type) .header(CONTENT_TYPE_HEADER, content_type)
.header(ACCEPT_HEADER, content_type)
.query(query) .query(query)
.query(&params) .query(&params)
.send() .send()
@ -509,7 +512,8 @@ impl Client {
.post(format!("{}/{}", self.base_url, E::path())) .post(format!("{}/{}", self.base_url, E::path()))
.body(body) .body(body)
.header(ACCESS_KEY_HEADER, &self.access_key) .header(ACCESS_KEY_HEADER, &self.access_key)
.header("Content-Type", content_type) .header(CONTENT_TYPE_HEADER, content_type)
.header(ACCEPT_HEADER, content_type)
.send() .send()
.await?; .await?;
let response = Self::extract_error(response).await?; let response = Self::extract_error(response).await?;
@ -551,17 +555,24 @@ impl Client {
#[tracing::instrument(skip(self, data), level = "trace")] #[tracing::instrument(skip(self, data), level = "trace")]
async fn post_binary<E: Endpoint>(&self, data: Vec<u8>) -> Result<E::Response> { async fn post_binary<E: Endpoint>(&self, data: Vec<u8>) -> Result<E::Response> {
tracing::trace!("Binary POST request to {}", E::path()); tracing::trace!("Binary POST request to {}", E::path());
#[cfg(feature = "cbor")]
let content_type = CONTENT_TYPE_CBOR;
#[cfg(feature = "json")]
let content_type = CONTENT_TYPE_JSON;
let response = self let response = self
.inner .inner
.post(format!("{}/{}", self.base_url, E::path())) .post(format!("{}/{}", self.base_url, E::path()))
.body(data) .body(data)
.header(ACCESS_KEY_HEADER, &self.access_key) .header(ACCESS_KEY_HEADER, &self.access_key)
.header(CONTENT_TYPE_HEADER, "application/octet-stream") .header(CONTENT_TYPE_HEADER, "application/octet-stream")
.header(ACCEPT_HEADER, content_type)
.send() .send()
.await?; .await?;
let response = Self::extract_error(response).await?; let response = Self::extract_error(response).await?;
response.json::<E::Response>().await.map_err(Error::from) Self::extract_content(response).await
} }
/// Returns an error with the response text content if the status doesn't indicate success /// Returns an error with the response text content if the status doesn't indicate success

@ -192,7 +192,6 @@ pub struct FileBasicMetadata {
pub height: Option<u32>, pub height: Option<u32>,
pub duration: Option<u64>, pub duration: Option<u64>,
pub time_modified: Option<u64>, pub time_modified: Option<u64>,
pub file_services: FileMetadataServices,
pub has_audio: Option<bool>, pub has_audio: Option<bool>,
pub num_frames: Option<u64>, pub num_frames: Option<u64>,
pub num_words: Option<u64>, pub num_words: Option<u64>,
@ -205,6 +204,7 @@ pub struct FileFullMetadata {
pub is_inbox: bool, pub is_inbox: bool,
pub is_local: bool, pub is_local: bool,
pub is_trashed: bool, pub is_trashed: bool,
pub file_services: FileMetadataServices,
pub known_urls: Vec<String>, pub known_urls: Vec<String>,
#[deprecated] #[deprecated]
pub service_names_to_statuses_to_tags: HashMap<String, HashMap<String, Vec<String>>>, pub service_names_to_statuses_to_tags: HashMap<String, HashMap<String, Vec<String>>>,

@ -206,14 +206,12 @@ impl HydrusFile {
) -> Result<Option<NaiveDateTime>> { ) -> Result<Option<NaiveDateTime>> {
let metadata = self.metadata().await?; let metadata = self.metadata().await?;
let naive_time_imported = metadata let naive_time_imported = metadata
.basic_metadata
.file_services .file_services
.current .current
.get(service_key.as_ref()) .get(service_key.as_ref())
.map(|s| s.time_imported) .map(|s| s.time_imported)
.or_else(|| { .or_else(|| {
metadata metadata
.basic_metadata
.file_services .file_services
.deleted .deleted
.get(service_key.as_ref()) .get(service_key.as_ref())
@ -231,7 +229,6 @@ impl HydrusFile {
) -> Result<Option<NaiveDateTime>> { ) -> Result<Option<NaiveDateTime>> {
let metadata = self.metadata().await?; let metadata = self.metadata().await?;
let naive_time_deleted = metadata let naive_time_deleted = metadata
.basic_metadata
.file_services .file_services
.deleted .deleted
.get(service_key.as_ref()) .get(service_key.as_ref())

@ -1,9 +1,12 @@
use super::super::common; use super::super::common;
use crate::common::create_testdata;
use hydrus_api::api_core::common::FileIdentifier; use hydrus_api::api_core::common::FileIdentifier;
use hydrus_api::api_core::endpoints::searching_and_fetching_files::file_sort_type::SORT_FILE_PIXEL_COUNT; use hydrus_api::api_core::endpoints::searching_and_fetching_files::file_sort_type::SORT_FILE_PIXEL_COUNT;
use hydrus_api::api_core::endpoints::searching_and_fetching_files::{ use hydrus_api::api_core::endpoints::searching_and_fetching_files::{
BasicMetadata, FileSearchOptions, FullMetadata, Identifiers, SearchQueryEntry, BasicMetadata, FileSearchOptions, FullMetadata, Identifiers, SearchQueryEntry,
}; };
use hydrus_api::wrapper::builders::tag_builder::SystemTagBuilder;
use hydrus_api::wrapper::service::ServiceName;
#[tokio::test] #[tokio::test]
async fn is_searches_files() { async fn is_searches_files() {
@ -58,18 +61,29 @@ async fn it_fetches_file_metadata() {
#[tokio::test] #[tokio::test]
async fn it_fetches_file_metadata_by_id() { async fn it_fetches_file_metadata_by_id() {
let client = common::get_client(); let client = common::get_client();
create_testdata(&client).await;
let mut files = client
.search_files(
vec![SearchQueryEntry::Tag(
SystemTagBuilder::new().everything().build().to_string(),
)],
FileSearchOptions::default().file_service_name(ServiceName::my_files()),
)
.await
.unwrap();
let test_id = files.file_ids.pop().unwrap();
let response = client let response = client
.get_file_metadata::<Identifiers>(vec![1], vec![]) .get_file_metadata::<Identifiers>(vec![test_id], vec![])
.await; .await;
assert!(response.is_ok()); response.unwrap();
let response = client let response = client
.get_file_metadata::<BasicMetadata>(vec![1], vec![]) .get_file_metadata::<BasicMetadata>(vec![test_id], vec![])
.await; .await;
assert!(response.is_ok()); response.unwrap();
let response = client let response = client
.get_file_metadata::<FullMetadata>(vec![1], vec![]) .get_file_metadata::<FullMetadata>(vec![test_id], vec![])
.await; .await;
assert!(response.is_ok()); response.unwrap();
} }
#[tokio::test] #[tokio::test]

Loading…
Cancel
Save