Add CLI command for deleting unused media attachments
This commit is contained in:
parent
439959c977
commit
da6ceadd51
4 changed files with 64 additions and 3 deletions
|
@ -155,6 +155,12 @@ Remove remote posts and media older than 30 days:
|
||||||
mitractl delete-extraneous-posts -d 30
|
mitractl delete-extraneous-posts -d 30
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Delete attachments that doesn't belong to any post:
|
||||||
|
|
||||||
|
```
|
||||||
|
mitractl delete-unused-attachments -d 5
|
||||||
|
```
|
||||||
|
|
||||||
Generate ethereum address:
|
Generate ethereum address:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -8,6 +8,7 @@ use mitra::database::migrate::apply_migrations;
|
||||||
use mitra::ethereum::signatures::generate_ecdsa_key;
|
use mitra::ethereum::signatures::generate_ecdsa_key;
|
||||||
use mitra::ethereum::utils::key_to_ethereum_address;
|
use mitra::ethereum::utils::key_to_ethereum_address;
|
||||||
use mitra::logger::configure_logger;
|
use mitra::logger::configure_logger;
|
||||||
|
use mitra::models::attachments::queries::delete_unused_attachments;
|
||||||
use mitra::models::posts::queries::{delete_post, find_extraneous_posts};
|
use mitra::models::posts::queries::{delete_post, find_extraneous_posts};
|
||||||
use mitra::models::profiles::queries::delete_profile;
|
use mitra::models::profiles::queries::delete_profile;
|
||||||
use mitra::models::users::queries::{
|
use mitra::models::users::queries::{
|
||||||
|
@ -33,6 +34,7 @@ enum SubCommand {
|
||||||
DeleteProfile(DeleteProfile),
|
DeleteProfile(DeleteProfile),
|
||||||
DeletePost(DeletePost),
|
DeletePost(DeletePost),
|
||||||
DeleteExtraneousPosts(DeleteExtraneousPosts),
|
DeleteExtraneousPosts(DeleteExtraneousPosts),
|
||||||
|
DeleteUnusedAttachments(DeleteUnusedAttachments),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate RSA private key
|
/// Generate RSA private key
|
||||||
|
@ -83,6 +85,13 @@ struct DeleteExtraneousPosts {
|
||||||
dry_run: bool,
|
dry_run: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Delete attachments that doesn't belong to any post
|
||||||
|
#[derive(Parser)]
|
||||||
|
struct DeleteUnusedAttachments {
|
||||||
|
#[clap(short)]
|
||||||
|
days: i64,
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let opts: Opts = Opts::parse();
|
let opts: Opts = Opts::parse();
|
||||||
|
@ -142,6 +151,15 @@ async fn main() {
|
||||||
println!("post {} deleted", post_id);
|
println!("post {} deleted", post_id);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
SubCommand::DeleteUnusedAttachments(subopts) => {
|
||||||
|
let created_before = Utc::now() - Duration::days(subopts.days);
|
||||||
|
let deletion_queue = delete_unused_attachments(
|
||||||
|
db_client,
|
||||||
|
&created_before,
|
||||||
|
).await.unwrap();
|
||||||
|
deletion_queue.process(&config).await;
|
||||||
|
println!("unused attachments deleted");
|
||||||
|
},
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use tokio_postgres::GenericClient;
|
use tokio_postgres::GenericClient;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::errors::DatabaseError;
|
use crate::errors::DatabaseError;
|
||||||
|
use crate::models::cleanup::{
|
||||||
|
find_orphaned_files,
|
||||||
|
find_orphaned_ipfs_objects,
|
||||||
|
DeletionQueue,
|
||||||
|
};
|
||||||
use crate::utils::id::new_uuid;
|
use crate::utils::id::new_uuid;
|
||||||
use super::types::DbMediaAttachment;
|
use super::types::DbMediaAttachment;
|
||||||
|
|
||||||
|
@ -42,3 +48,32 @@ pub async fn set_attachment_ipfs_cid(
|
||||||
let db_attachment = row.try_get("media_attachment")?;
|
let db_attachment = row.try_get("media_attachment")?;
|
||||||
Ok(db_attachment)
|
Ok(db_attachment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn delete_unused_attachments(
|
||||||
|
db_client: &impl GenericClient,
|
||||||
|
created_before: &DateTime<Utc>,
|
||||||
|
) -> Result<DeletionQueue, DatabaseError> {
|
||||||
|
let rows = db_client.query(
|
||||||
|
"
|
||||||
|
DELETE FROM media_attachment
|
||||||
|
WHERE post_id IS NULL AND created_at < $1
|
||||||
|
RETURNING file_name, ipfs_cid
|
||||||
|
",
|
||||||
|
&[&created_before],
|
||||||
|
).await?;
|
||||||
|
let mut files = vec![];
|
||||||
|
let mut ipfs_objects = vec![];
|
||||||
|
for row in rows {
|
||||||
|
let file_name = row.try_get("file_name")?;
|
||||||
|
files.push(file_name);
|
||||||
|
if let Some(ipfs_cid) = row.try_get("ipfs_cid")? {
|
||||||
|
ipfs_objects.push(ipfs_cid);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
let orphaned_files = find_orphaned_files(db_client, files).await?;
|
||||||
|
let orphaned_ipfs_objects = find_orphaned_ipfs_objects(db_client, ipfs_objects).await?;
|
||||||
|
Ok(DeletionQueue {
|
||||||
|
files: orphaned_files,
|
||||||
|
ipfs_objects: orphaned_ipfs_objects,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -104,9 +104,11 @@ pub fn remove_files(files: Vec<String>, from_dir: &Path) -> () {
|
||||||
let file_path_str = file_path.to_string_lossy();
|
let file_path_str = file_path.to_string_lossy();
|
||||||
match remove_file(&file_path) {
|
match remove_file(&file_path) {
|
||||||
Ok(_) => log::info!("removed file {}", file_path_str),
|
Ok(_) => log::info!("removed file {}", file_path_str),
|
||||||
Err(_) => log::warn!("failed to remove file {}", file_path_str),
|
Err(err) => {
|
||||||
}
|
log::warn!("failed to remove file {} ({})", file_path_str, err);
|
||||||
}
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Reference in a new issue