diff --git a/src/database/key_value/media.rs b/src/database/key_value/media.rs index 712da165..da7162b6 100644 --- a/src/database/key_value/media.rs +++ b/src/database/key_value/media.rs @@ -39,6 +39,15 @@ impl service::media::Data for KeyValueDatabase { Ok(key) } + fn delete_file_mxc(&self, mxc: String) -> Result<()> { + let mut key = mxc.as_bytes().to_vec(); + key.push(0xff); + + self.mediaid_file.remove(&key)?; + + Ok(()) + } + fn search_file_metadata( &self, mxc: String, diff --git a/src/service/media/data.rs b/src/service/media/data.rs index 0cb7c097..667267f6 100644 --- a/src/service/media/data.rs +++ b/src/service/media/data.rs @@ -10,6 +10,8 @@ pub trait Data: Send + Sync { content_type: Option<&str>, ) -> Result>; + fn delete_file_mxc(&self, mxc: String) -> Result<()>; + /// Returns content_disposition, content_type and the metadata key. fn search_file_metadata( &self, diff --git a/src/service/media/mod.rs b/src/service/media/mod.rs index 70e1b182..7ecd7519 100644 --- a/src/service/media/mod.rs +++ b/src/service/media/mod.rs @@ -8,8 +8,9 @@ use std::{ pub(crate) use data::Data; use serde::Serialize; +use tracing::{debug, error, warn}; -use crate::{services, Result}; +use crate::{services, Error, Result}; use image::imageops::FilterType; use tokio::{ @@ -18,6 +19,7 @@ use tokio::{ sync::Mutex, }; +#[derive(Debug)] pub struct FileMeta { pub content_disposition: Option, pub content_type: Option, @@ -89,6 +91,50 @@ impl Service { Ok(()) } + /// Deletes a file in the database and from the media directory via an MXC + pub async fn delete(&self, mxc: String) -> Result<()> { + if let Ok(filemeta) = self.get(mxc.clone()).await { + match filemeta { + Some(filemeta) => { + debug!("Got file metadata: {:?}", filemeta); + let file_key = filemeta.file; + debug!("File key from file metadata: {:?}", file_key); + + let file_path = if cfg!(feature = "sha256_media") { + services().globals.get_media_file_new(&file_key) + } else { + #[allow(deprecated)] + services().globals.get_media_file(&file_key) + }; + debug!("Got local file path: {:?}", file_path); + + debug!( + "Deleting local file {:?} from filesystem, original MXC: {mxc}", + file_path + ); + tokio::fs::remove_file(file_path).await?; + + debug!("Deleting MXC {mxc} from database"); + self.db.delete_file_mxc(mxc)?; + + Ok(()) + } + None => { + warn!( + "MXC {mxc} does not exist in our database or file in MXC does not exist." + ); + Err(Error::bad_database( + "MXC does not exist in our database or file in MXC does not exist.", + )) + } + } + } else { + // we shouldn't get to this point as this is failing to actually attempt to get the file metadata (Result) + error!("Failed getting file metadata for MXC \"{mxc}\" in database (does not exist or database issue?)"); + Err(Error::bad_database("Failed getting file metadata via MXC in database (does not exist or database issue?)")) + } + } + /// Uploads or replaces a file thumbnail. pub async fn upload_thumbnail( &self,