diff --git a/mediarepo-daemon/mediarepo-logic/src/content_descriptor.rs b/mediarepo-daemon/mediarepo-logic/src/content_descriptor.rs deleted file mode 100644 index 2762278..0000000 --- a/mediarepo-daemon/mediarepo-logic/src/content_descriptor.rs +++ /dev/null @@ -1,101 +0,0 @@ -use crate::file::File; -use mediarepo_core::content_descriptor::convert_v1_descriptor_to_v2; -use mediarepo_core::error::RepoResult; -use mediarepo_database::entities::content_descriptor; -use mediarepo_database::entities::file; -use sea_orm::prelude::*; -use sea_orm::{DatabaseConnection, Set}; -use std::fmt::Debug; - -pub struct ContentDescriptor { - db: DatabaseConnection, - model: content_descriptor::Model, -} - -impl ContentDescriptor { - #[tracing::instrument(level = "trace")] - pub(crate) fn new(db: DatabaseConnection, model: content_descriptor::Model) -> Self { - Self { db, model } - } - - pub async fn all(db: DatabaseConnection) -> RepoResult> { - let descriptors = content_descriptor::Entity::find() - .all(&db) - .await? - .into_iter() - .map(|model| Self::new(db.clone(), model)) - .collect(); - - Ok(descriptors) - } - - /// Searches for the hash by id - #[tracing::instrument(level = "debug", skip(db))] - pub async fn by_id(db: DatabaseConnection, id: i64) -> RepoResult> { - let hash = content_descriptor::Entity::find_by_id(id) - .one(&db) - .await? - .map(|model| Self::new(db, model)); - - Ok(hash) - } - - /// Returns the hash by value - #[tracing::instrument(level = "debug", skip(db))] - pub async fn by_value + Debug>( - db: DatabaseConnection, - descriptor: D, - ) -> RepoResult> { - let cid = content_descriptor::Entity::find() - .filter(content_descriptor::Column::Descriptor.eq(descriptor.as_ref())) - .one(&db) - .await? - .map(|model| Self::new(db, model)); - - Ok(cid) - } - - /// Adds a new hash to the database - #[tracing::instrument(level = "debug", skip(db))] - pub async fn add(db: DatabaseConnection, descriptor: Vec) -> RepoResult { - let active_model = content_descriptor::ActiveModel { - descriptor: Set(descriptor), - ..Default::default() - }; - let model = active_model.insert(&db).await?; - - Ok(Self::new(db, model)) - } - - pub fn id(&self) -> i64 { - self.model.id - } - - pub fn descriptor(&self) -> &[u8] { - &self.model.descriptor[..] - } - - /// Returns the file associated with the hash - #[tracing::instrument(level = "debug", skip(self))] - pub async fn file(&self) -> RepoResult> { - let file = self - .model - .find_related(file::Entity) - .one(&self.db) - .await? - .map(|file_model| File::new(self.db.clone(), file_model, self.model.clone())); - - Ok(file) - } - - pub async fn convert_v1_to_v2(&mut self) -> RepoResult<()> { - let descriptor = convert_v1_descriptor_to_v2(&self.model.descriptor)?; - let active_model = content_descriptor::ActiveModel { - id: Set(self.id()), - descriptor: Set(descriptor), - }; - self.model = active_model.update(&self.db).await?; - - Ok(()) - } -} diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/job/mod.rs b/mediarepo-daemon/mediarepo-logic/src/dao/job/mod.rs new file mode 100644 index 0000000..e69f477 --- /dev/null +++ b/mediarepo-daemon/mediarepo-logic/src/dao/job/mod.rs @@ -0,0 +1,59 @@ +use crate::dao::{DaoContext, DaoProvider}; +use mediarepo_core::content_descriptor::{ + convert_v1_descriptor_to_v2, encode_content_descriptor, is_v1_content_descriptor, +}; +use mediarepo_core::error::RepoResult; +use mediarepo_database::entities::content_descriptor; +use sea_orm::prelude::*; +use sea_orm::ActiveValue::Set; +use sea_orm::ConnectionTrait; + +pub struct JobDao { + ctx: DaoContext, +} + +impl DaoProvider for JobDao { + fn dao_ctx(&self) -> DaoContext { + self.ctx.clone() + } +} + +impl JobDao { + pub fn new(ctx: DaoContext) -> JobDao { + Self { ctx } + } + + pub async fn migrate_content_descriptors(&self) -> RepoResult<()> { + let cds: Vec = + content_descriptor::Entity::find().all(&self.ctx.db).await?; + + tracing::info!("Converting content descriptors to v2 format..."); + let mut converted_count = 0; + + for mut cd in cds { + if is_v1_content_descriptor(&cd.descriptor) { + let trx = self.ctx.db.begin().await?; + let src_cd = cd.descriptor; + let dst_cd = convert_v1_descriptor_to_v2(&src_cd)?; + + let active_model = content_descriptor::ActiveModel { + id: Set(cd.id), + descriptor: Set(dst_cd.clone()), + }; + self.ctx.main_storage.rename_file(&src_cd, &dst_cd).await?; + self.ctx + .thumbnail_storage + .rename_parent( + encode_content_descriptor(&src_cd), + encode_content_descriptor(&dst_cd), + ) + .await?; + trx.commit().await?; + converted_count += 1; + } + } + tracing::info!("Converted {} descriptors", converted_count); + + Ok(()) + } +} diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/mod.rs b/mediarepo-daemon/mediarepo-logic/src/dao/mod.rs index 268ecce..38101a4 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dao/mod.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dao/mod.rs @@ -1,8 +1,10 @@ pub mod file; +pub mod job; pub mod repo; pub mod tag; use crate::dao::file::FileDao; +use crate::dao::job::JobDao; use crate::dao::tag::TagDao; use mediarepo_core::fs::file_hash_store::FileHashStore; use mediarepo_core::fs::thumbnail_store::ThumbnailStore; @@ -25,6 +27,10 @@ pub trait DaoProvider { fn tag(&self) -> TagDao { TagDao::new(self.dao_ctx()) } + + fn job(&self) -> JobDao { + JobDao::new(self.dao_ctx()) + } } fn opt_to_active_val>(opt: Option) -> ActiveValue { diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/repo/mod.rs b/mediarepo-daemon/mediarepo-logic/src/dao/repo/mod.rs index d0c1d5d..af954b9 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dao/repo/mod.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dao/repo/mod.rs @@ -1,18 +1,18 @@ -use crate::content_descriptor::ContentDescriptor; use crate::dao::{DaoContext, DaoProvider}; -use crate::file::File; use crate::file_metadata::FileMetadata; use crate::namespace::Namespace; use crate::tag::Tag; -use crate::thumbnail::Thumbnail; use chrono::{Local, NaiveDateTime}; -use mediarepo_core::content_descriptor::{encode_content_descriptor, is_v1_content_descriptor}; +use mediarepo_core::content_descriptor::{ + convert_v1_descriptor_to_v2, encode_content_descriptor, is_v1_content_descriptor, +}; use mediarepo_core::error::{RepoError, RepoResult}; use mediarepo_core::fs::file_hash_store::FileHashStore; use mediarepo_core::fs::thumbnail_store::{Dimensions, ThumbnailStore}; use mediarepo_core::itertools::Itertools; use mediarepo_core::thumbnailer::ThumbnailSize; use mediarepo_core::utils::parse_namespace_and_tag; +use mediarepo_database::entities::content_descriptor; use mediarepo_database::get_database; use mediarepo_database::queries::analysis::{get_all_counts, Counts}; use sea_orm::DatabaseConnection; @@ -77,158 +77,6 @@ impl Repo { FileMetadata::all_by_ids(self.db.clone(), ids).await } - /// Adds a file from bytes to the database - #[tracing::instrument(level = "debug", skip(self, content))] - pub async fn add_file( - &self, - mime_type: Option, - content: Vec, - creation_time: NaiveDateTime, - change_time: NaiveDateTime, - ) -> RepoResult { - let file_size = content.len(); - let reader = Cursor::new(content); - let cd_binary = self.main_storage.add_file(reader, None).await?; - let cd = ContentDescriptor::add(self.db.clone(), cd_binary).await?; - - let mime_type = mime_type - .and_then(|m| mime::Mime::from_str(&m).ok()) - .unwrap_or_else(|| mime::APPLICATION_OCTET_STREAM) - .to_string(); - - let file = File::add(self.db.clone(), cd.id(), mime_type).await?; - FileMetadata::add( - self.db.clone(), - file.id(), - file_size as i64, - creation_time, - change_time, - ) - .await?; - - Ok(file) - } - - /// Adds a file to the database by its readable path in the file system - #[tracing::instrument(level = "debug", skip(self))] - pub async fn add_file_by_path(&self, path: PathBuf) -> RepoResult { - let mime_type = mime_guess::from_path(&path).first().map(|m| m.to_string()); - - let mut os_file = OpenOptions::new().read(true).open(&path).await?; - let mut buf = Vec::new(); - os_file.read_to_end(&mut buf).await?; - - self.add_file( - mime_type, - buf, - Local::now().naive_local(), - Local::now().naive_local(), - ) - .await - } - - /// Deletes a file from the database and disk - #[tracing::instrument(level = "debug", skip(self, file))] - pub async fn delete_file(&self, file: File) -> RepoResult<()> { - let cd = file.cd().to_owned(); - let cd_string = file.encoded_cd(); - file.delete().await?; - self.main_storage.delete_file(&cd).await?; - self.thumbnail_storage.delete_parent(&cd_string).await?; - - Ok(()) - } - - /// Returns all thumbnails of a file - pub async fn get_file_thumbnails(&self, file_cd: &[u8]) -> RepoResult> { - let file_cd = encode_content_descriptor(file_cd); - let thumbnails = self - .thumbnail_storage - .get_thumbnails(&file_cd) - .await? - .into_iter() - .map(|(size, path)| Thumbnail { - file_hash: file_cd.to_owned(), - path, - size, - mime_type: mime::IMAGE_PNG.to_string(), - }) - .collect_vec(); - - Ok(thumbnails) - } - - pub async fn get_file_bytes(&self, file: &File) -> RepoResult> { - let mut buf = Vec::new(); - let mut reader = file.get_reader(&self.main_storage).await?; - reader.read_to_end(&mut buf).await?; - - Ok(buf) - } - - /// Creates thumbnails of all sizes for a file - #[tracing::instrument(level = "debug", skip(self, file))] - pub async fn create_thumbnails_for_file(&self, file: &File) -> RepoResult> { - let size = ThumbnailSize::Medium; - let (height, width) = size.dimensions(); - let thumbs = file.create_thumbnail(&self.main_storage, [size]).await?; - let mut created_thumbs = Vec::with_capacity(1); - - for thumb in thumbs { - let entry = self - .store_single_thumbnail(file.encoded_cd(), height, width, thumb) - .await?; - created_thumbs.push(entry); - } - - Ok(created_thumbs) - } - - #[tracing::instrument(level = "debug", skip(self, file))] - pub async fn create_file_thumbnail( - &self, - file: &File, - size: ThumbnailSize, - ) -> RepoResult { - let (height, width) = size.dimensions(); - let thumb = file - .create_thumbnail(&self.main_storage, [size]) - .await? - .pop() - .ok_or_else(|| RepoError::from("Failed to create thumbnail"))?; - let thumbnail = self - .store_single_thumbnail(file.encoded_cd(), height, width, thumb) - .await?; - - Ok(thumbnail) - } - - /// Stores a single thumbnail - async fn store_single_thumbnail( - &self, - file_hash: String, - height: u32, - width: u32, - thumb: mediarepo_core::thumbnailer::Thumbnail, - ) -> RepoResult { - let mut buf = Vec::new(); - thumb.write_png(&mut buf)?; - let size = Dimensions { height, width }; - let path = self - .thumbnail_storage - .add_thumbnail(&file_hash, size.clone(), &buf) - .await?; - - let thumbnail = Thumbnail { - file_hash, - path, - size, - mime_type: mime::IMAGE_PNG.to_string(), - }; - - Ok(thumbnail) - } - /// Returns all tags stored in the database #[tracing::instrument(level = "debug", skip(self))] pub async fn tags(&self) -> RepoResult> { @@ -386,30 +234,4 @@ impl Repo { pub async fn get_counts(&self) -> RepoResult { get_all_counts(&self.db).await } - - pub async fn migrate(&self) -> RepoResult<()> { - let cds = ContentDescriptor::all(self.db.clone()).await?; - - tracing::info!("Converting content descriptors to v2 format..."); - let mut converted_count = 0; - - for mut cd in cds { - if is_v1_content_descriptor(cd.descriptor()) { - let src_cd = cd.descriptor().to_owned(); - cd.convert_v1_to_v2().await?; - let dst_cd = cd.descriptor().to_owned(); - self.main_storage.rename_file(&src_cd, &dst_cd).await?; - self.thumbnail_storage - .rename_parent( - encode_content_descriptor(&src_cd), - encode_content_descriptor(&dst_cd), - ) - .await?; - converted_count += 1; - } - } - tracing::info!("Converted {} descriptors", converted_count); - - Ok(()) - } } diff --git a/mediarepo-daemon/mediarepo-logic/src/dto/thumbnail.rs b/mediarepo-daemon/mediarepo-logic/src/dto/thumbnail.rs index eecbfe5..2ac6166 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dto/thumbnail.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dto/thumbnail.rs @@ -1,6 +1,7 @@ use mediarepo_core::error::RepoResult; use mediarepo_core::fs::thumbnail_store::Dimensions; use std::path::PathBuf; +use tokio::fs; use tokio::fs::{File, OpenOptions}; use tokio::io::BufReader; @@ -39,4 +40,12 @@ impl ThumbnailDto { let file = OpenOptions::new().read(true).open(&self.path).await?; Ok(BufReader::new(file)) } + + /// Deletes the thumbnail + #[tracing::instrument(level = "debug")] + pub async fn delete(self) -> RepoResult<()> { + fs::remove_file(&self.path).await?; + + Ok(()) + } } diff --git a/mediarepo-daemon/mediarepo-logic/src/file/mod.rs b/mediarepo-daemon/mediarepo-logic/src/file/mod.rs deleted file mode 100644 index f76baaa..0000000 --- a/mediarepo-daemon/mediarepo-logic/src/file/mod.rs +++ /dev/null @@ -1,300 +0,0 @@ -use std::fmt::Debug; -use std::io::Cursor; -use std::str::FromStr; - -use mediarepo_core::content_descriptor::encode_content_descriptor; -use sea_orm::prelude::*; -use sea_orm::{ConnectionTrait, DatabaseConnection, Set}; -use sea_orm::{JoinType, QuerySelect}; -use tokio::io::{AsyncReadExt, BufReader}; - -use crate::dao::file::find; -use crate::dao::file::find::FilterProperty; -use crate::dto::FileStatus; -use crate::file_metadata::FileMetadata; -use mediarepo_core::error::{RepoError, RepoResult}; -use mediarepo_core::fs::file_hash_store::FileHashStore; -use mediarepo_core::thumbnailer::{self, Thumbnail as ThumbnailerThumb, ThumbnailSize}; -use mediarepo_database::entities::content_descriptor; -use mediarepo_database::entities::content_descriptor_tag; -use mediarepo_database::entities::file; -use mediarepo_database::entities::file_metadata; -use mediarepo_database::entities::namespace; -use mediarepo_database::entities::tag; - -use crate::tag::Tag; - -#[derive(Clone)] -pub struct File { - db: DatabaseConnection, - model: file::Model, - content_descriptor: content_descriptor::Model, -} - -impl File { - #[tracing::instrument(level = "trace")] - pub(crate) fn new( - db: DatabaseConnection, - model: file::Model, - hash: content_descriptor::Model, - ) -> Self { - Self { - db, - model, - content_descriptor: hash, - } - } - - /// Returns a list of all known stored files - #[tracing::instrument(level = "debug", skip(db))] - pub async fn all(db: DatabaseConnection) -> RepoResult> { - let files: Vec<(file::Model, Option)> = file::Entity::find() - .find_also_related(content_descriptor::Entity) - .all(&db) - .await?; - let files = files - .into_iter() - .filter_map(|(f, h)| { - let h = h?; - Some(Self::new(db.clone(), f, h)) - }) - .collect(); - - Ok(files) - } - - /// Fetches the file by id - #[tracing::instrument(level = "debug", skip(db))] - pub async fn by_id(db: DatabaseConnection, id: i64) -> RepoResult> { - if let Some((model, Some(hash))) = file::Entity::find_by_id(id) - .find_also_related(content_descriptor::Entity) - .one(&db) - .await? - { - let file = File::new(db, model, hash); - Ok(Some(file)) - } else { - Ok(None) - } - } - - /// Finds the file by hash - #[tracing::instrument(level = "debug", skip(db))] - pub async fn by_cd(db: DatabaseConnection, cd: &[u8]) -> RepoResult> { - if let Some((hash, Some(model))) = content_descriptor::Entity::find() - .filter(content_descriptor::Column::Descriptor.eq(cd)) - .find_also_related(file::Entity) - .one(&db) - .await? - { - let file = File::new(db, model, hash); - Ok(Some(file)) - } else { - Ok(None) - } - } - - /// Adds a file with its hash to the database - #[tracing::instrument(level = "debug", skip(db))] - pub(crate) async fn add( - db: DatabaseConnection, - cd_id: i64, - mime_type: String, - ) -> RepoResult { - let file = file::ActiveModel { - cd_id: Set(cd_id), - mime_type: Set(mime_type), - ..Default::default() - }; - let file: file::ActiveModel = file.insert(&db).await?.into(); - let file = Self::by_id(db, file.id.unwrap()) - .await? - .expect("Inserted file does not exist"); - - Ok(file) - } - - /// Returns the unique identifier of the file - pub fn id(&self) -> i64 { - self.model.id - } - - /// Returns the hash of the file (content identifier) - pub fn cd(&self) -> &[u8] { - &self.content_descriptor.descriptor - } - - /// Returns the encoded content descriptor - pub fn encoded_cd(&self) -> String { - encode_content_descriptor(self.cd()) - } - - /// Returns the id of the civ (content identifier value) of the file - pub fn cd_id(&self) -> i64 { - self.content_descriptor.id - } - - /// Returns the mime type of the file - pub fn mime_type(&self) -> &String { - &self.model.mime_type - } - - /// Returns the status of the file - pub fn status(&self) -> FileStatus { - match self.model.status { - 10 => FileStatus::Imported, - 20 => FileStatus::Archived, - 30 => FileStatus::Deleted, - _ => FileStatus::Imported, - } - } - - pub async fn set_status(&mut self, status: FileStatus) -> RepoResult<()> { - let active_model = file::ActiveModel { - id: Set(self.model.id), - status: Set(status as i32), - ..Default::default() - }; - self.model = active_model.update(&self.db).await?; - - Ok(()) - } - - /// Returns the metadata associated with this file - /// A file MUST always have metadata associated - pub async fn metadata(&self) -> RepoResult { - FileMetadata::by_id(self.db.clone(), self.model.id) - .await - .and_then(|f| f.ok_or_else(|| RepoError::from("missing file metadata"))) - } - - /// Returns the list of tags of the file - #[tracing::instrument(level = "debug", skip(self))] - pub async fn tags(&self) -> RepoResult> { - let tags: Vec<(tag::Model, Option)> = tag::Entity::find() - .find_also_related(namespace::Entity) - .join( - JoinType::LeftJoin, - content_descriptor_tag::Relation::Tag.def().rev(), - ) - .filter(content_descriptor_tag::Column::CdId.eq(self.content_descriptor.id)) - .all(&self.db) - .await?; - let tags = tags - .into_iter() - .map(|(tag, namespace)| Tag::new(self.db.clone(), tag, namespace)) - .collect(); - - Ok(tags) - } - - /// Adds a single tag to the file - #[tracing::instrument(level = "debug", skip(self))] - pub async fn add_tag(&mut self, tag_id: i64) -> RepoResult<()> { - let cd_id = self.content_descriptor.id; - let active_model = content_descriptor_tag::ActiveModel { - cd_id: Set(cd_id), - tag_id: Set(tag_id), - }; - active_model.insert(&self.db).await?; - Ok(()) - } - - /// Adds multiple tags to the file at once - #[tracing::instrument(level = "debug", skip(self))] - pub async fn add_tags(&self, tag_ids: Vec) -> RepoResult<()> { - if tag_ids.is_empty() { - return Ok(()); - } - let cd_id = self.content_descriptor.id; - let own_tag_ids = self - .tags() - .await? - .into_iter() - .map(|t| t.id()) - .collect::>(); - - let models: Vec = tag_ids - .into_iter() - .filter(|tag_id| !own_tag_ids.contains(tag_id)) - .map(|tag_id| content_descriptor_tag::ActiveModel { - cd_id: Set(cd_id), - tag_id: Set(tag_id), - }) - .collect(); - if models.len() > 0 { - content_descriptor_tag::Entity::insert_many(models) - .exec(&self.db) - .await?; - } - - Ok(()) - } - - /// Removes multiple tags from the file - #[tracing::instrument(level = "debug", skip(self))] - pub async fn remove_tags(&self, tag_ids: Vec) -> RepoResult<()> { - let hash_id = self.content_descriptor.id; - content_descriptor_tag::Entity::delete_many() - .filter(content_descriptor_tag::Column::CdId.eq(hash_id)) - .filter(content_descriptor_tag::Column::TagId.is_in(tag_ids)) - .exec(&self.db) - .await?; - - Ok(()) - } - - /// Returns the reader for the file - #[tracing::instrument(level = "debug", skip(self))] - pub async fn get_reader( - &self, - storage: &FileHashStore, - ) -> RepoResult> { - storage - .get_file(&self.content_descriptor.descriptor) - .await - .map(|(_, f)| f) - } - - /// Creates a thumbnail for the file - #[tracing::instrument(level = "debug", skip(self))] - pub async fn create_thumbnail + Debug>( - &self, - storage: &FileHashStore, - sizes: I, - ) -> RepoResult> { - let mut buf = Vec::new(); - self.get_reader(storage) - .await? - .read_to_end(&mut buf) - .await?; - let mime_type = self.model.mime_type.clone(); - let mime_type = - mime::Mime::from_str(&mime_type).unwrap_or_else(|_| mime::APPLICATION_OCTET_STREAM); - let thumbs = thumbnailer::create_thumbnails(Cursor::new(buf), mime_type, sizes)?; - - Ok(thumbs) - } - - /// Deletes the file as well as the content descriptor, tag mappings and metadata about the file - #[tracing::instrument(level = "debug", skip(self))] - pub async fn delete(self) -> RepoResult<()> { - let trx = self.db.begin().await?; - file_metadata::Entity::delete_many() - .filter(file_metadata::Column::FileId.eq(self.model.id)) - .exec(&trx) - .await?; - self.model.delete(&trx).await?; - content_descriptor_tag::Entity::delete_many() - .filter(content_descriptor_tag::Column::CdId.eq(self.content_descriptor.id)) - .exec(&trx) - .await?; - content_descriptor::Entity::delete_many() - .filter(content_descriptor::Column::Id.eq(self.content_descriptor.id)) - .exec(&trx) - .await?; - trx.commit().await?; - - Ok(()) - } -} diff --git a/mediarepo-daemon/mediarepo-logic/src/lib.rs b/mediarepo-daemon/mediarepo-logic/src/lib.rs index 817571d..1d620f5 100644 --- a/mediarepo-daemon/mediarepo-logic/src/lib.rs +++ b/mediarepo-daemon/mediarepo-logic/src/lib.rs @@ -1,9 +1,6 @@ -pub mod content_descriptor; -pub mod file; +pub mod dao; +pub mod dto; pub mod file_metadata; pub mod namespace; pub mod tag; -pub mod thumbnail; pub mod type_keys; -pub mod dto; -pub mod dao; diff --git a/mediarepo-daemon/mediarepo-logic/src/thumbnail.rs b/mediarepo-daemon/mediarepo-logic/src/thumbnail.rs deleted file mode 100644 index be45be5..0000000 --- a/mediarepo-daemon/mediarepo-logic/src/thumbnail.rs +++ /dev/null @@ -1,30 +0,0 @@ -use mediarepo_core::error::RepoResult; -use mediarepo_core::fs::thumbnail_store::Dimensions; -use std::path::PathBuf; -use tokio::fs::{self, File, OpenOptions}; -use tokio::io::BufReader; - -#[derive(Debug)] -pub struct Thumbnail { - pub file_hash: String, - pub path: PathBuf, - pub size: Dimensions, - pub mime_type: String, -} - -impl Thumbnail { - /// Returns the reader of the thumbnail file - #[tracing::instrument(level = "debug")] - pub async fn get_reader(&self) -> RepoResult> { - let file = OpenOptions::new().read(true).open(&self.path).await?; - Ok(BufReader::new(file)) - } - - /// Deletes the thumbnail - #[tracing::instrument(level = "debug")] - pub async fn delete(self) -> RepoResult<()> { - fs::remove_file(&self.path).await?; - - Ok(()) - } -} diff --git a/mediarepo-daemon/mediarepo-socket/src/from_model.rs b/mediarepo-daemon/mediarepo-socket/src/from_model.rs index bdccea0..ec96095 100644 --- a/mediarepo-daemon/mediarepo-socket/src/from_model.rs +++ b/mediarepo-daemon/mediarepo-socket/src/from_model.rs @@ -5,11 +5,9 @@ use mediarepo_core::mediarepo_api::types::tags::{NamespaceResponse, TagResponse} use mediarepo_logic::dto::{ FileDto, FileMetadataDto, FileStatus as FileStatusModel, TagDto, ThumbnailDto, }; -use mediarepo_logic::file::File; use mediarepo_logic::file_metadata::FileMetadata; use mediarepo_logic::namespace::Namespace; use mediarepo_logic::tag::Tag; -use mediarepo_logic::thumbnail::Thumbnail; pub trait FromModel { fn from_model(model: M) -> Self; @@ -41,17 +39,6 @@ impl FromModel for FileMetadataResponse { } } -impl FromModel for FileBasicDataResponse { - fn from_model(file: File) -> Self { - FileBasicDataResponse { - id: file.id(), - status: FileStatus::from_model(file.status()), - cd: file.encoded_cd(), - mime_type: file.mime_type().to_owned(), - } - } -} - impl FromModel for FileBasicDataResponse { fn from_model(model: FileDto) -> Self { FileBasicDataResponse { @@ -93,17 +80,6 @@ impl FromModel for TagResponse { } } -impl FromModel for ThumbnailMetadataResponse { - fn from_model(model: Thumbnail) -> Self { - Self { - file_hash: model.file_hash, - height: model.size.height, - width: model.size.width, - mime_type: model.mime_type.to_owned(), - } - } -} - impl FromModel for ThumbnailMetadataResponse { fn from_model(model: ThumbnailDto) -> Self { Self { diff --git a/mediarepo-daemon/mediarepo-socket/src/namespaces/files/mod.rs b/mediarepo-daemon/mediarepo-socket/src/namespaces/files/mod.rs index fdad59a..973daf4 100644 --- a/mediarepo-daemon/mediarepo-socket/src/namespaces/files/mod.rs +++ b/mediarepo-daemon/mediarepo-socket/src/namespaces/files/mod.rs @@ -350,7 +350,7 @@ impl FilesNamespace { let repo = get_repo_from_context(ctx).await; let id = event.payload::()?; let file = file_by_identifier(id, &repo).await?; - let thumbnails = repo.get_file_thumbnails(file.cd()).await?; + let thumbnails = repo.file().thumbnails(file.encoded_cd()).await?; for thumb in thumbnails { thumb.delete().await?; diff --git a/mediarepo-daemon/mediarepo-socket/src/namespaces/files/sorting.rs b/mediarepo-daemon/mediarepo-socket/src/namespaces/files/sorting.rs index 5a7972f..e80bbe1 100644 --- a/mediarepo-daemon/mediarepo-socket/src/namespaces/files/sorting.rs +++ b/mediarepo-daemon/mediarepo-socket/src/namespaces/files/sorting.rs @@ -8,7 +8,6 @@ use mediarepo_database::queries::tags::{ use mediarepo_logic::dao::repo::Repo; use mediarepo_logic::dao::DaoProvider; use mediarepo_logic::dto::{FileDto, FileMetadataDto}; -use mediarepo_logic::file::File; use mediarepo_logic::file_metadata::FileMetadata; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use std::cmp::Ordering; diff --git a/mediarepo-daemon/mediarepo-socket/src/namespaces/jobs.rs b/mediarepo-daemon/mediarepo-socket/src/namespaces/jobs.rs index 393fed8..83231bf 100644 --- a/mediarepo-daemon/mediarepo-socket/src/namespaces/jobs.rs +++ b/mediarepo-daemon/mediarepo-socket/src/namespaces/jobs.rs @@ -4,6 +4,7 @@ use mediarepo_core::error::RepoResult; use mediarepo_core::mediarepo_api::types::jobs::{JobType, RunJobRequest}; use mediarepo_core::mediarepo_api::types::repo::SizeType; use mediarepo_core::type_keys::SizeMetadataKey; +use mediarepo_logic::dao::DaoProvider; pub struct JobsNamespace; @@ -23,10 +24,10 @@ impl JobsNamespace { #[tracing::instrument(skip_all)] pub async fn run_job(ctx: &Context, event: Event) -> IPCResult<()> { let run_request = event.payload::()?; - let repo = get_repo_from_context(ctx).await; + let job_dao = get_repo_from_context(ctx).await.job(); match run_request.job_type { - JobType::MigrateContentDescriptors => repo.migrate().await?, + JobType::MigrateContentDescriptors => job_dao.migrate_content_descriptors().await?, JobType::CalculateSizes => calculate_all_sizes(ctx).await?, JobType::CheckIntegrity => {} }