diff --git a/app/community/routes.py b/app/community/routes.py index 03cbe021..6af5df89 100644 --- a/app/community/routes.py +++ b/app/community/routes.py @@ -30,7 +30,8 @@ from app.utils import get_setting, render_template, allowlist_html, markdown_to_ shorten_string, gibberish, community_membership, ap_datetime, \ request_etag_matches, return_304, instance_banned, can_create_post, can_upvote, can_downvote, user_filters_posts, \ joined_communities, moderating_communities, blocked_domains, mimetype_from_url, blocked_instances, \ - community_moderators, communities_banned_from, show_ban_message, recently_upvoted_posts, recently_downvoted_posts + community_moderators, communities_banned_from, show_ban_message, recently_upvoted_posts, recently_downvoted_posts, \ + blocked_users from feedgen.feed import FeedGenerator from datetime import timezone, timedelta @@ -181,6 +182,11 @@ def show_community(community: Community): if instance_ids: posts = posts.filter(or_(Post.instance_id.not_in(instance_ids), Post.instance_id == None)) + # filter blocked users + blocked_accounts = blocked_users(current_user.id) + if blocked_accounts: + posts = posts.filter(Post.user_id.not_in(blocked_accounts)) + if sort == '' or sort == 'hot': posts = posts.order_by(desc(Post.sticky)).order_by(desc(Post.ranking)).order_by(desc(Post.posted_at)) elif sort == 'top': diff --git a/app/post/util.py b/app/post/util.py index 99e7f6cb..c7dd5b73 100644 --- a/app/post/util.py +++ b/app/post/util.py @@ -5,7 +5,7 @@ from sqlalchemy import desc, text, or_ from app import db from app.models import PostReply -from app.utils import blocked_instances +from app.utils import blocked_instances, blocked_users # replies to a post, in a tree, sorted by a variety of methods @@ -17,6 +17,9 @@ def post_replies(post_id: int, sort_by: str, show_first: int = 0) -> List[PostRe comments = comments.filter(or_(PostReply.instance_id.not_in(instance_ids), PostReply.instance_id == None)) if current_user.ignore_bots: comments = comments.filter(PostReply.from_bot == False) + blocked_accounts = blocked_users(current_user.id) + if blocked_accounts: + comments = comments.filter(PostReply.user_id.not_in(blocked_accounts)) if sort_by == 'hot': comments = comments.order_by(desc(PostReply.ranking)) elif sort_by == 'top': diff --git a/app/search/routes.py b/app/search/routes.py index 036f34b9..4705e82a 100644 --- a/app/search/routes.py +++ b/app/search/routes.py @@ -6,7 +6,7 @@ from sqlalchemy import or_ from app.models import Post from app.search import bp from app.utils import moderating_communities, joined_communities, render_template, blocked_domains, blocked_instances, \ - communities_banned_from, recently_upvoted_posts, recently_downvoted_posts + communities_banned_from, recently_upvoted_posts, recently_downvoted_posts, blocked_users @bp.route('/search', methods=['GET', 'POST']) @@ -30,6 +30,10 @@ def run_search(): instance_ids = blocked_instances(current_user.id) if instance_ids: posts = posts.filter(or_(Post.instance_id.not_in(instance_ids), Post.instance_id == None)) + # filter blocked users + blocked_accounts = blocked_users(current_user.id) + if blocked_accounts: + posts = posts.filter(Post.user_id.not_in(blocked_accounts)) banned_from = communities_banned_from(current_user.id) if banned_from: posts = posts.filter(Post.community_id.not_in(banned_from)) diff --git a/app/topic/routes.py b/app/topic/routes.py index 325342d4..0751bcb4 100644 --- a/app/topic/routes.py +++ b/app/topic/routes.py @@ -17,7 +17,7 @@ from app import db, celery, cache from app.topic.forms import ChooseTopicsForm from app.utils import render_template, user_filters_posts, moderating_communities, joined_communities, \ community_membership, blocked_domains, validation_required, mimetype_from_url, blocked_instances, \ - communities_banned_from + communities_banned_from, blocked_users @bp.route('/topic/', methods=['GET']) @@ -63,12 +63,18 @@ def show_topic(topic_path): posts = posts.filter(Post.nsfw == False) content_filters = user_filters_posts(current_user.id) + # filter blocked domains and instances domains_ids = blocked_domains(current_user.id) if domains_ids: posts = posts.filter(or_(Post.domain_id.not_in(domains_ids), Post.domain_id == None)) instance_ids = blocked_instances(current_user.id) if instance_ids: posts = posts.filter(or_(Post.instance_id.not_in(instance_ids), Post.instance_id == None)) + # filter blocked users + blocked_accounts = blocked_users(current_user.id) + if blocked_accounts: + posts = posts.filter(Post.user_id.not_in(blocked_accounts)) + banned_from = communities_banned_from(current_user.id) if banned_from: posts = posts.filter(Post.community_id.not_in(banned_from)) diff --git a/app/user/routes.py b/app/user/routes.py index 196474ad..c1b2efa9 100644 --- a/app/user/routes.py +++ b/app/user/routes.py @@ -19,7 +19,7 @@ from app.user.utils import purge_user_then_delete from app.utils import get_setting, render_template, markdown_to_html, user_access, markdown_to_text, shorten_string, \ is_image_url, ensure_directory_exists, gibberish, file_get_contents, community_membership, user_filters_home, \ user_filters_posts, user_filters_replies, moderating_communities, joined_communities, theme_list, blocked_instances, \ - allowlist_html, recently_upvoted_posts, recently_downvoted_posts + allowlist_html, recently_upvoted_posts, recently_downvoted_posts, blocked_users from sqlalchemy import desc, or_, text import os @@ -294,6 +294,7 @@ def block_profile(actor): # federate block flash(f'{actor} has been blocked.') + cache.delete_memoized(blocked_users, current_user.id) goto = request.args.get('redirect') if 'redirect' in request.args else f'/u/{actor}' return redirect(goto) @@ -322,6 +323,7 @@ def unblock_profile(actor): # federate unblock flash(f'{actor} has been unblocked.') + cache.delete_memoized(blocked_users, current_user.id) goto = request.args.get('redirect') if 'redirect' in request.args else f'/u/{actor}' return redirect(goto) diff --git a/app/utils.py b/app/utils.py index 853f4c35..a389397b 100644 --- a/app/utils.py +++ b/app/utils.py @@ -29,7 +29,7 @@ import re from app.email import send_welcome_email from app.models import Settings, Domain, Instance, BannedInstances, User, Community, DomainBlock, ActivityPubLog, IpBan, \ - Site, Post, PostReply, utcnow, Filter, CommunityMember, InstanceBlock, CommunityBan, Topic + Site, Post, PostReply, utcnow, Filter, CommunityMember, InstanceBlock, CommunityBan, Topic, UserBlock # Flask's render_template function, with support for themes added @@ -335,6 +335,12 @@ def blocked_instances(user_id) -> List[int]: return [block.instance_id for block in blocks] +@cache.memoize(timeout=86400) +def blocked_users(user_id) -> List[int]: + blocks = UserBlock.query.filter_by(blocker_id=user_id) + return [block.blocked_id for block in blocks] + + @cache.memoize(timeout=86400) def blocked_phrases() -> List[str]: site = Site.query.get(1)