mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-23 11:26:56 -08:00
API: post locks
This commit is contained in:
parent
5765b9a29c
commit
e8d9176931
6 changed files with 161 additions and 6 deletions
|
@ -1,7 +1,7 @@
|
||||||
from app.api.alpha import bp
|
from app.api.alpha import bp
|
||||||
from app.api.alpha.utils import get_site, post_site_block, \
|
from app.api.alpha.utils import get_site, post_site_block, \
|
||||||
get_search, \
|
get_search, \
|
||||||
get_post_list, get_post, post_post_like, put_post_save, put_post_subscribe, post_post, put_post, post_post_delete, post_post_report, \
|
get_post_list, get_post, post_post_like, put_post_save, put_post_subscribe, post_post, put_post, post_post_delete, post_post_report, post_post_lock, \
|
||||||
get_reply_list, post_reply_like, put_reply_save, put_reply_subscribe, post_reply, put_reply, post_reply_delete, post_reply_report, \
|
get_reply_list, post_reply_like, put_reply_save, put_reply_subscribe, post_reply, put_reply, post_reply_delete, post_reply_report, \
|
||||||
get_community_list, get_community, post_community_follow, post_community_block, \
|
get_community_list, get_community, post_community_follow, post_community_block, \
|
||||||
get_user, post_user_block
|
get_user, post_user_block
|
||||||
|
@ -207,6 +207,17 @@ def post_alpha_post_report():
|
||||||
return jsonify({"error": str(ex)}), 400
|
return jsonify({"error": str(ex)}), 400
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/api/alpha/post/lock', methods=['POST'])
|
||||||
|
def post_alpha_post_lock():
|
||||||
|
if not enable_api():
|
||||||
|
return jsonify({'error': 'alpha api is not enabled'})
|
||||||
|
try:
|
||||||
|
auth = request.headers.get('Authorization')
|
||||||
|
data = request.get_json(force=True) or {}
|
||||||
|
return jsonify(post_post_lock(auth, data))
|
||||||
|
except Exception as ex:
|
||||||
|
return jsonify({"error": str(ex)}), 400
|
||||||
|
|
||||||
# Reply
|
# Reply
|
||||||
@bp.route('/api/alpha/comment/list', methods=['GET'])
|
@bp.route('/api/alpha/comment/list', methods=['GET'])
|
||||||
def get_alpha_comment_list():
|
def get_alpha_comment_list():
|
||||||
|
@ -370,7 +381,6 @@ def alpha_community():
|
||||||
|
|
||||||
# Post - not yet implemented
|
# Post - not yet implemented
|
||||||
@bp.route('/api/alpha/post/remove', methods=['POST'])
|
@bp.route('/api/alpha/post/remove', methods=['POST'])
|
||||||
@bp.route('/api/alpha/post/lock', methods=['POST'])
|
|
||||||
@bp.route('/api/alpha/post/feature', methods=['POST'])
|
@bp.route('/api/alpha/post/feature', methods=['POST'])
|
||||||
@bp.route('/api/alpha/post/report', methods=['POST'])
|
@bp.route('/api/alpha/post/report', methods=['POST'])
|
||||||
@bp.route('/api/alpha/post/report/resolve', methods=['PUT'])
|
@bp.route('/api/alpha/post/report/resolve', methods=['PUT'])
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from app.api.alpha.utils.site import get_site, post_site_block
|
from app.api.alpha.utils.site import get_site, post_site_block
|
||||||
from app.api.alpha.utils.misc import get_search
|
from app.api.alpha.utils.misc import get_search
|
||||||
from app.api.alpha.utils.post import get_post_list, get_post, post_post_like, put_post_save, put_post_subscribe, post_post, put_post, post_post_delete, post_post_report
|
from app.api.alpha.utils.post import get_post_list, get_post, post_post_like, put_post_save, put_post_subscribe, post_post, put_post, post_post_delete, post_post_report, post_post_lock
|
||||||
from app.api.alpha.utils.reply import get_reply_list, post_reply_like, put_reply_save, put_reply_subscribe, post_reply, put_reply, post_reply_delete, post_reply_report
|
from app.api.alpha.utils.reply import get_reply_list, post_reply_like, put_reply_save, put_reply_subscribe, post_reply, put_reply, post_reply_delete, post_reply_report
|
||||||
from app.api.alpha.utils.community import get_community, get_community_list, post_community_follow, post_community_block
|
from app.api.alpha.utils.community import get_community, get_community_list, post_community_follow, post_community_block
|
||||||
from app.api.alpha.utils.user import get_user, post_user_block
|
from app.api.alpha.utils.user import get_user, post_user_block
|
||||||
|
|
|
@ -3,7 +3,7 @@ from app.api.alpha.views import post_view, post_report_view
|
||||||
from app.api.alpha.utils.validators import required, integer_expected, boolean_expected, string_expected
|
from app.api.alpha.utils.validators import required, integer_expected, boolean_expected, string_expected
|
||||||
from app.constants import POST_TYPE_ARTICLE, POST_TYPE_LINK, POST_TYPE_IMAGE, POST_TYPE_VIDEO
|
from app.constants import POST_TYPE_ARTICLE, POST_TYPE_LINK, POST_TYPE_IMAGE, POST_TYPE_VIDEO
|
||||||
from app.models import Post, Community, CommunityMember, utcnow
|
from app.models import Post, Community, CommunityMember, utcnow
|
||||||
from app.shared.post import vote_for_post, bookmark_the_post, remove_the_bookmark_from_post, toggle_post_notification, make_post, edit_post, delete_post, restore_post, report_post
|
from app.shared.post import vote_for_post, bookmark_the_post, remove_the_bookmark_from_post, toggle_post_notification, make_post, edit_post, delete_post, restore_post, report_post, lock_post
|
||||||
from app.utils import authorise_api_user, blocked_users, blocked_communities, blocked_instances, community_ids_from_instances, is_image_url, is_video_url
|
from app.utils import authorise_api_user, blocked_users, blocked_communities, blocked_instances, community_ids_from_instances, is_image_url, is_video_url
|
||||||
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
@ -239,3 +239,16 @@ def post_post_report(auth, data):
|
||||||
post_json = post_report_view(report=report, post_id=post_id, user_id=user_id)
|
post_json = post_report_view(report=report, post_id=post_id, user_id=user_id)
|
||||||
return post_json
|
return post_json
|
||||||
|
|
||||||
|
|
||||||
|
def post_post_lock(auth, data):
|
||||||
|
required(['post_id', 'locked'], data)
|
||||||
|
integer_expected(['post_id'], data)
|
||||||
|
boolean_expected(['locked'], data)
|
||||||
|
|
||||||
|
post_id = data['post_id']
|
||||||
|
locked = data['locked']
|
||||||
|
|
||||||
|
user_id, post = lock_post(post_id, locked, SRC_API, auth)
|
||||||
|
|
||||||
|
post_json = post_view(post=post, variant=4, user_id=user_id)
|
||||||
|
return post_json
|
||||||
|
|
|
@ -7,7 +7,7 @@ from app.shared.tasks import task_selector
|
||||||
from app.utils import render_template, authorise_api_user, shorten_string, gibberish, ensure_directory_exists, \
|
from app.utils import render_template, authorise_api_user, shorten_string, gibberish, ensure_directory_exists, \
|
||||||
piefed_markdown_to_lemmy_markdown, markdown_to_html, remove_tracking_from_link, domain_from_url, \
|
piefed_markdown_to_lemmy_markdown, markdown_to_html, remove_tracking_from_link, domain_from_url, \
|
||||||
opengraph_parse, url_to_thumbnail_file, can_create_post, is_video_hosting_site, recently_upvoted_posts, \
|
opengraph_parse, url_to_thumbnail_file, can_create_post, is_video_hosting_site, recently_upvoted_posts, \
|
||||||
is_image_url, is_video_hosting_site
|
is_image_url, is_video_hosting_site, add_to_modlog_activitypub
|
||||||
|
|
||||||
from flask import abort, flash, redirect, request, url_for, current_app, g
|
from flask import abort, flash, redirect, request, url_for, current_app, g
|
||||||
from flask_babel import _
|
from flask_babel import _
|
||||||
|
@ -531,3 +531,35 @@ def report_post(post_id, input, src, auth=None):
|
||||||
return user_id, report
|
return user_id, report
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def lock_post(post_id, locked, src, auth=None):
|
||||||
|
if src == SRC_API:
|
||||||
|
user = authorise_api_user(auth, return_type='model')
|
||||||
|
else:
|
||||||
|
user = current_user
|
||||||
|
|
||||||
|
post = Post.query.filter_by(id=post_id).one()
|
||||||
|
if locked:
|
||||||
|
comments_enabled = False
|
||||||
|
modlog_type = 'lock_post'
|
||||||
|
else:
|
||||||
|
comments_enabled = True
|
||||||
|
modlog_type = 'unlock_post'
|
||||||
|
|
||||||
|
if post.community.is_moderator(user) or post.community.is_instance_admin(user):
|
||||||
|
post.comments_enabled = comments_enabled
|
||||||
|
db.session.commit()
|
||||||
|
add_to_modlog_activitypub(modlog_type, user, community_id=post.community_id,
|
||||||
|
link_text=shorten_string(post.title), link=f'post/{post.id}', reason='')
|
||||||
|
|
||||||
|
if locked:
|
||||||
|
task_selector('lock_post', user_id=user.id, post_id=post_id)
|
||||||
|
else:
|
||||||
|
task_selector('unlock_post', user_id=user.id, post_id=post_id)
|
||||||
|
|
||||||
|
return user.id, post
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ from app.shared.tasks.notes import make_reply, edit_reply
|
||||||
from app.shared.tasks.deletes import delete_reply, restore_reply, delete_post, restore_post
|
from app.shared.tasks.deletes import delete_reply, restore_reply, delete_post, restore_post
|
||||||
from app.shared.tasks.flags import report_reply, report_post
|
from app.shared.tasks.flags import report_reply, report_post
|
||||||
from app.shared.tasks.pages import make_post, edit_post
|
from app.shared.tasks.pages import make_post, edit_post
|
||||||
|
from app.shared.tasks.locks import lock_post, unlock_post
|
||||||
|
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
|
||||||
|
@ -23,7 +24,9 @@ def task_selector(task_key, send_async=True, **kwargs):
|
||||||
'edit_post': edit_post,
|
'edit_post': edit_post,
|
||||||
'delete_post': delete_post,
|
'delete_post': delete_post,
|
||||||
'restore_post': restore_post,
|
'restore_post': restore_post,
|
||||||
'report_post': report_post
|
'report_post': report_post,
|
||||||
|
'lock_post': lock_post,
|
||||||
|
'unlock_post': unlock_post
|
||||||
}
|
}
|
||||||
|
|
||||||
if current_app.debug:
|
if current_app.debug:
|
||||||
|
|
97
app/shared/tasks/locks.py
Normal file
97
app/shared/tasks/locks.py
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
from app import celery
|
||||||
|
from app.activitypub.signature import default_context, post_request
|
||||||
|
from app.models import Post, User
|
||||||
|
from app.utils import gibberish, instance_banned
|
||||||
|
|
||||||
|
from flask import current_app
|
||||||
|
|
||||||
|
|
||||||
|
""" JSON format
|
||||||
|
Lock:
|
||||||
|
{
|
||||||
|
'id':
|
||||||
|
'type':
|
||||||
|
'actor':
|
||||||
|
'object':
|
||||||
|
'@context':
|
||||||
|
'audience':
|
||||||
|
'to': []
|
||||||
|
'cc': []
|
||||||
|
}
|
||||||
|
For Announce, remove @context from inner object, and use same fields except audience
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@celery.task
|
||||||
|
def lock_post(send_async, user_id, post_id):
|
||||||
|
post = Post.query.filter_by(id=post_id).one()
|
||||||
|
lock_object(user_id, post)
|
||||||
|
|
||||||
|
|
||||||
|
@celery.task
|
||||||
|
def unlock_post(send_async, user_id, post_id):
|
||||||
|
post = Post.query.filter_by(id=post_id).one()
|
||||||
|
lock_object(user_id, post, is_undo=True)
|
||||||
|
|
||||||
|
|
||||||
|
def lock_object(user_id, object, is_undo=False):
|
||||||
|
user = User.query.filter_by(id=user_id).one()
|
||||||
|
community = object.community
|
||||||
|
|
||||||
|
if community.local_only or not community.instance.online():
|
||||||
|
return
|
||||||
|
|
||||||
|
lock_id = f"https://{current_app.config['SERVER_NAME']}/activities/lock/{gibberish(15)}"
|
||||||
|
to = ["https://www.w3.org/ns/activitystreams#Public"]
|
||||||
|
cc = [community.public_url()]
|
||||||
|
lock = {
|
||||||
|
'id': lock_id,
|
||||||
|
'type': 'Lock',
|
||||||
|
'actor': user.public_url(),
|
||||||
|
'object': object.public_url(),
|
||||||
|
'@context': default_context(),
|
||||||
|
'audience': community.public_url(),
|
||||||
|
'to': to,
|
||||||
|
'cc': cc
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_undo:
|
||||||
|
del lock['@context']
|
||||||
|
undo_id = f"https://{current_app.config['SERVER_NAME']}/activities/undo/{gibberish(15)}"
|
||||||
|
undo = {
|
||||||
|
'id': undo_id,
|
||||||
|
'type': 'Undo',
|
||||||
|
'actor': user.public_url(),
|
||||||
|
'object': lock,
|
||||||
|
'@context': default_context(),
|
||||||
|
'audience': community.public_url(),
|
||||||
|
'to': to,
|
||||||
|
'cc': cc
|
||||||
|
}
|
||||||
|
|
||||||
|
if community.is_local():
|
||||||
|
if is_undo:
|
||||||
|
del undo['@context']
|
||||||
|
object=undo
|
||||||
|
else:
|
||||||
|
del lock['@context']
|
||||||
|
object=lock
|
||||||
|
|
||||||
|
announce_id = f"https://{current_app.config['SERVER_NAME']}/activities/announce/{gibberish(15)}"
|
||||||
|
actor = community.public_url()
|
||||||
|
cc = [community.ap_followers_url]
|
||||||
|
announce = {
|
||||||
|
'id': announce_id,
|
||||||
|
'type': 'Announce',
|
||||||
|
'actor': actor,
|
||||||
|
'object': object,
|
||||||
|
'@context': default_context(),
|
||||||
|
'to': to,
|
||||||
|
'cc': cc
|
||||||
|
}
|
||||||
|
for instance in community.following_instances():
|
||||||
|
if instance.inbox and instance.online() and not user.has_blocked_instance(instance.id) and not instance_banned(instance.domain):
|
||||||
|
post_request(instance.inbox, announce, community.private_key, community.public_url() + '#main-key')
|
||||||
|
else:
|
||||||
|
payload = undo if is_undo else lock
|
||||||
|
post_request(community.ap_inbox_url, payload, user.private_key, user.public_url() + '#main-key')
|
Loading…
Reference in a new issue