From 5809cffa71ab07d3fd5bef312bccc59052fc7b44 Mon Sep 17 00:00:00 2001 From: silverpill Date: Mon, 16 Jan 2023 12:39:01 +0000 Subject: [PATCH] Prevent delete-extraneous-posts command from deleting post if there's a recent reply or repost --- CHANGELOG.md | 1 + src/cli.rs | 4 ++-- src/models/posts/queries.rs | 48 +++++++++++++++++++++---------------- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 138b0b3..38b6e49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Save downloaded media as "unknown" if its media type is not supported. - Use `mediaType` property value to determine file extension when saving downloaded media. - Added `mediaType` property to images in actor object. +- Prevent `delete-extraneous-posts` command from deleting post if there's a recent reply or repost. ### Removed diff --git a/src/cli.rs b/src/cli.rs index d0d4675..9f200ac 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -263,8 +263,8 @@ impl DeleteExtraneousPosts { config: &Config, db_client: &mut impl GenericClient, ) -> Result<(), Error> { - let created_before = Utc::now() - Duration::days(self.days); - let posts = find_extraneous_posts(db_client, &created_before).await?; + let updated_before = Utc::now() - Duration::days(self.days); + let posts = find_extraneous_posts(db_client, &updated_before).await?; for post_id in posts { let deletion_queue = delete_post(db_client, &post_id).await?; deletion_queue.process(config).await; diff --git a/src/models/posts/queries.rs b/src/models/posts/queries.rs index 27f24ea..2e377fa 100644 --- a/src/models/posts/queries.rs +++ b/src/models/posts/queries.rs @@ -951,40 +951,46 @@ pub async fn get_token_waitlist( } /// Finds all contexts (identified by top-level post) -/// created before the specified date +/// updated before the specified date /// that do not contain local posts, reposts, mentions, links or reactions. pub async fn find_extraneous_posts( db_client: &impl GenericClient, - created_before: &DateTime, + updated_before: &DateTime, ) -> Result, DatabaseError> { let rows = db_client.query( " - WITH RECURSIVE context (id, post_id) AS ( - SELECT post.id, post.id FROM post + WITH RECURSIVE context_post (id, post_id, created_at) AS ( + SELECT post.id, post.id, post.created_at + FROM post WHERE post.in_reply_to_id IS NULL AND post.repost_of_id IS NULL AND post.created_at < $1 UNION - SELECT context.id, post.id FROM post - JOIN context ON ( - post.in_reply_to_id = context.post_id - OR post.repost_of_id = context.post_id + SELECT context_post.id, post.id, post.created_at + FROM post + JOIN context_post ON ( + post.in_reply_to_id = context_post.post_id + OR post.repost_of_id = context_post.post_id ) ) - SELECT context_agg.id + SELECT context.id FROM ( - SELECT context.id, array_agg(context.post_id) AS posts - FROM context - GROUP BY context.id - ) AS context_agg + SELECT + context_post.id, + array_agg(context_post.post_id) AS posts, + max(context_post.created_at) AS updated_at + FROM context_post + GROUP BY context_post.id + ) AS context WHERE - NOT EXISTS ( + context.updated_at < $1 + AND NOT EXISTS ( SELECT 1 FROM post JOIN actor_profile ON post.author_id = actor_profile.id WHERE - post.id = ANY(context_agg.posts) + post.id = ANY(context.posts) AND actor_profile.actor_json IS NULL ) AND NOT EXISTS ( @@ -992,7 +998,7 @@ pub async fn find_extraneous_posts( FROM mention JOIN actor_profile ON mention.profile_id = actor_profile.id WHERE - mention.post_id = ANY(context_agg.posts) + mention.post_id = ANY(context.posts) AND actor_profile.actor_json IS NULL ) AND NOT EXISTS ( @@ -1000,7 +1006,7 @@ pub async fn find_extraneous_posts( FROM post_reaction JOIN actor_profile ON post_reaction.author_id = actor_profile.id WHERE - post_reaction.post_id = ANY(context_agg.posts) + post_reaction.post_id = ANY(context.posts) AND actor_profile.actor_json IS NULL ) AND NOT EXISTS ( @@ -1009,11 +1015,11 @@ pub async fn find_extraneous_posts( JOIN post ON post_link.target_id = post.id JOIN actor_profile ON post.author_id = actor_profile.id WHERE - post_link.source_id = ANY(context_agg.posts) + post_link.source_id = ANY(context.posts) AND actor_profile.actor_json IS NULL ) ", - &[&created_before], + &[&updated_before], ).await?; let ids: Vec = rows.iter() .map(|row| row.try_get("id")) @@ -1449,10 +1455,10 @@ mod tests { ..Default::default() }; create_post(db_client, &author.id, post_data).await.unwrap(); - let created_before = Utc::now() - Duration::days(1); + let updated_before = Utc::now() - Duration::days(1); let result = find_extraneous_posts( db_client, - &created_before, + &updated_before, ).await.unwrap(); assert!(result.is_empty()); }