PeerTube: New posts from incoming activity

This commit is contained in:
freamon 2024-05-26 15:53:17 +01:00
parent 21afa9a6aa
commit 7f2ed0b658
2 changed files with 75 additions and 2 deletions

View file

@ -21,7 +21,7 @@ from app.activitypub.util import public_key, users_total, active_half_year, acti
upvote_post, delete_post_or_comment, community_members, \
user_removed_from_remote_server, create_post, create_post_reply, update_post_reply_from_activity, \
update_post_from_activity, undo_vote, undo_downvote, post_to_page, get_redis_connection, find_reported_object, \
process_report, ensure_domains_match, can_edit, can_delete, remove_data_from_banned_user
process_report, ensure_domains_match, can_edit, can_delete, remove_data_from_banned_user, resolve_remote_post
from app.utils import gibberish, get_setting, is_image_url, allowlist_html, render_template, \
domain_from_url, markdown_to_html, community_membership, ap_datetime, ip_address, can_downvote, \
can_upvote, can_create_post, awaken_dormant_instance, shorten_string, can_create_post_reply, sha256_digest, \
@ -610,6 +610,10 @@ def process_inbox_request(request_json, activitypublog_id, ip_address):
if isinstance(request_json['object'], str):
activity_log.activity_json = json.dumps(request_json)
activity_log.exception_message = 'invalid json?'
if 'actor' in request_json:
community = find_actor_or_create(request_json['actor'], community_only=True, create_if_not_found=False)
if community:
resolve_remote_post(request_json['object'], community.id, request_json['actor'])
elif request_json['object']['type'] == 'Create':
activity_log.activity_type = request_json['object']['type']
if 'object' in request_json and 'object' in request_json['object']:

View file

@ -7,7 +7,7 @@ from random import randint
from typing import Union, Tuple
import redis
from flask import current_app, request, g, url_for
from flask import current_app, request, g, url_for, json
from flask_babel import _
from sqlalchemy import text, func
from app import db, cache, constants, celery
@ -2307,3 +2307,72 @@ def can_edit(user_ap_id, post):
def can_delete(user_ap_id, post):
return can_edit(user_ap_id, post)
def resolve_remote_post(uri: str, community_id: int, announce_actor=None) -> Union[str, None]:
post = Post.query.filter_by(ap_id=uri).first()
if post:
return post.id
community = Community.query.get(community_id)
site = Site.query.get(1)
parsed_url = urlparse(uri)
uri_domain = parsed_url.netloc
if announce_actor:
parsed_url = urlparse(announce_actor)
announce_actor_domain = parsed_url.netloc
if announce_actor_domain != uri_domain:
return None
actor_domain = None
actor = None
post_request = get_request(uri, headers={'Accept': 'application/activity+json'})
if post_request.status_code == 200:
post_data = post_request.json()
post_request.close()
# check again that it doesn't already exist (can happen with different but equivilent URLs)
post = Post.query.filter_by(ap_id=post_data['id']).first()
if post:
return post.id
if 'attributedTo' in post_data:
if isinstance(post_data['attributedTo'], str):
actor = post_data['attributedTo']
parsed_url = urlparse(post_data['attributedTo'])
actor_domain = parsed_url.netloc
elif isinstance(post_data['attributedTo'], list):
for a in post_data['attributedTo']:
if a['type'] == 'Person':
actor = a['id']
parsed_url = urlparse(a['id'])
actor_domain = parsed_url.netloc
break
if uri_domain != actor_domain:
return None
activity_log = ActivityPubLog(direction='in', activity_id=post_data['id'], activity_type='Resolve Post', result='failure')
if site.log_activitypub_json:
activity_log.activity_json = json.dumps(post_data)
db.session.add(activity_log)
user = find_actor_or_create(actor)
if user and community and post_data:
post = post_json_to_model(activity_log, post_data, user, community)
post.ranking = post_ranking(post.score, post.posted_at)
community.last_active = utcnow()
if post.url:
other_posts = Post.query.filter(Post.id != post.id, Post.url == post.url,
Post.posted_at > post.posted_at - timedelta(days=3),
Post.posted_at < post.posted_at + timedelta(days=3)).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()
if post:
return post.id
return None