diff --git a/files/classes/user.py b/files/classes/user.py index a04966a66..4853538c5 100644 --- a/files/classes/user.py +++ b/files/classes/user.py @@ -873,6 +873,24 @@ class User(Base): def userblocks(self): return [x[0] for x in g.db.query(UserBlock.target_id).filter_by(user_id=self.id).all()] + def get_relationship_count(self, relationship_cls): + # TODO: deduplicate (see routes/users.py) + if relationship_cls in [SaveRelationship, Subscription]: + query = relationship_cls.submission_id + join = relationship_cls.post + cls = Submission + elif relationship_cls is CommentSaveRelationship: + query = relationship_cls.comment_id + join = relationship_cls.comment + cls = Comment + else: + raise TypeError("Relationships supported is SaveRelationship, Subscription, CommentSaveRelationship") + + query = g.db.query(query).join(join).filter(relationship_cls.user_id == self.id) + if not self.admin_level >= PERMS['POST_COMMENT_MODERATION']: + query = query.filter(cls.is_banned == False, cls.deleted_utc == 0) + return query.count() + @property @lazy def saved_idlist(self): @@ -895,17 +913,17 @@ class User(Base): @property @lazy def saved_count(self): - return g.db.query(SaveRelationship).filter_by(user_id=self.id).count() + return self.get_relationship_count(SaveRelationship) @property @lazy def saved_comment_count(self): - return g.db.query(CommentSaveRelationship).filter_by(user_id=self.id).count() + return self.get_relationship_count(CommentSaveRelationship) @property @lazy def subscribed_count(self): - return g.db.query(Subscription).filter_by(user_id=self.id).count() + return self.get_relationship_count(Subscription) @property @lazy diff --git a/files/helpers/get.py b/files/helpers/get.py index 33ec03736..a2c1d8a9b 100644 --- a/files/helpers/get.py +++ b/files/helpers/get.py @@ -2,7 +2,7 @@ from typing import Callable, Iterable, List, Optional, Union from flask import * from sqlalchemy import and_, any_, or_ -from sqlalchemy.orm import joinedload, selectinload +from sqlalchemy.orm import joinedload, selectinload, Query from files.classes import Comment, CommentVote, Hat, Sub, Submission, User, UserBlock, Vote from files.helpers.const import AUTOJANNY_ID @@ -145,7 +145,7 @@ def get_post(i:Union[str, int], v:Optional[User]=None, graceful=False) -> Option return x -def get_posts(pids:Iterable[int], v:Optional[User]=None, eager:bool=False) -> List[Submission]: +def get_posts(pids:Iterable[int], v:Optional[User]=None, eager:bool=False, extra:Optional[Callable[[Query], Query]]=None) -> List[Submission]: if not pids: return [] if v: @@ -178,6 +178,8 @@ def get_posts(pids:Iterable[int], v:Optional[User]=None, eager:bool=False) -> Li else: query = g.db.query(Submission).filter(Submission.id.in_(pids)) + if extra: query = extra(query) + if eager: query = query.options( selectinload(Submission.author).options( @@ -276,12 +278,14 @@ def add_vote_and_block_props(target:Union[Submission, Comment], v:Optional[User] target = add_block_props(target, v) return add_vote_props(target, v, vote_cls) -def get_comments(cids:Iterable[int], v:Optional[User]=None) -> List[Comment]: +def get_comments(cids:Iterable[int], v:Optional[User]=None, extra:Optional[Callable[[Query], Query]]=None) -> List[Comment]: if not cids: return [] if v: - output = get_comments_v_properties(v, True, None, Comment.id.in_(cids))[1] + output = get_comments_v_properties(v, True, None, Comment.id.in_(cids))[1] # TODO: support 'extra' for get_comments_v_properties else: - output = g.db.query(Comment).join(Comment.author).filter(User.shadowbanned == None, Comment.id.in_(cids)).all() + output = g.db.query(Comment).join(Comment.author) + if extra: output = extra(output) + output = output.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): diff --git a/files/routes/users.py b/files/routes/users.py index 09e1373b3..086ee9e25 100644 --- a/files/routes/users.py +++ b/files/routes/users.py @@ -935,7 +935,6 @@ def user_profile_name(username): return redirect(x.profile_url) def get_saves_and_subscribes(v, template, relationship_cls, page:int, standalone=False): - PAGE_SIZE = 25 if relationship_cls in [SaveRelationship, Subscription]: query = relationship_cls.submission_id join = relationship_cls.post @@ -949,12 +948,18 @@ def get_saves_and_subscribes(v, template, relationship_cls, page:int, standalone ids = [x[0] for x in g.db.query(query).join(join).filter(relationship_cls.user_id == v.id).order_by(cls.created_utc.desc()).offset(PAGE_SIZE * (page - 1)).limit(PAGE_SIZE + 1).all()] next_exists = len(ids) > PAGE_SIZE ids = ids[:PAGE_SIZE] + + extra = None + if not v.admin_level >= PERMS['POST_COMMENT_MODERATION']: + extra = lambda q:q.filter(cls.is_banned == False, cls.deleted_utc == 0) + if cls is Submission: - listing = get_posts(ids, v=v, eager=True) + listing = get_posts(ids, v=v, eager=True, extra=extra) elif cls is Comment: - listing = get_comments(ids, v=v) + listing = get_comments(ids, v=v, extra=extra) else: raise TypeError("Only supports Submissions and Comments. This is probably the result of a bug with *this* function") + if v.client: return {"data": [x.json(g.db) for x in listing]} return render_template(template, u=v, v=v, listing=listing, page=page, next_exists=next_exists, standalone=standalone)