Add event to get file tags

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/4/head
trivernis 3 years ago
parent dbe0c20f63
commit 813ddc669e

@ -1,5 +1,6 @@
use crate::file_type::FileType; use crate::file_type::FileType;
use crate::storage::Storage; use crate::storage::Storage;
use crate::tag::Tag;
use crate::thumbnail::Thumbnail; use crate::thumbnail::Thumbnail;
use chrono::{Local, NaiveDateTime}; use chrono::{Local, NaiveDateTime};
use mediarepo_core::error::{RepoError, RepoResult}; use mediarepo_core::error::{RepoError, RepoResult};
@ -10,9 +11,12 @@ use mediarepo_core::image_processing::{
use mediarepo_database::entities::file; use mediarepo_database::entities::file;
use mediarepo_database::entities::hash; use mediarepo_database::entities::hash;
use mediarepo_database::entities::hash_tag; use mediarepo_database::entities::hash_tag;
use mediarepo_database::entities::namespace;
use mediarepo_database::entities::tag;
use mime::Mime; use mime::Mime;
use sea_orm::prelude::*; use sea_orm::prelude::*;
use sea_orm::{DatabaseConnection, Set}; use sea_orm::{DatabaseConnection, Set};
use sea_orm::{JoinType, QuerySelect};
use tokio::io::BufReader; use tokio::io::BufReader;
#[derive(Clone)] #[derive(Clone)]
@ -167,6 +171,23 @@ impl File {
Thumbnail::for_file_id(self.db.clone(), self.model.id).await Thumbnail::for_file_id(self.db.clone(), self.model.id).await
} }
/// Returns the list of tags of the file
pub async fn tags(&self) -> RepoResult<Vec<Tag>> {
let tags: Vec<(tag::Model, Option<namespace::Model>)> = 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::Id.eq(self.hash.id))
.all(&self.db)
.await?;
let tags = tags
.into_iter()
.map(|(tag, namespace)| Tag::new(self.db.clone(), tag, namespace))
.collect();
Ok(tags)
}
/// Changes the name of the file /// Changes the name of the file
pub async fn set_name<S: ToString>(&mut self, name: S) -> RepoResult<()> { pub async fn set_name<S: ToString>(&mut self, name: S) -> RepoResult<()> {
let mut active_file = self.get_active_model(); let mut active_file = self.get_active_model();

@ -1,12 +1,8 @@
use crate::types::requests::{ use crate::types::requests::{AddFileRequest, GetFileThumbnailsRequest, ReadFileRequest};
AddFileRequest, FileIdentifier, GetFileThumbnailsRequest, ReadFileRequest,
};
use crate::types::responses::{FileResponse, ThumbnailResponse}; use crate::types::responses::{FileResponse, ThumbnailResponse};
use crate::utils::get_repo_from_context; use crate::utils::{file_by_identifier, get_repo_from_context};
use mediarepo_core::error::{RepoError, RepoResult}; use mediarepo_core::error::RepoError;
use mediarepo_core::rmp_ipc::prelude::*; use mediarepo_core::rmp_ipc::prelude::*;
use mediarepo_model::file::File;
use mediarepo_model::repo::Repo;
use std::path::PathBuf; use std::path::PathBuf;
use tokio::io::AsyncReadExt; use tokio::io::AsyncReadExt;
@ -31,11 +27,10 @@ impl NamespaceProvider for FilesNamespace {
impl FilesNamespace { impl FilesNamespace {
/// Returns a list of all files /// Returns a list of all files
async fn all_files(ctx: &Context, event: Event) -> IPCResult<()> { async fn all_files(ctx: &Context, event: Event) -> IPCResult<()> {
let files = {
let repo = get_repo_from_context(ctx).await; let repo = get_repo_from_context(ctx).await;
repo.files().await? let files = repo.files().await?;
};
let responses: Vec<FileResponse> = files.into_iter().map(FileResponse::from).collect(); let responses: Vec<FileResponse> = files.into_iter().map(FileResponse::from).collect();
ctx.emitter ctx.emitter
.emit_response_to(event.id(), Self::name(), "all_files", responses) .emit_response_to(event.id(), Self::name(), "all_files", responses)
.await?; .await?;
@ -115,11 +110,3 @@ impl FilesNamespace {
Ok(()) Ok(())
} }
} }
async fn file_by_identifier(identifier: FileIdentifier, repo: &Repo) -> RepoResult<File> {
let file = match identifier {
FileIdentifier::ID(id) => repo.file_by_id(id).await,
FileIdentifier::Hash(hash) => repo.file_by_hash(hash).await,
}?;
file.ok_or_else(|| RepoError::from("Thumbnail not found"))
}

@ -1,5 +1,6 @@
use crate::types::requests::GetFileTagsRequest;
use crate::types::responses::TagResponse; use crate::types::responses::TagResponse;
use crate::utils::get_repo_from_context; use crate::utils::{file_by_identifier, get_repo_from_context};
use mediarepo_core::rmp_ipc::prelude::*; use mediarepo_core::rmp_ipc::prelude::*;
pub struct TagsNamespace; pub struct TagsNamespace;
@ -11,7 +12,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
); );
} }
} }
@ -32,4 +34,19 @@ impl TagsNamespace {
Ok(()) Ok(())
} }
/// Returns all tags for a single file
async fn tags_for_file(ctx: &Context, event: Event) -> IPCResult<()> {
let repo = get_repo_from_context(ctx).await;
let request = event.data::<GetFileTagsRequest>()?;
let file = file_by_identifier(request, &repo).await?;
let tags = file.tags().await?;
let responses: Vec<TagResponse> = tags.into_iter().map(TagResponse::from).collect();
ctx.emitter
.emit_response_to(event.id(), Self::name(), "tags_for_file", responses)
.await?;
Ok(())
}
} }

@ -13,3 +13,4 @@ pub enum FileIdentifier {
pub type ReadFileRequest = FileIdentifier; pub type ReadFileRequest = FileIdentifier;
pub type GetFileThumbnailsRequest = FileIdentifier; pub type GetFileThumbnailsRequest = FileIdentifier;
pub type GetFileTagsRequest = FileIdentifier;

@ -1,4 +1,7 @@
use crate::types::requests::FileIdentifier;
use mediarepo_core::error::{RepoError, RepoResult};
use mediarepo_core::rmp_ipc::ipc::context::Context; use mediarepo_core::rmp_ipc::ipc::context::Context;
use mediarepo_model::file::File;
use mediarepo_model::repo::Repo; use mediarepo_model::repo::Repo;
use mediarepo_model::type_keys::RepoKey; use mediarepo_model::type_keys::RepoKey;
use std::sync::Arc; use std::sync::Arc;
@ -8,3 +11,11 @@ pub async fn get_repo_from_context(ctx: &Context) -> Arc<Repo> {
let repo = data.get::<RepoKey>().unwrap(); let repo = data.get::<RepoKey>().unwrap();
Arc::clone(repo) Arc::clone(repo)
} }
pub async fn file_by_identifier(identifier: FileIdentifier, repo: &Repo) -> RepoResult<File> {
let file = match identifier {
FileIdentifier::ID(id) => repo.file_by_id(id).await,
FileIdentifier::Hash(hash) => repo.file_by_hash(hash).await,
}?;
file.ok_or_else(|| RepoError::from("Thumbnail not found"))
}

Loading…
Cancel
Save