Add tag implication api

Signed-off-by: trivernis <trivernis@protonmail.com>
feature/tag-implications
trivernis 2 years ago
parent 42396f2174
commit 9574cfaa5a
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -1,12 +1,15 @@
use std::collections::HashMap;
use crate::client_api::error::ApiResult; use crate::client_api::error::ApiResult;
use crate::client_api::IPCApi; 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::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 async_trait::async_trait;
use bromine::context::{PoolGuard, PooledContext}; use bromine::context::{PoolGuard, PooledContext};
use bromine::ipc::context::Context; use bromine::ipc::context::Context;
use std::collections::HashMap;
use std::time::Duration; use std::time::Duration;
pub struct TagApi { pub struct TagApi {
@ -75,8 +78,16 @@ impl TagApi {
/// Returns a map from files to assigned tags /// Returns a map from files to assigned tags
#[tracing::instrument(level = "debug", skip_all)] #[tracing::instrument(level = "debug", skip_all)]
pub async fn get_file_tag_map(&self, cds: Vec<String>) -> ApiResult<HashMap<String, Vec<TagResponse>>> { pub async fn get_file_tag_map(
self.emit_and_get("file_tag_map", GetFileTagMapRequest{cds}, Some(Duration::from_secs(10))).await &self,
cds: Vec<String>,
) -> ApiResult<HashMap<String, Vec<TagResponse>>> {
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 /// Creates a new tag and returns the created tag object
@ -105,4 +116,29 @@ impl TagApi {
) )
.await .await
} }
/// Add implications for the given tags
#[tracing::instrument(level = "debug", skip(self))]
pub async fn add_tag_implications(&self, implications: Vec<TagImplication>) -> 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<TagImplication>,
) -> ApiResult<()> {
self.emit_and_get(
"delete_tag_implications",
DeleteTagImplicationsRequest { implications },
None,
)
.await
}
} }

@ -24,7 +24,7 @@ pub struct ChangeFileTagsRequest {
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AddTagImplicationsRequest { pub struct AddTagImplicationsRequest {
pub implications: TagImplication, pub implications: Vec<TagImplication>,
} }
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
@ -34,6 +34,6 @@ pub struct TagImplication {
} }
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RemoveTagImplicationsRequest { pub struct DeleteTagImplicationsRequest {
pub implications: TagImplication, pub implications: Vec<TagImplication>,
} }

@ -2,21 +2,21 @@ use mediarepo_core::error::RepoResult;
use mediarepo_database::entities::tag_implication; use mediarepo_database::entities::tag_implication;
use sea_orm::{prelude::*, Condition}; use sea_orm::{prelude::*, Condition};
use crate::dto::TagImplicationDto; use crate::dto::DeleteTagImplicationDto;
use super::TagDao; use super::TagDao;
impl TagDao { impl TagDao {
pub async fn delete_implications( pub async fn delete_implications(
&self, &self,
implications: Vec<TagImplicationDto>, implications: Vec<DeleteTagImplicationDto>,
) -> RepoResult<()> { ) -> RepoResult<()> {
let filter_condition = implications let filter_condition = implications
.into_iter() .into_iter()
.map(|i| { .map(|i| {
Condition::all() Condition::all()
.add(tag_implication::Column::TagId.eq(i.tag_id())) .add(tag_implication::Column::TagId.eq(i.tag_id))
.add(tag_implication::Column::ImpliedTagId.eq(i.implied_tag_id())) .add(tag_implication::Column::ImpliedTagId.eq(i.implied_tag_id))
}) })
.fold(Condition::any(), |acc, val| acc.add(val)); .fold(Condition::any(), |acc, val| acc.add(val));
tag_implication::Entity::delete_many() tag_implication::Entity::delete_many()

@ -7,11 +7,12 @@ use mediarepo_core::mediarepo_api::types::files::{
GetFileTagMapRequest, GetFileTagsRequest, GetFilesTagsRequest, GetFileTagMapRequest, GetFileTagsRequest, GetFilesTagsRequest,
}; };
use mediarepo_core::mediarepo_api::types::tags::{ 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_core::utils::parse_namespace_and_tag;
use mediarepo_logic::dao::DaoProvider; use mediarepo_logic::dao::DaoProvider;
use mediarepo_logic::dto::AddTagDto; use mediarepo_logic::dto::{AddTagDto, AddTagImplicationDto, DeleteTagImplicationDto};
use crate::from_model::FromModel; use crate::from_model::FromModel;
use crate::utils::{file_by_identifier, get_repo_from_context}; 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, "tags_for_files" => Self::tags_for_files,
"file_tag_map" => Self::tag_cd_map_for_files, "file_tag_map" => Self::tag_cd_map_for_files,
"create_tags" => Self::create_tags, "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) ctx.response(responses)
} }
/// Adds multiple tag implications
#[tracing::instrument(skip_all)]
async fn add_tag_implications(ctx: &Context, event: Event) -> IPCResult<Response> {
let repo = get_repo_from_context(ctx).await;
let request = event.payload::<AddTagImplicationsRequest>()?;
let add_dtos: Vec<AddTagImplicationDto> = 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<Response> {
let repo = get_repo_from_context(ctx).await;
let request = event.payload::<DeleteTagImplicationsRequest>()?;
let delete_dtos: Vec<DeleteTagImplicationDto> = 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(())
}
} }

Loading…
Cancel
Save