You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mediarepo/mediarepo-daemon/mediarepo-logic/src/dao/file/update.rs

96 lines
3.3 KiB
Rust

use std::fmt::Debug;
use std::io::Cursor;
use std::str::FromStr;
use sea_orm::prelude::*;
use sea_orm::ActiveValue::{Set, Unchanged};
use sea_orm::{NotSet, TransactionTrait};
use mediarepo_core::error::{RepoError, RepoResult};
use mediarepo_core::fs::thumbnail_store::Dimensions;
use mediarepo_core::thumbnailer;
use mediarepo_core::thumbnailer::ThumbnailSize;
use mediarepo_database::entities::{content_descriptor, file, file_metadata};
use crate::dao::file::FileDao;
use crate::dao::opt_to_active_val;
use crate::dto::{FileDto, FileMetadataDto, ThumbnailDto, UpdateFileDto, UpdateFileMetadataDto};
impl FileDao {
#[tracing::instrument(level = "debug", skip(self))]
pub async fn update(&self, update_dto: UpdateFileDto) -> RepoResult<FileDto> {
let trx = self.ctx.db.begin().await?;
let model = file::ActiveModel {
id: Set(update_dto.id),
cd_id: update_dto.cd_id.map(Set).unwrap_or(NotSet),
mime_type: update_dto.mime_type.map(Set).unwrap_or(NotSet),
status: update_dto.status.map(|v| Set(v as i32)).unwrap_or(NotSet),
};
let file_model = model.update(&trx).await?;
let cd = file_model
.find_related(content_descriptor::Entity)
.one(&trx)
.await?
.ok_or_else(|| RepoError::from("Content descriptor not found"))?;
trx.commit().await?;
Ok(FileDto::new(file_model, cd, None))
}
#[tracing::instrument(level = "debug", skip(self))]
pub async fn update_metadata(
&self,
update_dto: UpdateFileMetadataDto,
) -> RepoResult<FileMetadataDto> {
let model = file_metadata::ActiveModel {
file_id: Unchanged(update_dto.file_id),
name: opt_to_active_val(update_dto.name),
comment: opt_to_active_val(update_dto.comment),
size: opt_to_active_val(update_dto.size),
change_time: opt_to_active_val(update_dto.change_time),
..Default::default()
};
let metadata = model.update(&self.ctx.db).await?;
Ok(FileMetadataDto::new(metadata))
}
#[tracing::instrument(level = "debug", skip(self))]
pub async fn create_thumbnails<I: IntoIterator<Item = ThumbnailSize> + Debug>(
&self,
file: &FileDto,
sizes: I,
) -> RepoResult<Vec<ThumbnailDto>> {
let bytes = self.get_bytes(file.cd()).await?;
let mime_type =
mime::Mime::from_str(file.mime_type()).unwrap_or(mime::APPLICATION_OCTET_STREAM);
let thumbnails =
thumbnailer::create_thumbnails(Cursor::new(bytes), mime_type.clone(), sizes)?;
let mut dtos = Vec::new();
for thumbnail in thumbnails {
let mut buf = Cursor::new(Vec::new());
let size = thumbnail.size();
let size = Dimensions {
height: size.1,
width: size.0,
};
thumbnail.write_png(&mut buf)?;
let path = self
.ctx
.thumbnail_storage
.add_thumbnail(file.encoded_cd(), size.clone(), &buf.into_inner())
.await?;
dtos.push(ThumbnailDto::new(
path,
file.encoded_cd(),
size,
mime_type.to_string(),
))
}
Ok(dtos)
}
}