From 35e2128dec2027c6de7f9f70214272759c603935 Mon Sep 17 00:00:00 2001 From: justcool393 Date: Fri, 28 Oct 2022 17:13:37 -0700 Subject: [PATCH] get: use function to get voted and blocked properties (#425) * get: comments and posts: use get function from get.py * fix prev commit * move filter to correct place * fix error and also log so i can figure out what's wrong * comments: add some more trace logging * should_keep_func always acts as return True if None is passed in * remove logging code --- files/helpers/get.py | 81 ++++++++++++++------------- files/routes/comments.py | 44 +-------------- files/routes/posts.py | 115 +++------------------------------------ 3 files changed, 56 insertions(+), 184 deletions(-) diff --git a/files/helpers/get.py b/files/helpers/get.py index 336ceb11a..04c99289a 100644 --- a/files/helpers/get.py +++ b/files/helpers/get.py @@ -1,4 +1,4 @@ -from typing import Iterable, List, Optional, Union +from typing import Callable, Iterable, List, Optional, Union from files.classes import * from flask import g @@ -255,46 +255,53 @@ def add_vote_and_block_props(target:Union[Submission, Comment], v:Optional[User] def get_comments(cids:Iterable[int], v:Optional[User]=None) -> List[Comment]: if not cids: return [] if v: - votes = g.db.query(CommentVote.vote_type, CommentVote.comment_id).filter_by(user_id=v.id).subquery() - - blocking = v.blocking.subquery() - - blocked = v.blocked.subquery() - - comments = g.db.query( - Comment, - votes.c.vote_type, - blocking.c.target_id, - blocked.c.target_id, - ).filter(Comment.id.in_(cids)) - - comments = comments.join( - votes, - votes.c.comment_id == Comment.id, - isouter=True - ).join( - blocking, - blocking.c.target_id == Comment.author_id, - isouter=True - ).join( - blocked, - blocked.c.user_id == Comment.author_id, - isouter=True - ).all() - - output = [] - for c in comments: - comment = c[0] - comment.voted = c[1] or 0 - comment.is_blocking = c[2] or 0 - comment.is_blocked = c[3] or 0 - output.append(comment) - + output = get_comments_v_properties(v, True, None, Comment.id.in_(cids))[1] else: output = g.db.query(Comment).join(Comment.author).filter(User.shadowbanned == None, Comment.id.in_(cids)).all() - return sorted(output, key=lambda x: cids.index(x.id)) +def get_comments_v_properties(v:User, include_shadowbanned=True, should_keep_func:Optional[Callable[[Comment], bool]]=None, *criterion): + if not v: + raise TypeError("A user is required") + votes = g.db.query(CommentVote.vote_type, CommentVote.comment_id).filter_by(user_id=v.id).subquery() + blocking = v.blocking.subquery() + blocked = v.blocked.subquery() + comments = g.db.query( + Comment, + votes.c.vote_type, + blocking.c.target_id, + blocked.c.target_id, + ) + + if not include_shadowbanned and not v.can_see_shadowbanned: + comments = comments.join(Comment.author).filter(User.shadowbanned == None) + + comments = comments.filter(*criterion) + comments = comments.join( + votes, + votes.c.comment_id == Comment.id, + isouter=True + ).join( + blocking, + blocking.c.target_id == Comment.author_id, + isouter=True + ).join( + blocked, + blocked.c.user_id == Comment.author_id, + isouter=True + ) + queried = comments.all() + output = [] + dump = [] + for c in queried: + comment = c[0] + comment.voted = c[1] or 0 + comment.is_blocking = c[2] or 0 + comment.is_blocked = c[3] or 0 + if not should_keep_func or should_keep_func(c[0]): output.append(comment) + else: dump.append(comment) + return (comments, output) + def get_sub_by_name(sub:str, v:Optional[User]=None, graceful=False) -> Optional[Sub]: if not sub: if graceful: return None diff --git a/files/routes/comments.py b/files/routes/comments.py index c219127a0..d206b7e75 100644 --- a/files/routes/comments.py +++ b/files/routes/comments.py @@ -46,7 +46,6 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None): g.db.add(notif) if comment.post and comment.post.club and not (v and (v.paid_dues or v.id in [comment.author_id, comment.post.author_id])): abort(403) - if not comment.parent_submission and not (v and (comment.author.id == v.id or comment.sentto == v.id)) and not (v and v.admin_level >= PERMS['POST_COMMENT_MODERATION']) : abort(403) if not pid: @@ -73,46 +72,9 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None): sort=request.values.get("sort", defaultsortingcomments) if v: - votes = g.db.query(CommentVote.vote_type, CommentVote.comment_id).filter_by(user_id=v.id).subquery() - - blocking = v.blocking.subquery() - - blocked = v.blocked.subquery() - - comments = g.db.query( - Comment, - votes.c.vote_type, - blocking.c.target_id, - blocked.c.target_id, - ) - - if not (v and v.can_see_shadowbanned): - comments = comments.join(Comment.author).filter(User.shadowbanned == None) - - comments=comments.filter( - Comment.top_comment_id == c.top_comment_id - ).join( - votes, - votes.c.comment_id == Comment.id, - isouter=True - ).join( - blocking, - blocking.c.target_id == Comment.author_id, - isouter=True - ).join( - blocked, - blocked.c.user_id == Comment.author_id, - isouter=True - ) - - output = [] - for c in comments: - comment = c[0] - comment.voted = c[1] or 0 - comment.is_blocking = c[2] or 0 - comment.is_blocked = c[3] or 0 - output.append(comment) - + # this is required because otherwise the vote and block + # props won't save properly unless you put them in a list + output = get_comments_v_properties(v, False, None, Comment.top_comment_id == c.top_comment_id)[1] post.replies=[top_comment] if v and v.client: return top_comment.json diff --git a/files/routes/posts.py b/files/routes/posts.py index c09897077..bc0bcaf2c 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -151,47 +151,13 @@ def post_id(pid, anything=None, v=None, sub=None): if post.club and not (v and (v.paid_dues or v.id == post.author_id)): abort(403) if v: - votes = g.db.query(CommentVote.vote_type, CommentVote.comment_id).filter_by(user_id=v.id).subquery() - - blocking = v.blocking.subquery() - - blocked = v.blocked.subquery() - - comments = g.db.query( - Comment, - votes.c.vote_type, - blocking.c.target_id, - blocked.c.target_id, - ) - comments=comments.filter(Comment.parent_submission == post.id, Comment.level < 10).join( - votes, - votes.c.comment_id == Comment.id, - isouter=True - ).join( - blocking, - blocking.c.target_id == Comment.author_id, - isouter=True - ).join( - blocked, - blocked.c.user_id == Comment.author_id, - isouter=True - ) - - output = [] - for c in comments.all(): - comment = c[0] - comment.voted = c[1] or 0 - comment.is_blocking = c[2] or 0 - comment.is_blocked = c[3] or 0 - output.append(comment) - + # shadowban check is done in sort_objects + # output is needed: see comments.py + comments, output = get_comments_v_properties(v, True, None, Comment.parent_submission == post.id, Comment.level < 10) pinned = [c[0] for c in comments.filter(Comment.stickied != None).all()] - comments = comments.filter(Comment.level == 1, Comment.stickied == None) - comments = sort_objects(sort, comments, Comment, include_shadowbanned=(v and v.can_see_shadowbanned)) - comments = [c[0] for c in comments.all()] else: pinned = g.db.query(Comment).filter(Comment.parent_submission == post.id, Comment.stickied != None).all() @@ -275,42 +241,10 @@ def viewmore(v, pid, sort, offset): except: abort(400) if v: - votes = g.db.query(CommentVote.vote_type, CommentVote.comment_id).filter_by(user_id=v.id).subquery() - - blocking = v.blocking.subquery() - - blocked = v.blocked.subquery() - - comments = g.db.query( - Comment, - votes.c.vote_type, - blocking.c.target_id, - blocked.c.target_id, - ).filter(Comment.parent_submission == pid, Comment.stickied == None, Comment.id.notin_(ids), Comment.level < 10) - comments=comments.join( - votes, - votes.c.comment_id == Comment.id, - isouter=True - ).join( - blocking, - blocking.c.target_id == Comment.author_id, - isouter=True - ).join( - blocked, - blocked.c.user_id == Comment.author_id, - isouter=True - ) - - output = [] - for c in comments.all(): - comment = c[0] - comment.voted = c[1] or 0 - comment.is_blocking = c[2] or 0 - comment.is_blocked = c[3] or 0 - output.append(comment) - + # shadowban check is done in sort_objects + # output is needed: see comments.py + comments, output = get_comments_v_properties(v, True, None, Comment.parent_submission == pid, Comment.stickied == None, Comment.id.notin_(ids), Comment.level < 10) comments = comments.filter(Comment.level == 1) - comments = sort_objects(sort, comments, Comment, include_shadowbanned=(v and v.can_see_shadowbanned)) @@ -360,40 +294,9 @@ def morecomments(v, cid): tcid = g.db.query(Comment.top_comment_id).filter_by(id=cid).one_or_none()[0] if v: - votes = g.db.query(CommentVote.vote_type, CommentVote.comment_id).filter_by(user_id=v.id).subquery() - - blocking = v.blocking.subquery() - - blocked = v.blocked.subquery() - - comments = g.db.query( - Comment, - votes.c.vote_type, - blocking.c.target_id, - blocked.c.target_id, - ).filter(Comment.top_comment_id == tcid, Comment.level > 9).join( - votes, - votes.c.comment_id == Comment.id, - isouter=True - ).join( - blocking, - blocking.c.target_id == Comment.author_id, - isouter=True - ).join( - blocked, - blocked.c.user_id == Comment.author_id, - isouter=True - ) - - output = [] - dump = [] - for c in comments.all(): - comment = c[0] - comment.voted = c[1] or 0 - comment.is_blocking = c[2] or 0 - comment.is_blocked = c[3] or 0 - if c[0].parent_comment_id == int(cid): output.append(comment) - else: dump.append(comment) + # shadowban check is done in sort_objects i think + # output is needed: see comments.py + comments, output = get_comments_v_properties(v, True, lambda c:bool(c.parent_comment_id == int(cid)), Comment.top_comment_id == tcid, Comment.level > 9) comments = output else: c = get_comment(cid)