admin: media: Force flag on past media removal

When enabled, if a file is deemed unremovable, it skips past it and
continues deleting all other files that fit the criteria. Additionally,
fix age comparison under the same command.

Signed-off-by: Lux Aliaga <lux@nixgoat.me>
This commit is contained in:
Lux Aliaga 2024-06-07 12:53:44 -04:00 committed by June 🍓🦴
parent 8d32fb1445
commit 176d95c2a8
3 changed files with 18 additions and 6 deletions

View file

@ -164,10 +164,12 @@ pub(crate) async fn delete_list(body: Vec<&str>) -> Result<RoomMessageEventConte
)) ))
} }
pub(crate) async fn delete_past_remote_media(_body: Vec<&str>, duration: String) -> Result<RoomMessageEventContent> { pub(crate) async fn delete_past_remote_media(
_body: Vec<&str>, duration: String, force: bool,
) -> Result<RoomMessageEventContent> {
let deleted_count = services() let deleted_count = services()
.media .media
.delete_all_remote_media_at_after_time(duration) .delete_all_remote_media_at_after_time(duration, force)
.await?; .await?;
Ok(RoomMessageEventContent::text_plain(format!( Ok(RoomMessageEventContent::text_plain(format!(

View file

@ -32,6 +32,9 @@ pub(crate) enum MediaCommand {
/// - The duration (at or after), e.g. "5m" to delete all media in the /// - The duration (at or after), e.g. "5m" to delete all media in the
/// past 5 minutes /// past 5 minutes
duration: String, duration: String,
/// Continues deleting remote media if an undeletable object is found
#[arg(short, long)]
force: bool,
}, },
} }
@ -44,6 +47,7 @@ pub(crate) async fn process(command: MediaCommand, body: Vec<&str>) -> Result<Ro
MediaCommand::DeleteList => delete_list(body).await?, MediaCommand::DeleteList => delete_list(body).await?,
MediaCommand::DeletePastRemoteMedia { MediaCommand::DeletePastRemoteMedia {
duration, duration,
} => delete_past_remote_media(body, duration).await?, force,
} => delete_past_remote_media(body, duration, force).await?,
}) })
} }

View file

@ -182,7 +182,7 @@ impl Service {
/// Deletes all remote only media files in the given at or after /// Deletes all remote only media files in the given at or after
/// time/duration. Returns a u32 with the amount of media files deleted. /// time/duration. Returns a u32 with the amount of media files deleted.
pub async fn delete_all_remote_media_at_after_time(&self, time: String) -> Result<usize> { pub async fn delete_all_remote_media_at_after_time(&self, time: String, force: bool) -> Result<usize> {
let all_keys = self.db.get_all_media_keys(); let all_keys = self.db.get_all_media_keys();
let user_duration: SystemTime = match cyborgtime::parse_duration(&time) { let user_duration: SystemTime = match cyborgtime::parse_duration(&time) {
@ -258,11 +258,17 @@ impl Service {
debug!("btime is unsupported, using mtime instead"); debug!("btime is unsupported, using mtime instead");
file_metadata.modified()? file_metadata.modified()?
}, },
Err(err) => return Err(err.into()), Err(err) => {
if force {
error!("Could not delete MXC path {:?}: {:?}. Skipping...", path, err);
continue;
}
return Err(err.into());
},
}; };
debug!("File created at: {:?}", file_created_at); debug!("File created at: {:?}", file_created_at);
if file_created_at >= user_duration { if file_created_at <= user_duration {
debug!("File is within user duration, pushing to list of file paths and keys to delete."); debug!("File is within user duration, pushing to list of file paths and keys to delete.");
remote_mxcs.push(mxc.to_string()); remote_mxcs.push(mxc.to_string());
} }