Prevent delete-extraneous-posts command from deleting post if there's a recent reply or repost
This commit is contained in:
parent
73145a9af6
commit
5809cffa71
3 changed files with 30 additions and 23 deletions
|
@ -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.
|
- Save downloaded media as "unknown" if its media type is not supported.
|
||||||
- Use `mediaType` property value to determine file extension when saving downloaded media.
|
- Use `mediaType` property value to determine file extension when saving downloaded media.
|
||||||
- Added `mediaType` property to images in actor object.
|
- 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
|
### Removed
|
||||||
|
|
||||||
|
|
|
@ -263,8 +263,8 @@ impl DeleteExtraneousPosts {
|
||||||
config: &Config,
|
config: &Config,
|
||||||
db_client: &mut impl GenericClient,
|
db_client: &mut impl GenericClient,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let created_before = Utc::now() - Duration::days(self.days);
|
let updated_before = Utc::now() - Duration::days(self.days);
|
||||||
let posts = find_extraneous_posts(db_client, &created_before).await?;
|
let posts = find_extraneous_posts(db_client, &updated_before).await?;
|
||||||
for post_id in posts {
|
for post_id in posts {
|
||||||
let deletion_queue = delete_post(db_client, &post_id).await?;
|
let deletion_queue = delete_post(db_client, &post_id).await?;
|
||||||
deletion_queue.process(config).await;
|
deletion_queue.process(config).await;
|
||||||
|
|
|
@ -951,40 +951,46 @@ pub async fn get_token_waitlist(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds all contexts (identified by top-level post)
|
/// 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.
|
/// that do not contain local posts, reposts, mentions, links or reactions.
|
||||||
pub async fn find_extraneous_posts(
|
pub async fn find_extraneous_posts(
|
||||||
db_client: &impl GenericClient,
|
db_client: &impl GenericClient,
|
||||||
created_before: &DateTime<Utc>,
|
updated_before: &DateTime<Utc>,
|
||||||
) -> Result<Vec<Uuid>, DatabaseError> {
|
) -> Result<Vec<Uuid>, DatabaseError> {
|
||||||
let rows = db_client.query(
|
let rows = db_client.query(
|
||||||
"
|
"
|
||||||
WITH RECURSIVE context (id, post_id) AS (
|
WITH RECURSIVE context_post (id, post_id, created_at) AS (
|
||||||
SELECT post.id, post.id FROM post
|
SELECT post.id, post.id, post.created_at
|
||||||
|
FROM post
|
||||||
WHERE
|
WHERE
|
||||||
post.in_reply_to_id IS NULL
|
post.in_reply_to_id IS NULL
|
||||||
AND post.repost_of_id IS NULL
|
AND post.repost_of_id IS NULL
|
||||||
AND post.created_at < $1
|
AND post.created_at < $1
|
||||||
UNION
|
UNION
|
||||||
SELECT context.id, post.id FROM post
|
SELECT context_post.id, post.id, post.created_at
|
||||||
JOIN context ON (
|
FROM post
|
||||||
post.in_reply_to_id = context.post_id
|
JOIN context_post ON (
|
||||||
OR post.repost_of_id = context.post_id
|
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 (
|
FROM (
|
||||||
SELECT context.id, array_agg(context.post_id) AS posts
|
SELECT
|
||||||
FROM context
|
context_post.id,
|
||||||
GROUP BY context.id
|
array_agg(context_post.post_id) AS posts,
|
||||||
) AS context_agg
|
max(context_post.created_at) AS updated_at
|
||||||
|
FROM context_post
|
||||||
|
GROUP BY context_post.id
|
||||||
|
) AS context
|
||||||
WHERE
|
WHERE
|
||||||
NOT EXISTS (
|
context.updated_at < $1
|
||||||
|
AND NOT EXISTS (
|
||||||
SELECT 1
|
SELECT 1
|
||||||
FROM post
|
FROM post
|
||||||
JOIN actor_profile ON post.author_id = actor_profile.id
|
JOIN actor_profile ON post.author_id = actor_profile.id
|
||||||
WHERE
|
WHERE
|
||||||
post.id = ANY(context_agg.posts)
|
post.id = ANY(context.posts)
|
||||||
AND actor_profile.actor_json IS NULL
|
AND actor_profile.actor_json IS NULL
|
||||||
)
|
)
|
||||||
AND NOT EXISTS (
|
AND NOT EXISTS (
|
||||||
|
@ -992,7 +998,7 @@ pub async fn find_extraneous_posts(
|
||||||
FROM mention
|
FROM mention
|
||||||
JOIN actor_profile ON mention.profile_id = actor_profile.id
|
JOIN actor_profile ON mention.profile_id = actor_profile.id
|
||||||
WHERE
|
WHERE
|
||||||
mention.post_id = ANY(context_agg.posts)
|
mention.post_id = ANY(context.posts)
|
||||||
AND actor_profile.actor_json IS NULL
|
AND actor_profile.actor_json IS NULL
|
||||||
)
|
)
|
||||||
AND NOT EXISTS (
|
AND NOT EXISTS (
|
||||||
|
@ -1000,7 +1006,7 @@ pub async fn find_extraneous_posts(
|
||||||
FROM post_reaction
|
FROM post_reaction
|
||||||
JOIN actor_profile ON post_reaction.author_id = actor_profile.id
|
JOIN actor_profile ON post_reaction.author_id = actor_profile.id
|
||||||
WHERE
|
WHERE
|
||||||
post_reaction.post_id = ANY(context_agg.posts)
|
post_reaction.post_id = ANY(context.posts)
|
||||||
AND actor_profile.actor_json IS NULL
|
AND actor_profile.actor_json IS NULL
|
||||||
)
|
)
|
||||||
AND NOT EXISTS (
|
AND NOT EXISTS (
|
||||||
|
@ -1009,11 +1015,11 @@ pub async fn find_extraneous_posts(
|
||||||
JOIN post ON post_link.target_id = post.id
|
JOIN post ON post_link.target_id = post.id
|
||||||
JOIN actor_profile ON post.author_id = actor_profile.id
|
JOIN actor_profile ON post.author_id = actor_profile.id
|
||||||
WHERE
|
WHERE
|
||||||
post_link.source_id = ANY(context_agg.posts)
|
post_link.source_id = ANY(context.posts)
|
||||||
AND actor_profile.actor_json IS NULL
|
AND actor_profile.actor_json IS NULL
|
||||||
)
|
)
|
||||||
",
|
",
|
||||||
&[&created_before],
|
&[&updated_before],
|
||||||
).await?;
|
).await?;
|
||||||
let ids: Vec<Uuid> = rows.iter()
|
let ids: Vec<Uuid> = rows.iter()
|
||||||
.map(|row| row.try_get("id"))
|
.map(|row| row.try_get("id"))
|
||||||
|
@ -1449,10 +1455,10 @@ mod tests {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
create_post(db_client, &author.id, post_data).await.unwrap();
|
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(
|
let result = find_extraneous_posts(
|
||||||
db_client,
|
db_client,
|
||||||
&created_before,
|
&updated_before,
|
||||||
).await.unwrap();
|
).await.unwrap();
|
||||||
assert!(result.is_empty());
|
assert!(result.is_empty());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue