Implement api to change the status of a file

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/4/head
trivernis 2 years ago
parent f627015bfb
commit ef30e38246

@ -1182,8 +1182,8 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]]
name = "mediarepo-api"
version = "0.26.0"
source = "git+https://github.com/Trivernis/mediarepo-api.git?rev=06d51ed147c4f65361f8351c30e3417ffd457f0c#06d51ed147c4f65361f8351c30e3417ffd457f0c"
version = "0.27.0"
source = "git+https://github.com/Trivernis/mediarepo-api.git?rev=9fd25e4696cdd68886fa98579aef4fa2ca561dc0#9fd25e4696cdd68886fa98579aef4fa2ca561dc0"
dependencies = [
"bromine",
"chrono",

@ -44,7 +44,7 @@ features = ["toml"]
[dependencies.mediarepo-api]
git = "https://github.com/Trivernis/mediarepo-api.git"
rev = "06d51ed147c4f65361f8351c30e3417ffd457f0c"
rev = "9fd25e4696cdd68886fa98579aef4fa2ca561dc0"
features = ["bromine"]
[features]

@ -78,6 +78,17 @@ impl FileHashStore {
Ok(())
}
pub async fn delete_file(&self, descriptor: &[u8]) -> RepoResult<()> {
let path = self.descriptor_to_file_path(descriptor);
if !path.exists() {
tracing::warn!("file {:?} doesn't exist", path);
return Ok(());
}
fs::remove_file(path).await?;
Ok(())
}
/// Scans the size of the folder
#[inline]
pub async fn get_size(&self) -> RepoResult<u64> {

@ -6,7 +6,7 @@ use std::str::FromStr;
use mediarepo_core::content_descriptor::encode_content_descriptor;
use sea_orm::prelude::*;
use sea_orm::{DatabaseConnection, Set};
use sea_orm::{ConnectionTrait, DatabaseConnection, Set};
use sea_orm::{JoinType, QuerySelect};
use tokio::io::{AsyncReadExt, BufReader};
@ -14,10 +14,12 @@ use crate::file::filter::FilterProperty;
use crate::file_metadata::FileMetadata;
use mediarepo_core::error::{RepoError, RepoResult};
use mediarepo_core::fs::file_hash_store::FileHashStore;
use mediarepo_core::mediarepo_api::types::files::FileStatus as ApiFileStatus;
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;
@ -29,6 +31,16 @@ pub enum FileStatus {
Deleted = 30,
}
impl From<ApiFileStatus> for FileStatus {
fn from(s: ApiFileStatus) -> Self {
match s {
ApiFileStatus::Imported => Self::Imported,
ApiFileStatus::Archived => Self::Archived,
ApiFileStatus::Deleted => Self::Deleted,
}
}
}
#[derive(Clone)]
pub struct File {
db: DatabaseConnection,
@ -177,6 +189,17 @@ impl File {
}
}
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> {
@ -286,4 +309,26 @@ impl File {
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(())
}
}

@ -144,6 +144,16 @@ impl Repo {
.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();
file.delete().await?;
self.main_storage.delete_file(&cd).await?;
Ok(())
}
/// Returns all thumbnails of a file
pub async fn get_file_thumbnails(&self, file_cd: &[u8]) -> RepoResult<Vec<Thumbnail>> {
let file_cd = encode_content_descriptor(file_cd);

@ -11,7 +11,7 @@ use mediarepo_core::itertools::Itertools;
use mediarepo_core::mediarepo_api::types::files::{
AddFileRequestHeader, FileBasicDataResponse, FileMetadataResponse,
GetFileThumbnailOfSizeRequest, GetFileThumbnailsRequest, ReadFileRequest,
ThumbnailMetadataResponse, UpdateFileNameRequest,
ThumbnailMetadataResponse, UpdateFileNameRequest, UpdateFileStatusRequest,
};
use mediarepo_core::mediarepo_api::types::filtering::FindFilesRequest;
use mediarepo_core::mediarepo_api::types::identifier::FileIdentifier;
@ -38,7 +38,9 @@ impl NamespaceProvider for FilesNamespace {
"get_thumbnails" => Self::thumbnails,
"get_thumbnail_of_size" => Self::get_thumbnail_of_size,
"update_file_name" => Self::update_file_name,
"delete_thumbnails" => Self::delete_thumbnails
"delete_thumbnails" => Self::delete_thumbnails,
"update_file_status" => Self::update_status,
"delete_file" => Self::delete_file
);
}
}
@ -160,11 +162,26 @@ impl FilesNamespace {
Ok(())
}
#[tracing::instrument(skip_all)]
async fn update_status(ctx: &Context, event: Event) -> IPCResult<()> {
let request = event.payload::<UpdateFileStatusRequest>()?;
let repo = get_repo_from_context(ctx).await;
let mut file = file_by_identifier(request.file_id, &repo).await?;
file.set_status(request.status.into()).await?;
ctx.emit_to(
Self::name(),
"update_file_status",
FileBasicDataResponse::from_model(file),
)
.await?;
Ok(())
}
/// Reads the binary contents of a file
#[tracing::instrument(skip_all)]
async fn read_file(ctx: &Context, event: Event) -> IPCResult<()> {
let request = event.payload::<ReadFileRequest>()?;
let repo = get_repo_from_context(ctx).await;
let file = file_by_identifier(request.id, &repo).await?;
let bytes = repo.get_file_bytes(&file).await?;
@ -175,6 +192,19 @@ impl FilesNamespace {
Ok(())
}
/// Deletes a file
#[tracing::instrument(skip_all)]
async fn delete_file(ctx: &Context, event: Event) -> IPCResult<()> {
let id = event.payload::<FileIdentifier>()?;
let repo = get_repo_from_context(ctx).await;
let file = file_by_identifier(id, &repo).await?;
repo.delete_file(file).await?;
ctx.emit_to(Self::name(), "delete_file", ()).await?;
Ok(())
}
/// Returns a list of available thumbnails of a file
#[tracing::instrument(skip_all)]
async fn thumbnails(ctx: &Context, event: Event) -> IPCResult<()> {

Loading…
Cancel
Save