mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-24 03:43:42 -08:00
Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
c91131424d
5 changed files with 133 additions and 3 deletions
|
@ -561,7 +561,7 @@ def refresh_community_profile_task(community_id):
|
||||||
community.description_html = markdown_to_html(community.description)
|
community.description_html = markdown_to_html(community.description)
|
||||||
community.rules = activity_json['rules'] if 'rules' in activity_json else ''
|
community.rules = activity_json['rules'] if 'rules' in activity_json else ''
|
||||||
community.rules_html = lemmy_markdown_to_html(activity_json['rules'] if 'rules' in activity_json else '')
|
community.rules_html = lemmy_markdown_to_html(activity_json['rules'] if 'rules' in activity_json else '')
|
||||||
community.restricted_to_mods = activity_json['postingRestrictedToMods'] if 'postingRestrictedToMods' in activity_json else True
|
community.restricted_to_mods = activity_json['postingRestrictedToMods'] if 'postingRestrictedToMods' in activity_json else False
|
||||||
community.new_mods_wanted = activity_json['newModsWanted'] if 'newModsWanted' in activity_json else False
|
community.new_mods_wanted = activity_json['newModsWanted'] if 'newModsWanted' in activity_json else False
|
||||||
community.private_mods = activity_json['privateMods'] if 'privateMods' in activity_json else False
|
community.private_mods = activity_json['privateMods'] if 'privateMods' in activity_json else False
|
||||||
community.ap_moderators_url = mods_url
|
community.ap_moderators_url = mods_url
|
||||||
|
@ -612,6 +612,9 @@ def refresh_community_profile_task(community_id):
|
||||||
new_language = find_language_or_create(ap_language['identifier'], ap_language['name'])
|
new_language = find_language_or_create(ap_language['identifier'], ap_language['name'])
|
||||||
if new_language not in community.languages:
|
if new_language not in community.languages:
|
||||||
community.languages.append(new_language)
|
community.languages.append(new_language)
|
||||||
|
instance = Instance.query.get(community.instance_id)
|
||||||
|
if instance and instance.software == 'peertube':
|
||||||
|
community.restricted_to_mods = True
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
if community.icon_id and icon_changed:
|
if community.icon_id and icon_changed:
|
||||||
make_image_sizes(community.icon_id, 60, 250, 'communities')
|
make_image_sizes(community.icon_id, 60, 250, 'communities')
|
||||||
|
@ -2428,3 +2431,106 @@ def resolve_remote_post(uri: str, community_id: int, announce_actor=None) -> Uni
|
||||||
return post
|
return post
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_remote_post_from_search(uri: str) -> Union[Post, None]:
|
||||||
|
post = Post.query.filter_by(ap_id=uri).first()
|
||||||
|
if post:
|
||||||
|
return post
|
||||||
|
|
||||||
|
site = Site.query.get(1)
|
||||||
|
|
||||||
|
parsed_url = urlparse(uri)
|
||||||
|
uri_domain = parsed_url.netloc
|
||||||
|
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 equivalent URLs)
|
||||||
|
post = Post.query.filter_by(ap_id=post_data['id']).first()
|
||||||
|
if post:
|
||||||
|
return post
|
||||||
|
|
||||||
|
# find the author of the post. Make sure their domain matches the site hosting it to migitage impersonation attempts
|
||||||
|
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
|
||||||
|
|
||||||
|
# find the community the post was submitted to
|
||||||
|
community = None
|
||||||
|
if not community and post_data['type'] == 'Page': # lemmy
|
||||||
|
if 'audience' in post_data:
|
||||||
|
community_id = post_data['audience']
|
||||||
|
community = Community.query.filter_by(ap_profile_id=community_id).first()
|
||||||
|
|
||||||
|
if not community and post_data['type'] == 'Video': # peertube
|
||||||
|
if 'attributedTo' in post_data and isinstance(post_data['attributedTo'], list):
|
||||||
|
for a in post_data['attributedTo']:
|
||||||
|
if a['type'] == 'Group':
|
||||||
|
community_id = a['id']
|
||||||
|
community = Community.query.filter_by(ap_profile_id=community_id).first()
|
||||||
|
if community:
|
||||||
|
break
|
||||||
|
|
||||||
|
if not community: # mastodon, etc
|
||||||
|
if 'inReplyTo' not in post_data or post_data['inReplyTo'] != None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if not community and 'to' in post_data and isinstance(post_data['to'], str):
|
||||||
|
community_id = post_data['to'].lower()
|
||||||
|
if not community_id == 'https://www.w3.org/ns/activitystreams#Public' and not community_id.endswith('/followers'):
|
||||||
|
community = Community.query.filter_by(ap_profile_id=community_id).first()
|
||||||
|
if not community and 'cc' in post_data and isinstance(post_data['cc'], str):
|
||||||
|
community_id = post_data['cc'].lower()
|
||||||
|
if not community_id == 'https://www.w3.org/ns/activitystreams#Public' and not community_id.endswith('/followers'):
|
||||||
|
community = Community.query.filter_by(ap_profile_id=community_id).first()
|
||||||
|
if not community and 'to' in post_data and isinstance(post_data['to'], list):
|
||||||
|
for t in post_data['to']:
|
||||||
|
community_id = t.lower()
|
||||||
|
if not community_id == 'https://www.w3.org/ns/activitystreams#Public' and not community_id.endswith('/followers'):
|
||||||
|
community = Community.query.filter_by(ap_profile_id=community_id).first()
|
||||||
|
if community:
|
||||||
|
break
|
||||||
|
if not community and 'cc' in post_data and isinstance(post_data['to'], list):
|
||||||
|
for c in post_data['cc']:
|
||||||
|
community_id = c.lower()
|
||||||
|
if not community_id == 'https://www.w3.org/ns/activitystreams#Public' and not community_id.endswith('/followers'):
|
||||||
|
community = Community.query.filter_by(ap_profile_id=community_id).first()
|
||||||
|
if community:
|
||||||
|
break
|
||||||
|
|
||||||
|
if not community:
|
||||||
|
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:
|
||||||
|
request_json = {
|
||||||
|
'id': f"https://{uri_domain}/activities/create/gibberish(15)",
|
||||||
|
'object': post_data
|
||||||
|
}
|
||||||
|
post = create_post(activity_log, community, request_json, user)
|
||||||
|
if post:
|
||||||
|
if 'published' in post_data:
|
||||||
|
post.posted_at=post_data['published']
|
||||||
|
post.last_active=post_data['published']
|
||||||
|
db.session.commit()
|
||||||
|
return post
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
|
@ -94,6 +94,7 @@ def retrieve_peertube_mods_and_backfill(community_id: int, mods: list):
|
||||||
else:
|
else:
|
||||||
new_membership = CommunityMember(community_id=community.id, user_id=user.id, is_moderator=True)
|
new_membership = CommunityMember(community_id=community.id, user_id=user.id, is_moderator=True)
|
||||||
db.session.add(new_membership)
|
db.session.add(new_membership)
|
||||||
|
community.restricted_to_mods = True
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
if community.ap_public_url:
|
if community.ap_public_url:
|
||||||
|
|
|
@ -7,6 +7,8 @@ from app.models import Post, Language, Community
|
||||||
from app.search import bp
|
from app.search import bp
|
||||||
from app.utils import moderating_communities, joined_communities, render_template, blocked_domains, blocked_instances, \
|
from app.utils import moderating_communities, joined_communities, render_template, blocked_domains, blocked_instances, \
|
||||||
communities_banned_from, recently_upvoted_posts, recently_downvoted_posts, blocked_users
|
communities_banned_from, recently_upvoted_posts, recently_downvoted_posts, blocked_users
|
||||||
|
from app.community.forms import RetrieveRemotePost
|
||||||
|
from app.activitypub.util import resolve_remote_post_from_search
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/search', methods=['GET', 'POST'])
|
@bp.route('/search', methods=['GET', 'POST'])
|
||||||
|
@ -87,3 +89,20 @@ def run_search():
|
||||||
moderating_communities=moderating_communities(current_user.get_id()),
|
moderating_communities=moderating_communities(current_user.get_id()),
|
||||||
joined_communities=joined_communities(current_user.get_id()),
|
joined_communities=joined_communities(current_user.get_id()),
|
||||||
site=g.site)
|
site=g.site)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/retrieve_remote_post', methods=['GET', 'POST'])
|
||||||
|
@login_required
|
||||||
|
def retrieve_remote_post():
|
||||||
|
if current_user.banned:
|
||||||
|
return show_ban_message()
|
||||||
|
form = RetrieveRemotePost()
|
||||||
|
new_post = None
|
||||||
|
if form.validate_on_submit():
|
||||||
|
address = form.address.data.strip()
|
||||||
|
new_post = resolve_remote_post_from_search(address)
|
||||||
|
if new_post is None:
|
||||||
|
flash(_('Post not found.'), 'warning')
|
||||||
|
|
||||||
|
return render_template('community/retrieve_remote_post.html',
|
||||||
|
title=_('Retrieve Remote Post'), form=form, new_post=new_post)
|
||||||
|
|
|
@ -11,7 +11,11 @@
|
||||||
<div class="card mt-5">
|
<div class="card mt-5">
|
||||||
<div class="card-body p-6">
|
<div class="card-body p-6">
|
||||||
<div class="card-title">{{ _('Retrieve Remote Post') }}</div>
|
<div class="card-title">{{ _('Retrieve Remote Post') }}</div>
|
||||||
|
{% if community %}
|
||||||
<p>Enter the full URL of the post submitted to {{ community.ap_id }}</p>
|
<p>Enter the full URL of the post submitted to {{ community.ap_id }}</p>
|
||||||
|
{% else %}
|
||||||
|
<p>Enter the full URL of the post</p>
|
||||||
|
{% endif %}
|
||||||
<p>Note: URL needs to match the one from the post author's instance (which may be different than the community's instance)</p>
|
<p>Note: URL needs to match the one from the post author's instance (which may be different than the community's instance)</p>
|
||||||
{{ render_form(form) }}
|
{{ render_form(form) }}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
<h6 class="mt-5">{{ _('Trying to add a communitiy or post from another instance?') }} </h6>
|
<h6 class="mt-5">{{ _('Trying to add a communitiy or post from another instance?') }} </h6>
|
||||||
<p>{{ _('In many types of federated platforms you can put a URL of a post or community into the search in order to add it to your local instance. In PieFed the search is just for searching.') }}</p>
|
<p>{{ _('In many types of federated platforms you can put a URL of a post or community into the search in order to add it to your local instance. In PieFed the search is just for searching.') }}</p>
|
||||||
<p><a href="{{ url_for('community.add_remote') }}" class="btn btn-primary">{{ _('Add remote community') }}</a></p>
|
<p><a href="{{ url_for('community.add_remote') }}" class="btn btn-primary">{{ _('Add remote community') }}</a></p>
|
||||||
<p>{{ _('To add a post from a remote instance, find the community in PieFed then look for the "Retrieve a post from the original server" link.') }}</p>
|
<p><a href="{{ url_for('search.retrieve_remote_post') }}" class="btn btn-primary">{{ _('Retrieve remote post') }}</a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Reference in a new issue