fedimovies/src/models/cleanup.rs
2023-02-19 00:39:15 +00:00

85 lines
2.4 KiB
Rust

use mitra_config::Config;
use crate::database::{DatabaseClient, DatabaseError};
use crate::ipfs::store as ipfs_store;
use crate::media::remove_files;
pub struct DeletionQueue {
pub files: Vec<String>,
pub ipfs_objects: Vec<String>,
}
impl DeletionQueue {
pub async fn process(self, config: &Config) -> () {
remove_files(self.files, &config.media_dir());
if !self.ipfs_objects.is_empty() {
match &config.ipfs_api_url {
Some(ipfs_api_url) => {
ipfs_store::remove(ipfs_api_url, self.ipfs_objects).await
.unwrap_or_else(|err| log::error!("{}", err));
},
None => {
log::error!(
"can not remove objects because IPFS API URL is not set: {:?}",
self.ipfs_objects,
);
},
}
}
}
}
pub async fn find_orphaned_files(
db_client: &impl DatabaseClient,
files: Vec<String>,
) -> Result<Vec<String>, DatabaseError> {
let rows = db_client.query(
"
SELECT DISTINCT fname
FROM unnest($1::text[]) AS fname
WHERE
NOT EXISTS (
SELECT 1 FROM media_attachment WHERE file_name = fname
)
AND NOT EXISTS (
SELECT 1 FROM actor_profile
WHERE avatar ->> 'file_name' = fname
OR banner ->> 'file_name' = fname
)
AND NOT EXISTS (
SELECT 1 FROM emoji
WHERE image ->> 'file_name' = fname
)
",
&[&files],
).await?;
let orphaned_files = rows.iter()
.map(|row| row.try_get("fname"))
.collect::<Result<_, _>>()?;
Ok(orphaned_files)
}
pub async fn find_orphaned_ipfs_objects(
db_client: &impl DatabaseClient,
ipfs_objects: Vec<String>,
) -> Result<Vec<String>, DatabaseError> {
let rows = db_client.query(
"
SELECT DISTINCT cid
FROM unnest($1::text[]) AS cid
WHERE
NOT EXISTS (
SELECT 1 FROM media_attachment WHERE ipfs_cid = cid
)
AND NOT EXISTS (
SELECT 1 FROM post WHERE ipfs_cid = cid
)
",
&[&ipfs_objects],
).await?;
let orphaned_ipfs_objects = rows.iter()
.map(|row| row.try_get("cid"))
.collect::<Result<_, _>>()?;
Ok(orphaned_ipfs_objects)
}