Add support for adding tags to services by service keys

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/9/head
trivernis 2 years ago
parent be51ac4054
commit 7260eb825a
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -1,3 +1,4 @@
use crate::api_core::common::ServiceIdentifier;
use crate::api_core::Endpoint;
use std::collections::HashMap;
@ -21,7 +22,9 @@ impl Endpoint for CleanTags {
pub struct AddTagsRequest {
pub hashes: Vec<String>,
pub service_names_to_tags: HashMap<String, Vec<String>>,
pub service_keys_to_tags: HashMap<String, Vec<String>>,
pub service_names_to_actions_to_tags: HashMap<String, HashMap<String, Vec<String>>>,
pub service_keys_to_actions_to_tags: HashMap<String, HashMap<String, Vec<String>>>,
}
pub struct AddTags;
@ -35,10 +38,13 @@ impl Endpoint for AddTags {
}
}
#[derive(Default)]
pub struct AddTagsRequestBuilder {
hashes: Vec<String>,
service_names_to_tags: HashMap<String, Vec<String>>,
service_keys_to_tags: HashMap<String, Vec<String>>,
service_names_to_actions_to_tags: HashMap<String, HashMap<String, Vec<String>>>,
service_keys_to_actions_to_tags: HashMap<String, HashMap<String, Vec<String>>>,
}
/// List of actions for a given tag
@ -78,16 +84,6 @@ impl TagAction {
}
}
impl Default for AddTagsRequestBuilder {
fn default() -> Self {
Self {
hashes: vec![],
service_names_to_tags: Default::default(),
service_names_to_actions_to_tags: Default::default(),
}
}
}
impl AddTagsRequestBuilder {
/// Adds a file hash to the request
pub fn add_hash<S: AsRef<str>>(mut self, hash: S) -> Self {
@ -104,41 +100,48 @@ impl AddTagsRequestBuilder {
}
/// Adds a single tag for a given service
pub fn add_tag<S1: AsRef<str>, S2: AsRef<str>>(mut self, service_name: S1, tag: S2) -> Self {
if let Some(mappings) = self.service_names_to_tags.get_mut(service_name.as_ref()) {
pub fn add_tag<S: AsRef<str>>(mut self, service_id: ServiceIdentifier, tag: S) -> Self {
let (service, relevant_mappings) = match service_id {
ServiceIdentifier::Name(name) => (name, &mut self.service_names_to_tags),
ServiceIdentifier::Key(key) => (key, &mut self.service_keys_to_tags),
};
if let Some(mappings) = relevant_mappings.get_mut(&service) {
mappings.push(tag.as_ref().into())
} else {
self.service_names_to_tags
.insert(service_name.as_ref().into(), vec![tag.as_ref().into()]);
relevant_mappings.insert(service, vec![tag.as_ref().into()]);
}
self
}
/// Adds multiple tags for a given service
pub fn add_tags<S1: AsRef<str>>(mut self, service_name: S1, mut tags: Vec<String>) -> Self {
if let Some(mappings) = self.service_names_to_tags.get_mut(service_name.as_ref()) {
pub fn add_tags(mut self, service_id: ServiceIdentifier, mut tags: Vec<String>) -> Self {
let (service, relevant_mappings) = match service_id {
ServiceIdentifier::Name(name) => (name, &mut self.service_names_to_tags),
ServiceIdentifier::Key(key) => (key, &mut self.service_keys_to_tags),
};
if let Some(mappings) = relevant_mappings.get_mut(&service) {
mappings.append(&mut tags);
} else {
self.service_names_to_tags
.insert(service_name.as_ref().into(), tags);
relevant_mappings.insert(service, tags);
}
self
}
/// Adds one tag for a given service with a defined action
pub fn add_tag_with_action<S1: AsRef<str>, S2: AsRef<str>>(
pub fn add_tag_with_action<S: AsRef<str>>(
mut self,
service_name: S1,
tag: S2,
service_id: ServiceIdentifier,
tag: S,
action: TagAction,
) -> Self {
let (service, relevant_mappings) = match service_id {
ServiceIdentifier::Name(name) => (name, &mut self.service_names_to_actions_to_tags),
ServiceIdentifier::Key(key) => (key, &mut self.service_keys_to_actions_to_tags),
};
let action_id = action.into_id();
if let Some(actions) = self
.service_names_to_actions_to_tags
.get_mut(service_name.as_ref())
{
if let Some(actions) = relevant_mappings.get_mut(&service) {
if let Some(tags) = actions.get_mut(&action_id.to_string()) {
tags.push(tag.as_ref().into());
} else {
@ -147,8 +150,7 @@ impl AddTagsRequestBuilder {
} else {
let mut actions = HashMap::new();
actions.insert(action_id.to_string(), vec![tag.as_ref().into()]);
self.service_names_to_actions_to_tags
.insert(service_name.as_ref().into(), actions);
relevant_mappings.insert(service, actions);
}
self
}
@ -158,7 +160,9 @@ impl AddTagsRequestBuilder {
AddTagsRequest {
hashes: self.hashes,
service_names_to_tags: self.service_names_to_tags,
service_keys_to_tags: self.service_keys_to_tags,
service_names_to_actions_to_tags: self.service_names_to_actions_to_tags,
service_keys_to_actions_to_tags: self.service_keys_to_actions_to_tags,
}
}
}

@ -228,6 +228,7 @@ impl Client {
}
/// Adds tags to files with the given hashes
#[tracing::instrument(skip(self), level = "debug")]
pub async fn add_tags(&self, request: AddTagsRequest) -> Result<()> {
self.post::<AddTags>(request).await?;

@ -6,6 +6,22 @@ pub struct BasicServiceInfo {
pub service_key: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, Hash, PartialOrd, PartialEq, Ord, Eq)]
pub enum ServiceIdentifier {
Name(String),
Key(String),
}
impl ServiceIdentifier {
pub fn name<S: ToString>(name: S) -> Self {
Self::Name(name.to_string())
}
pub fn key<S: ToString>(key: S) -> Self {
Self::Key(key.to_string())
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BasicHashList {
pub hashes: Vec<String>,

@ -1,6 +1,6 @@
use crate::api_core::adding_tags::{AddTagsRequestBuilder, TagAction};
use crate::api_core::common::ServiceIdentifier;
use crate::error::Result;
use crate::wrapper::service::ServiceName;
use crate::wrapper::tag::Tag;
use crate::Client;
use std::collections::HashMap;
@ -8,7 +8,7 @@ use std::collections::HashMap;
pub struct TaggingBuilder {
client: Client,
hashes: Vec<String>,
tag_mappings: HashMap<ServiceName, HashMap<TagAction, Vec<Tag>>>,
tag_mappings: HashMap<ServiceIdentifier, HashMap<TagAction, Vec<Tag>>>,
}
impl TaggingBuilder {
@ -28,12 +28,17 @@ impl TaggingBuilder {
}
/// Adds a single tag for a given service
pub fn add_tag(self, service: ServiceName, action: TagAction, tag: Tag) -> Self {
pub fn add_tag(self, service: ServiceIdentifier, action: TagAction, tag: Tag) -> Self {
self.add_tags(service, action, vec![tag])
}
/// Adds tags with actions for the given service
pub fn add_tags(mut self, service: ServiceName, action: TagAction, mut tags: Vec<Tag>) -> Self {
pub fn add_tags(
mut self,
service: ServiceIdentifier,
action: TagAction,
mut tags: Vec<Tag>,
) -> Self {
let service_action_mappings =
if let Some(service_action_mappings) = self.tag_mappings.get_mut(&service) {
service_action_mappings
@ -57,7 +62,7 @@ impl TaggingBuilder {
for (action, tags) in action_tag_mappings {
for tag in tags {
request = request.add_tag_with_action(
service.0.clone(),
service.clone().into(),
tag.to_string(),
action.clone(),
);

@ -217,7 +217,7 @@ impl HydrusFile {
let hash = self.hash().await?;
let request = AddTagsRequestBuilder::default()
.add_hash(hash)
.add_tags(service.0, tag_list_to_string_list(tags))
.add_tags(service.into(), tag_list_to_string_list(tags))
.build();
self.client.add_tags(request).await
@ -234,8 +234,11 @@ impl HydrusFile {
let mut reqwest = AddTagsRequestBuilder::default().add_hash(hash);
for tag in tags {
reqwest =
reqwest.add_tag_with_action(service.0.clone(), tag.to_string(), action.clone());
reqwest = reqwest.add_tag_with_action(
service.clone().into(),
tag.to_string(),
action.clone(),
);
}
self.client.add_tags(reqwest.build()).await

@ -5,6 +5,7 @@ use crate::api_core::access_management::{
SERVICE_TYPE_TAG_REPOSITORIES, SERVICE_TYPE_TRASH,
};
use crate::api_core::common::ServiceIdentifier;
use crate::error::Error;
use crate::wrapper::builders::search_builder::SearchBuilder;
use crate::Client;
@ -96,6 +97,12 @@ impl Display for ServiceName {
}
}
impl Into<ServiceIdentifier> for ServiceName {
fn into(self) -> ServiceIdentifier {
ServiceIdentifier::Name(self.0)
}
}
#[derive(Clone)]
pub struct Service {
client: Client,

@ -1,5 +1,6 @@
use super::super::common;
use hydrus_api::api_core::adding_tags::{AddTagsRequestBuilder, TagAction};
use hydrus_api::api_core::common::ServiceIdentifier;
#[tokio::test]
async fn it_cleans_tags() {
@ -21,8 +22,15 @@ async fn it_adds_tags() {
let client = common::get_client();
let request = AddTagsRequestBuilder::default()
.add_hash("0000000000000000000000000000000000000000000000000000000000000000") // valid hash, I hope no files are affected
.add_tags("my tags", vec!["beach".into(), "summer".into()])
.add_tag_with_action("my tags", "rain", TagAction::DeleteFromLocalService)
.add_tags(
ServiceIdentifier::name("my tags"),
vec!["beach".into(), "summer".into()],
)
.add_tag_with_action(
ServiceIdentifier::name("my tags"),
"rain",
TagAction::DeleteFromLocalService,
)
.build();
client.add_tags(request).await.unwrap();
}

@ -60,7 +60,7 @@ async fn it_adds_tags() {
hydrus
.tagging()
.add_tag(
ServiceName::my_tags(),
ServiceName::my_tags().into(),
TagAction::AddToLocalService,
"summer".into(),
)

Loading…
Cancel
Save