diff --git a/app/activitypub/util.py b/app/activitypub/util.py index 428c7901..e7a37d2a 100644 --- a/app/activitypub/util.py +++ b/app/activitypub/util.py @@ -1397,6 +1397,20 @@ def create_post(activity_log: ActivityPubLog, community: Community, request_json if post.image_id: make_image_sizes(post.image_id, 150, 512, 'posts') # the 512 sized image is for masonry view + if post.url: + other_posts = Post.query.filter(Post.id != post.id, Post.url == post.url, + Post.posted_at > post.posted_at - timedelta(days=6)).all() + for op in other_posts: + if op.cross_posts is None: + op.cross_posts = [post.id] + else: + op.cross_posts.append(post.id) + if post.cross_posts is None: + post.cross_posts = [op.id] + else: + post.cross_posts.append(op.id) + db.session.commit() + notify_about_post(post) if user.reputation > 100: @@ -1503,6 +1517,27 @@ def update_post_from_activity(post: Post, request_json: dict): post.domain = domain else: post.url = old_url # don't change if url changed from non-banned domain to banned domain + + new_cross_posts = Post.query.filter(Post.id != post.id, Post.url == post.url, + Post.posted_at > utcnow() - timedelta(days=6)).all() + for ncp in new_cross_posts: + if ncp.cross_posts is None: + ncp.cross_posts = [post.id] + else: + ncp.cross_posts.append(post.id) + if post.cross_posts is None: + post.cross_posts = [ncp.id] + else: + post.cross_posts.append(ncp.id) + + if post.url != old_url: + if post.cross_posts is not None: + old_cross_posts = Post.query.filter(Post.id.in_(post.cross_posts)).all() + post.cross_posts.clear() + for ocp in old_cross_posts: + if ocp.cross_posts is not None: + ocp.cross_posts.remove(post.id) + if post is not None: if 'image' in request_json['object'] and post.image is None: image = File(source_url=request_json['object']['image']['url']) diff --git a/app/community/routes.py b/app/community/routes.py index 87c44739..07aba09a 100644 --- a/app/community/routes.py +++ b/app/community/routes.py @@ -470,6 +470,20 @@ def add_post(actor): if post.image_id and post.image.file_path is None: make_image_sizes(post.image_id, 150, 512, 'posts') # the 512 sized image is for masonry view + if post.url: + other_posts = Post.query.filter(Post.id != post.id, Post.url == post.url, + Post.posted_at > post.posted_at - timedelta(days=6)).all() + for op in other_posts: + if op.cross_posts is None: + op.cross_posts = [post.id] + else: + op.cross_posts.append(post.id) + if post.cross_posts is None: + post.cross_posts = [op.id] + else: + post.cross_posts.append(op.id) + db.session.commit() + notify_about_post(post) if not community.local_only: diff --git a/app/post/routes.py b/app/post/routes.py index 57082fcf..6647d271 100644 --- a/app/post/routes.py +++ b/app/post/routes.py @@ -1,5 +1,5 @@ from collections import namedtuple -from datetime import datetime +from datetime import datetime, timedelta from random import randint from flask import redirect, url_for, flash, current_app, abort, request, g, make_response @@ -683,12 +683,36 @@ def post_edit(post_id: int): form.nsfw.render_kw = {'disabled': True} #form.communities.choices = [(c.id, c.display_name()) for c in current_user.communities()] + old_url = post.url if form.validate_on_submit(): save_post(form, post) post.community.last_active = utcnow() post.edited_at = utcnow() db.session.commit() + + if post.url != old_url: + if post.cross_posts is not None: + old_cross_posts = Post.query.filter(Post.id.in_(post.cross_posts)).all() + post.cross_posts.clear() + for ocp in old_cross_posts: + if ocp.cross_posts is not None: + ocp.cross_posts.remove(post.id) + + new_cross_posts = Post.query.filter(Post.id != post.id, Post.url == post.url, + Post.posted_at > post.edited_at - timedelta(days=6)).all() + for ncp in new_cross_posts: + if ncp.cross_posts is None: + ncp.cross_posts = [post.id] + else: + ncp.cross_posts.append(post.id) + if post.cross_posts is None: + post.cross_posts = [ncp.id] + else: + post.cross_posts.append(ncp.id) + + db.session.commit() + post.flush_cache() flash(_('Your changes have been saved.'), 'success') # federate edit