Implement api to get tags for a list of file hashes

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/4/head
trivernis 3 years ago
parent 1c633d9581
commit 20f75d0983

@ -828,8 +828,8 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]] [[package]]
name = "mediarepo-api" name = "mediarepo-api"
version = "0.1.0" version = "0.2.0"
source = "git+https://github.com/Trivernis/mediarepo-api.git?rev=faf363da10c22cb2d7262ed7fe27301583fcbb9a#faf363da10c22cb2d7262ed7fe27301583fcbb9a" source = "git+https://github.com/Trivernis/mediarepo-api.git?rev=ea72553cd5284e785abea815d6d6b9ad262d880a#ea72553cd5284e785abea815d6d6b9ad262d880a"
dependencies = [ dependencies = [
"chrono", "chrono",
"serde", "serde",

@ -110,7 +110,7 @@ impl Repo {
.map(|t| parse_namespace_and_tag(t.0.clone())) .map(|t| parse_namespace_and_tag(t.0.clone()))
.collect(); .collect();
let db_tags = self.find_all_tags(parsed_tags).await?; let db_tags = self.all_tags(parsed_tags).await?;
let tag_map: HashMap<String, bool> = HashMap::from_iter(tags.into_iter()); let tag_map: HashMap<String, bool> = HashMap::from_iter(tags.into_iter());
let tag_ids: Vec<(i64, bool)> = db_tags let tag_ids: Vec<(i64, bool)> = db_tags
@ -197,10 +197,16 @@ impl Repo {
/// Finds all tags by name /// Finds all tags by name
#[tracing::instrument(level = "debug", skip(self))] #[tracing::instrument(level = "debug", skip(self))]
pub async fn find_all_tags(&self, tags: Vec<(Option<String>, String)>) -> RepoResult<Vec<Tag>> { pub async fn all_tags(&self, tags: Vec<(Option<String>, String)>) -> RepoResult<Vec<Tag>> {
Tag::all_by_name(self.db.clone(), tags).await Tag::all_by_name(self.db.clone(), tags).await
} }
/// Finds all tags that are assigned to the given list of hashes
#[tracing::instrument(level = "debug", skip_all)]
pub async fn find_tags_for_hashes(&self, hashes: Vec<String>) -> RepoResult<Vec<Tag>> {
Tag::for_hash_list(self.db.clone(), hashes).await
}
/// Adds or finds a tag /// Adds or finds a tag
#[tracing::instrument(level = "debug", skip(self))] #[tracing::instrument(level = "debug", skip(self))]
pub async fn add_or_find_tag<S: ToString + Debug>(&self, tag: S) -> RepoResult<Tag> { pub async fn add_or_find_tag<S: ToString + Debug>(&self, tag: S) -> RepoResult<Tag> {

@ -1,10 +1,13 @@
use crate::namespace::Namespace; use crate::namespace::Namespace;
use mediarepo_core::error::RepoResult; use mediarepo_core::error::RepoResult;
use mediarepo_database::entities::hash;
use mediarepo_database::entities::hash_tag;
use mediarepo_database::entities::namespace; use mediarepo_database::entities::namespace;
use mediarepo_database::entities::tag; use mediarepo_database::entities::tag;
use sea_orm::prelude::*; use sea_orm::prelude::*;
use sea_orm::sea_query::Expr; use sea_orm::sea_query::Expr;
use sea_orm::{Condition, DatabaseConnection, Set}; use sea_orm::QuerySelect;
use sea_orm::{Condition, DatabaseConnection, JoinType, Set};
use std::fmt::Debug; use std::fmt::Debug;
#[derive(Clone)] #[derive(Clone)]
@ -101,6 +104,27 @@ impl Tag {
Ok(tags) Ok(tags)
} }
/// Returns all tags that are assigned to any of the passed hashes
#[tracing::instrument(level = "debug", skip_all)]
pub async fn for_hash_list(
db: DatabaseConnection,
hashes: Vec<String>,
) -> RepoResult<Vec<Self>> {
let tags: Vec<Self> = tag::Entity::find()
.find_also_related(namespace::Entity)
.join(JoinType::LeftJoin, hash_tag::Relation::Tag.def().rev())
.join(JoinType::InnerJoin, hash_tag::Relation::Hash.def())
.filter(hash::Column::Value.is_in(hashes))
.group_by(tag::Column::Id)
.all(&db)
.await?
.into_iter()
.map(|(t, n)| Self::new(db.clone(), t, n))
.collect();
Ok(tags)
}
/// Adds a new tag to the database /// Adds a new tag to the database
#[tracing::instrument(level = "debug", skip(db))] #[tracing::instrument(level = "debug", skip(db))]
pub async fn add<S: ToString + Debug>( pub async fn add<S: ToString + Debug>(

@ -769,8 +769,8 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]] [[package]]
name = "mediarepo-api" name = "mediarepo-api"
version = "0.1.0" version = "0.2.0"
source = "git+https://github.com/Trivernis/mediarepo-api.git?rev=faf363da10c22cb2d7262ed7fe27301583fcbb9a#faf363da10c22cb2d7262ed7fe27301583fcbb9a" source = "git+https://github.com/Trivernis/mediarepo-api.git?rev=ea72553cd5284e785abea815d6d6b9ad262d880a#ea72553cd5284e785abea815d6d6b9ad262d880a"
dependencies = [ dependencies = [
"chrono", "chrono",
"serde", "serde",

@ -33,4 +33,4 @@ features = ["tokio-executor"]
[dependencies.mediarepo-api] [dependencies.mediarepo-api]
git = "https://github.com/Trivernis/mediarepo-api.git" git = "https://github.com/Trivernis/mediarepo-api.git"
rev = "faf363da10c22cb2d7262ed7fe27301583fcbb9a" rev = "ea72553cd5284e785abea815d6d6b9ad262d880a"

@ -1,6 +1,6 @@
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};
use mediarepo_api::types::files::GetFileTagsRequest; use mediarepo_api::types::files::{GetFileTagsRequest, GetFilesTagsRequest};
use mediarepo_api::types::tags::TagResponse; use mediarepo_api::types::tags::TagResponse;
use mediarepo_core::rmp_ipc::prelude::*; use mediarepo_core::rmp_ipc::prelude::*;
@ -14,7 +14,8 @@ impl NamespaceProvider for TagsNamespace {
fn register(handler: &mut EventHandler) { fn register(handler: &mut EventHandler) {
events!(handler, events!(handler,
"all_tags" => Self::all_tags, "all_tags" => Self::all_tags,
"tags_for_file" => Self::tags_for_file "tags_for_file" => Self::tags_for_file,
"tags_for_files" => Self::tags_for_files
); );
} }
} }
@ -52,4 +53,22 @@ impl TagsNamespace {
Ok(()) Ok(())
} }
/// Returns all tags for a given list of file hashes
#[tracing::instrument(skip_all)]
async fn tags_for_files(ctx: &Context, event: Event) -> IPCResult<()> {
let repo = get_repo_from_context(ctx).await;
let request = event.data::<GetFilesTagsRequest>()?;
let tag_responses: Vec<TagResponse> = repo
.find_tags_for_hashes(request.hashes)
.await?
.into_iter()
.map(TagResponse::from_model)
.collect();
ctx.emitter
.emit_response_to(event.id(), Self::name(), "tags_for_files", tag_responses)
.await?;
Ok(())
}
} }

@ -233,7 +233,7 @@ async fn add_tags_from_tags_file(
log::info!("Adding tags"); log::info!("Adding tags");
if tags_path.exists() { if tags_path.exists() {
let mut tags = parse_tags_file(tags_path).await?; let mut tags = parse_tags_file(tags_path).await?;
let resolved_tags = repo.find_all_tags(tags.clone()).await?; let resolved_tags = repo.all_tags(tags.clone()).await?;
tags.retain(|tag| { tags.retain(|tag| {
resolved_tags resolved_tags
.iter() .iter()

Loading…
Cancel
Save