add functions to delete media from specific local users
Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
parent
a79ae7d1a2
commit
6b65a8fc86
2 changed files with 51 additions and 5 deletions
|
@ -6,7 +6,7 @@ use conduit::{
|
||||||
Err, Error, Result,
|
Err, Error, Result,
|
||||||
};
|
};
|
||||||
use database::{Database, Map};
|
use database::{Database, Map};
|
||||||
use ruma::{api::client::error::ErrorKind, http_headers::ContentDisposition, Mxc, UserId};
|
use ruma::{api::client::error::ErrorKind, http_headers::ContentDisposition, Mxc, OwnedMxcUri, UserId};
|
||||||
|
|
||||||
use super::preview::UrlPreviewData;
|
use super::preview::UrlPreviewData;
|
||||||
|
|
||||||
|
@ -176,6 +176,23 @@ impl Data {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets all the MXCs associated with a user
|
||||||
|
pub(super) fn get_all_user_mxcs(&self, user_id: &UserId) -> Vec<OwnedMxcUri> {
|
||||||
|
let user_id = user_id.as_bytes().to_vec();
|
||||||
|
|
||||||
|
self.mediaid_user
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(key, user)| {
|
||||||
|
if *user == user_id {
|
||||||
|
let mxc_s = string_from_bytes(&key).ok()?;
|
||||||
|
Some(OwnedMxcUri::from(mxc_s))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets all the media keys in our database (this includes all the metadata
|
/// Gets all the media keys in our database (this includes all the metadata
|
||||||
/// associated with it such as width, height, content-type, etc)
|
/// associated with it such as width, height, content-type, etc)
|
||||||
pub(crate) fn get_all_media_keys(&self) -> Vec<Vec<u8>> { self.mediaid_file.iter().map(|(key, _)| key).collect() }
|
pub(crate) fn get_all_media_keys(&self) -> Vec<Vec<u8>> { self.mediaid_file.iter().map(|(key, _)| key).collect() }
|
||||||
|
|
|
@ -8,7 +8,11 @@ use std::{path::PathBuf, sync::Arc, time::SystemTime};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use base64::{engine::general_purpose, Engine as _};
|
use base64::{engine::general_purpose, Engine as _};
|
||||||
use conduit::{debug, debug_error, err, error, trace, utils, utils::MutexMap, Err, Result, Server};
|
use conduit::{
|
||||||
|
debug, debug_error, debug_info, err, error, trace,
|
||||||
|
utils::{self, MutexMap},
|
||||||
|
warn, Err, Result, Server,
|
||||||
|
};
|
||||||
use data::{Data, Metadata};
|
use data::{Data, Metadata};
|
||||||
use ruma::{http_headers::ContentDisposition, Mxc, OwnedMxcUri, UserId};
|
use ruma::{http_headers::ContentDisposition, Mxc, OwnedMxcUri, UserId};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
|
@ -106,6 +110,31 @@ impl Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deletes all media by the specified user
|
||||||
|
///
|
||||||
|
/// currently, this is only practical for local users
|
||||||
|
pub async fn delete_from_user(&self, user: &UserId, force: bool) -> Result<usize> {
|
||||||
|
let mxcs = self.db.get_all_user_mxcs(user);
|
||||||
|
let mut deletion_count: usize = 0;
|
||||||
|
|
||||||
|
for mxc in mxcs {
|
||||||
|
let mxc: Mxc<'_> = mxc.as_str().try_into()?;
|
||||||
|
debug_info!("Deleting MXC {mxc} by user {user} from database and filesystem");
|
||||||
|
if force {
|
||||||
|
_ = self
|
||||||
|
.delete(&mxc)
|
||||||
|
.await
|
||||||
|
.inspect_err(|e| warn!("Failed to delete {mxc} from user {user}, ignoring error: {e}"));
|
||||||
|
} else {
|
||||||
|
self.delete(&mxc).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
deletion_count = deletion_count.saturating_add(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(deletion_count)
|
||||||
|
}
|
||||||
|
|
||||||
/// Downloads a file.
|
/// Downloads a file.
|
||||||
pub async fn get(&self, mxc: &Mxc<'_>) -> Result<Option<FileMeta>> {
|
pub async fn get(&self, mxc: &Mxc<'_>) -> Result<Option<FileMeta>> {
|
||||||
if let Ok(Metadata {
|
if let Ok(Metadata {
|
||||||
|
@ -163,7 +192,7 @@ impl Service {
|
||||||
return Err!(Database("Parsed MXC URL unicode bytes from database but still is None"));
|
return Err!(Database("Parsed MXC URL unicode bytes from database but still is None"));
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("Parsed MXC key to URL: {mxc_s}");
|
debug_info!("Parsed MXC key to URL: {mxc_s}");
|
||||||
let mxc = OwnedMxcUri::from(mxc_s);
|
let mxc = OwnedMxcUri::from(mxc_s);
|
||||||
if mxc.server_name() == Ok(self.services.globals.server_name()) {
|
if mxc.server_name() == Ok(self.services.globals.server_name()) {
|
||||||
debug!("Ignoring local media MXC: {mxc}");
|
debug!("Ignoring local media MXC: {mxc}");
|
||||||
|
@ -206,11 +235,11 @@ impl Service {
|
||||||
return Err!(Database("Did not found any eligible MXCs to delete."));
|
return Err!(Database("Did not found any eligible MXCs to delete."));
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("Deleting media now in the past {user_duration:?}.");
|
debug_info!("Deleting media now in the past {user_duration:?}.");
|
||||||
let mut deletion_count: usize = 0;
|
let mut deletion_count: usize = 0;
|
||||||
for mxc in remote_mxcs {
|
for mxc in remote_mxcs {
|
||||||
let mxc: Mxc<'_> = mxc.as_str().try_into()?;
|
let mxc: Mxc<'_> = mxc.as_str().try_into()?;
|
||||||
debug!("Deleting MXC {mxc} from database and filesystem");
|
debug_info!("Deleting MXC {mxc} from database and filesystem");
|
||||||
self.delete(&mxc).await?;
|
self.delete(&mxc).await?;
|
||||||
deletion_count = deletion_count.saturating_add(1);
|
deletion_count = deletion_count.saturating_add(1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue