mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-23 11:26:56 -08:00
API: post delete and restore
This commit is contained in:
parent
3e3aca1910
commit
ac6f66e892
7 changed files with 134 additions and 18 deletions
|
@ -1,7 +1,7 @@
|
|||
from app.api.alpha import bp
|
||||
from app.api.alpha.utils import get_site, post_site_block, \
|
||||
get_search, \
|
||||
get_post_list, get_post, post_post_like, put_post_save, put_post_subscribe, post_post, put_post, \
|
||||
get_post_list, get_post, post_post_like, put_post_save, put_post_subscribe, post_post, put_post, post_post_delete, \
|
||||
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_user, post_user_block
|
||||
|
@ -183,6 +183,18 @@ def put_alpha_post():
|
|||
return jsonify({"error": str(ex)}), 400
|
||||
|
||||
|
||||
@bp.route('/api/alpha/post/delete', methods=['POST'])
|
||||
def post_alpha_post_delete():
|
||||
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_delete(auth, data))
|
||||
except Exception as ex:
|
||||
return jsonify({"error": str(ex)}), 400
|
||||
|
||||
|
||||
# Reply
|
||||
@bp.route('/api/alpha/comment/list', methods=['GET'])
|
||||
def get_alpha_comment_list():
|
||||
|
@ -345,7 +357,6 @@ def alpha_community():
|
|||
return jsonify({"error": "not_yet_implemented"}), 400
|
||||
|
||||
# Post - not yet implemented
|
||||
@bp.route('/api/alpha/post/delete', 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'])
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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.post import get_post_list, get_post, post_post_like, put_post_save, put_post_subscribe, post_post, put_post
|
||||
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
|
||||
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.user import get_user, post_user_block
|
||||
|
|
|
@ -3,7 +3,7 @@ from app.api.alpha.views import post_view
|
|||
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.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
|
||||
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
|
||||
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
|
||||
|
@ -205,3 +205,20 @@ def put_post(auth, data):
|
|||
|
||||
post_json = post_view(post=post, variant=4, user_id=user_id)
|
||||
return post_json
|
||||
|
||||
|
||||
def post_post_delete(auth, data):
|
||||
required(['post_id', 'deleted'], data)
|
||||
integer_expected(['post_id'], data)
|
||||
boolean_expected(['deleted'], data)
|
||||
|
||||
post_id = data['post_id']
|
||||
deleted = data['deleted']
|
||||
|
||||
if deleted == True:
|
||||
user_id, post = delete_post(post_id, SRC_API, auth)
|
||||
else:
|
||||
user_id, post = restore_post(post_id, SRC_API, auth)
|
||||
|
||||
post_json = post_view(post=post, variant=4, user_id=user_id)
|
||||
return post_json
|
||||
|
|
|
@ -421,3 +421,55 @@ def edit_post(input, post, type, src, user=None, auth=None, uploaded_file=None,
|
|||
elif from_scratch:
|
||||
return post
|
||||
|
||||
|
||||
# just for deletes by owner (mod deletes are classed as 'remove')
|
||||
def delete_post(post_id, src, auth):
|
||||
if src == SRC_API:
|
||||
user_id = authorise_api_user(auth)
|
||||
else:
|
||||
user_id = current_user.id
|
||||
|
||||
post = Post.query.filter_by(id=post_id, user_id=user_id, deleted=False).one()
|
||||
if post.url:
|
||||
post.calculate_cross_posts(delete_only=True)
|
||||
|
||||
post.deleted = True
|
||||
post.deleted_by = user_id
|
||||
post.author.post_count -= 1
|
||||
post.community.post_count -= 1
|
||||
db.session.commit()
|
||||
if src == SRC_WEB:
|
||||
flash(_('Post deleted.'))
|
||||
|
||||
task_selector('delete_post', user_id=user_id, post_id=post.id)
|
||||
|
||||
if src == SRC_API:
|
||||
return user_id, post
|
||||
else:
|
||||
return
|
||||
|
||||
|
||||
def restore_post(post_id, src, auth):
|
||||
if src == SRC_API:
|
||||
user_id = authorise_api_user(auth)
|
||||
else:
|
||||
user_id = current_user.id
|
||||
|
||||
post = Post.query.filter_by(id=post_id, user_id=user_id, deleted=True).one()
|
||||
if post.url:
|
||||
post.calculate_cross_posts()
|
||||
|
||||
post.deleted = False
|
||||
post.deleted_by = None
|
||||
post.author.post_count -= 1
|
||||
post.community.post_count -= 1
|
||||
db.session.commit()
|
||||
if src == SRC_WEB:
|
||||
flash(_('Post restored.'))
|
||||
|
||||
task_selector('restore_post', user_id=user_id, post_id=post.id)
|
||||
|
||||
if src == SRC_API:
|
||||
return user_id, post
|
||||
else:
|
||||
return
|
||||
|
|
|
@ -233,12 +233,11 @@ def edit_reply(input, reply, post, src, auth=None):
|
|||
# just for deletes by owner (mod deletes are classed as 'remove')
|
||||
def delete_reply(reply_id, src, auth):
|
||||
if src == SRC_API:
|
||||
reply = PostReply.query.filter_by(id=reply_id, deleted=False).one()
|
||||
user_id = authorise_api_user(auth, id_match=reply.user_id)
|
||||
user_id = authorise_api_user(auth)
|
||||
else:
|
||||
reply = PostReply.query.get_or_404(reply_id)
|
||||
user_id = current_user.id
|
||||
|
||||
reply = PostReply.query.filter_by(id=reply_id, user_id=user_id, deleted=False).one()
|
||||
reply.deleted = True
|
||||
reply.deleted_by = user_id
|
||||
|
||||
|
@ -259,14 +258,11 @@ def delete_reply(reply_id, src, auth):
|
|||
|
||||
def restore_reply(reply_id, src, auth):
|
||||
if src == SRC_API:
|
||||
reply = PostReply.query.filter_by(id=reply_id, deleted=True).one()
|
||||
user_id = authorise_api_user(auth, id_match=reply.user_id)
|
||||
if reply.user_id != reply.deleted_by:
|
||||
raise Exception('incorrect_login')
|
||||
user_id = authorise_api_user(auth)
|
||||
else:
|
||||
reply = PostReply.query.get_or_404(reply_id)
|
||||
user_id = current_user.id
|
||||
|
||||
reply = PostReply.query.filter_by(id=reply_id, user_id=user_id, deleted=True).one()
|
||||
reply.deleted = False
|
||||
reply.deleted_by = None
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from app.shared.tasks.follows import join_community, leave_community
|
||||
from app.shared.tasks.likes import vote_for_post, vote_for_reply
|
||||
from app.shared.tasks.notes import make_reply, edit_reply
|
||||
from app.shared.tasks.deletes import delete_reply, restore_reply
|
||||
from app.shared.tasks.deletes import delete_reply, restore_reply, delete_post, restore_post
|
||||
from app.shared.tasks.flags import report_reply
|
||||
from app.shared.tasks.pages import make_post, edit_post
|
||||
|
||||
|
@ -20,7 +20,9 @@ def task_selector(task_key, send_async=True, **kwargs):
|
|||
'restore_reply': restore_reply,
|
||||
'report_reply': report_reply,
|
||||
'make_post': make_post,
|
||||
'edit_post': edit_post
|
||||
'edit_post': edit_post,
|
||||
'delete_post': delete_post,
|
||||
'restore_post': restore_post
|
||||
}
|
||||
|
||||
if current_app.debug:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from app import celery
|
||||
from app.activitypub.signature import default_context, post_request
|
||||
from app.models import CommunityBan, PostReply, User
|
||||
from app.models import CommunityBan, Instance, Post, PostReply, User, UserFollower
|
||||
from app.utils import gibberish, instance_banned
|
||||
|
||||
from flask import current_app
|
||||
|
@ -34,10 +34,31 @@ def restore_reply(send_async, user_id, reply_id):
|
|||
delete_object(user_id, reply, is_restore=True)
|
||||
|
||||
|
||||
def delete_object(user_id, object, is_restore=False):
|
||||
@celery.task
|
||||
def delete_post(send_async, user_id, post_id):
|
||||
post = Post.query.filter_by(id=post_id).one()
|
||||
delete_object(user_id, post, is_post=True)
|
||||
|
||||
|
||||
@celery.task
|
||||
def restore_post(send_async, user_id, post_id):
|
||||
post = Post.query.filter_by(id=post_id).one()
|
||||
delete_object(user_id, post, is_post=True, is_restore=True)
|
||||
|
||||
|
||||
def delete_object(user_id, object, is_post=False, is_restore=False):
|
||||
user = User.query.filter_by(id=user_id).one()
|
||||
community = object.community
|
||||
if community.local_only or not community.instance.online():
|
||||
|
||||
# local_only communities can also be used to send activity to User Followers (only applies to posts, not comments)
|
||||
# return now though, if there aren't any
|
||||
if not is_post and community.local_only:
|
||||
return
|
||||
followers = UserFollower.query.filter_by(local_user_id=user.id).all()
|
||||
if not followers and community.local_only:
|
||||
return
|
||||
|
||||
if not community.instance.online():
|
||||
return
|
||||
|
||||
banned = CommunityBan.query.filter_by(user_id=user_id, community_id=community.id).first()
|
||||
|
@ -75,6 +96,8 @@ def delete_object(user_id, object, is_restore=False):
|
|||
'cc': cc
|
||||
}
|
||||
|
||||
domains_sent_to = []
|
||||
|
||||
if community.is_local():
|
||||
if is_restore:
|
||||
del undo['@context']
|
||||
|
@ -97,9 +120,24 @@ def delete_object(user_id, object, is_restore=False):
|
|||
}
|
||||
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')
|
||||
post_request(instance.inbox, announce, community.private_key, community.public_url() + '#main-key')
|
||||
domains_sent_to.append(instance.domain)
|
||||
else:
|
||||
payload = undo if is_restore else delete
|
||||
post_request(community.ap_inbox_url, payload, user.private_key, user.public_url() + '#main-key')
|
||||
domains_sent_to.append(community.instance.domain)
|
||||
|
||||
if is_post and followers:
|
||||
payload = undo if is_restore else delete
|
||||
for follower in followers:
|
||||
user_details = User.query.get(follower.remote_user_id)
|
||||
if user_details:
|
||||
payload['cc'].append(user_details.public_url())
|
||||
instances = Instance.query.join(User, User.instance_id == Instance.id).join(UserFollower, UserFollower.remote_user_id == User.id)
|
||||
instances = instances.filter(UserFollower.local_user_id == user.id).filter(Instance.gone_forever == False)
|
||||
for instance in instances:
|
||||
if instance.domain not in domains_sent_to:
|
||||
post_request(instance.inbox, payload, user.private_key, user.public_url() + '#main-key')
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue