diff --git a/mediarepo-api/src/client_api/tag.rs b/mediarepo-api/src/client_api/tag.rs index e4b7f79..76223b9 100644 --- a/mediarepo-api/src/client_api/tag.rs +++ b/mediarepo-api/src/client_api/tag.rs @@ -1,12 +1,15 @@ -use std::collections::HashMap; use crate::client_api::error::ApiResult; use crate::client_api::IPCApi; -use crate::types::files::{GetFileTagsRequest, GetFilesTagsRequest, GetFileTagMapRequest}; +use crate::types::files::{GetFileTagMapRequest, GetFileTagsRequest, GetFilesTagsRequest}; use crate::types::identifier::FileIdentifier; -use crate::types::tags::{ChangeFileTagsRequest, NamespaceResponse, TagResponse}; +use crate::types::tags::{ + AddTagImplicationsRequest, ChangeFileTagsRequest, DeleteTagImplicationsRequest, + NamespaceResponse, TagImplication, TagResponse, +}; use async_trait::async_trait; use bromine::context::{PoolGuard, PooledContext}; use bromine::ipc::context::Context; +use std::collections::HashMap; use std::time::Duration; pub struct TagApi { @@ -75,8 +78,16 @@ impl TagApi { /// Returns a map from files to assigned tags #[tracing::instrument(level = "debug", skip_all)] - pub async fn get_file_tag_map(&self, cds: Vec) -> ApiResult>> { - self.emit_and_get("file_tag_map", GetFileTagMapRequest{cds}, Some(Duration::from_secs(10))).await + pub async fn get_file_tag_map( + &self, + cds: Vec, + ) -> ApiResult>> { + self.emit_and_get( + "file_tag_map", + GetFileTagMapRequest { cds }, + Some(Duration::from_secs(10)), + ) + .await } /// Creates a new tag and returns the created tag object @@ -105,4 +116,29 @@ impl TagApi { ) .await } + + /// Add implications for the given tags + #[tracing::instrument(level = "debug", skip(self))] + pub async fn add_tag_implications(&self, implications: Vec) -> ApiResult<()> { + self.emit_and_get( + "add_tag_implications", + AddTagImplicationsRequest { implications }, + None, + ) + .await + } + + /// Add implications for the given tags + #[tracing::instrument(level = "debug", skip(self))] + pub async fn delete_tag_implications( + &self, + implications: Vec, + ) -> ApiResult<()> { + self.emit_and_get( + "delete_tag_implications", + DeleteTagImplicationsRequest { implications }, + None, + ) + .await + } } diff --git a/mediarepo-api/src/types/tags.rs b/mediarepo-api/src/types/tags.rs index 7cc381d..2a42681 100644 --- a/mediarepo-api/src/types/tags.rs +++ b/mediarepo-api/src/types/tags.rs @@ -24,7 +24,7 @@ pub struct ChangeFileTagsRequest { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct AddTagImplicationsRequest { - pub implications: TagImplication, + pub implications: Vec, } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -34,6 +34,6 @@ pub struct TagImplication { } #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct RemoveTagImplicationsRequest { - pub implications: TagImplication, +pub struct DeleteTagImplicationsRequest { + pub implications: Vec, } diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/tag/delete_implications.rs b/mediarepo-daemon/mediarepo-logic/src/dao/tag/delete_implications.rs index a9f2ee6..b8c0e5d 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dao/tag/delete_implications.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dao/tag/delete_implications.rs @@ -2,21 +2,21 @@ use mediarepo_core::error::RepoResult; use mediarepo_database::entities::tag_implication; use sea_orm::{prelude::*, Condition}; -use crate::dto::TagImplicationDto; +use crate::dto::DeleteTagImplicationDto; use super::TagDao; impl TagDao { pub async fn delete_implications( &self, - implications: Vec, + implications: Vec, ) -> RepoResult<()> { let filter_condition = implications .into_iter() .map(|i| { Condition::all() - .add(tag_implication::Column::TagId.eq(i.tag_id())) - .add(tag_implication::Column::ImpliedTagId.eq(i.implied_tag_id())) + .add(tag_implication::Column::TagId.eq(i.tag_id)) + .add(tag_implication::Column::ImpliedTagId.eq(i.implied_tag_id)) }) .fold(Condition::any(), |acc, val| acc.add(val)); tag_implication::Entity::delete_many() diff --git a/mediarepo-daemon/mediarepo-socket/src/namespaces/tags.rs b/mediarepo-daemon/mediarepo-socket/src/namespaces/tags.rs index b3fa43a..7f6e866 100644 --- a/mediarepo-daemon/mediarepo-socket/src/namespaces/tags.rs +++ b/mediarepo-daemon/mediarepo-socket/src/namespaces/tags.rs @@ -7,11 +7,12 @@ use mediarepo_core::mediarepo_api::types::files::{ GetFileTagMapRequest, GetFileTagsRequest, GetFilesTagsRequest, }; use mediarepo_core::mediarepo_api::types::tags::{ - ChangeFileTagsRequest, NamespaceResponse, TagResponse, + AddTagImplicationsRequest, ChangeFileTagsRequest, DeleteTagImplicationsRequest, + NamespaceResponse, TagResponse, }; use mediarepo_core::utils::parse_namespace_and_tag; use mediarepo_logic::dao::DaoProvider; -use mediarepo_logic::dto::AddTagDto; +use mediarepo_logic::dto::{AddTagDto, AddTagImplicationDto, DeleteTagImplicationDto}; use crate::from_model::FromModel; use crate::utils::{file_by_identifier, get_repo_from_context}; @@ -31,7 +32,9 @@ impl NamespaceProvider for TagsNamespace { "tags_for_files" => Self::tags_for_files, "file_tag_map" => Self::tag_cd_map_for_files, "create_tags" => Self::create_tags, - "change_file_tags" => Self::change_file_tags + "change_file_tags" => Self::change_file_tags, + "add_tag_implications" => Self::add_tag_implications, + "delete_tag_implications" => Self::delete_tag_implications ); } } @@ -183,4 +186,40 @@ impl TagsNamespace { ctx.response(responses) } + + /// Adds multiple tag implications + #[tracing::instrument(skip_all)] + async fn add_tag_implications(ctx: &Context, event: Event) -> IPCResult { + let repo = get_repo_from_context(ctx).await; + let request = event.payload::()?; + let add_dtos: Vec = request + .implications + .into_iter() + .map(|i| AddTagImplicationDto { + tag_id: i.tag_id, + implied_tag_id: i.implied_tag_id, + }) + .collect(); + repo.tag().add_implications(add_dtos).await?; + + ctx.response(()) + } + + /// Deletes multiple tag implications + #[tracing::instrument(skip_all)] + async fn delete_tag_implications(ctx: &Context, event: Event) -> IPCResult { + let repo = get_repo_from_context(ctx).await; + let request = event.payload::()?; + let delete_dtos: Vec = request + .implications + .into_iter() + .map(|i| DeleteTagImplicationDto { + tag_id: i.tag_id, + implied_tag_id: i.implied_tag_id, + }) + .collect(); + repo.tag().delete_implications(delete_dtos).await?; + + ctx.response(()) + } }