diff --git a/files/routes/votes.py b/files/routes/votes.py index 3d4a897b8..81b2df579 100644 --- a/files/routes/votes.py +++ b/files/routes/votes.py @@ -42,152 +42,115 @@ def vote_info_get(v, link): ups=ups, downs=downs) +def vote_post_comment(target_id, new, v, cls, vote_cls): + if new == "-1" and DISABLE_DOWNVOTES: abort(403) + if new not in ["-1", "0", "1"]: abort(400) + if request.headers.get("Authorization") and v.id != BBBB_ID: abort(403) + new = int(new) + target = None + if cls == Submission: + target = get_post(target_id) + elif cls == Comment: + target = get_comment(target_id) + else: + abort(404) + + coin_delta = 1 + if v.id == target.author.id: + coin_delta = 0 + + coin_mult = 1 + + g.db.flush() + existing = g.db.query(vote_cls).filter_by(user_id=v.id) + if vote_cls == Vote: + existing = existing.filter_by(submission_id=target.id) + elif vote_cls == CommentVote: + existing = existing.filter_by(comment_id=target.id) + else: + abort(400) + + if DOUBLE_XP_ENABLED > 0: + if not existing and int(time.time()) > DOUBLE_XP_ENABLED: + coin_mult = 2 + elif existing and existing.created_utc > DOUBLE_XP_ENABLED: + coin_mult = 2 + + if existing and existing.vote_type == new: return "", 204 + if existing: + if existing.vote_type == 0 and new != 0: + target.author.coins += coin_delta * coin_mult + target.author.truecoins += coin_delta + g.db.add(target.author) + existing.vote_type = new + g.db.add(existing) + elif existing.vote_type != 0 and new == 0: + target.author.coins -= coin_delta * coin_mult + target.author.truecoins -= coin_delta + g.db.add(target.author) + g.db.delete(existing) + else: + existing.vote_type = new + g.db.add(existing) + elif new != 0: + target.author.coins += coin_delta * coin_mult + target.author.truecoins += coin_delta + g.db.add(target.author) + + if new == 1 and (v.agendaposter or v.shadowbanned or (v.is_banned and not v.unban_utc) or (v.profile_url.startswith('/e/') and not v.customtitle and v.namecolor == DEFAULT_COLOR)): real = False + else: real = True + + vote = None + if vote_cls == Vote: + vote = Vote(user_id=v.id, + vote_type=new, + submission_id=target_id, + app_id=v.client.application.id if v.client else None, + real = real + ) + elif vote_cls == CommentVote: + vote = CommentVote(user_id=v.id, + vote_type=new, + comment_id=target_id, + app_id=v.client.application.id if v.client else None, + real=real + ) + g.db.add(vote) + g.db.flush() + + # this is hacky but it works, we should probably do better later + def get_vote_count(dir, real_instead_of_dir): + votes = g.db.query(vote_cls) + votes = votes.filter_by(vote_type=dir) + if real_instead_of_dir: + votes = votes.filter_by(real=True) + elif vote_cls == Vote: + votes = votes.filter_by(submission_id=target.id) + elif vote_cls == CommentVote: + votes = votes.filter_by(comment_id=target.id) + else: + return 0 + return votes.count() + + target.upvotes = get_vote_count(1, False) + target.downvotes = get_vote_count(-1, False) + target.realupvotes = get_vote_count(0, True) # first arg is ignored here + + if target.author.progressivestack or (cls == Submission and (target.sub in ('space', 'istory', 'dinos') or target.domain.endswith('.win'))): + target.realupvotes *= 2 + g.db.add(target) + return "", 204 @app.post("/vote/post//") @limiter.limit("5/second;60/minute;1000/hour;2000/day") @limiter.limit("5/second;60/minute;1000/hour;2000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @is_not_permabanned def vote_post(post_id, new, v): - - if new == "-1" and DISABLE_DOWNVOTES: abort(403) - - if new not in ["-1", "0", "1"]: abort(400) - - if request.headers.get("Authorization") and v.id != BBBB_ID: abort(403) - - new = int(new) - - post = get_post(post_id) - - coin_delta = 1 - if v.id == post.author.id: - coin_delta = 0 - - coin_mult = 1 - - g.db.flush() - existing = g.db.query(Vote).filter_by(user_id=v.id, submission_id=post.id).one_or_none() - - if DOUBLE_XP_ENABLED > 0: - if not existing and int(time.time()) > DOUBLE_XP_ENABLED: - coin_mult = 2 - elif existing and existing.created_utc > DOUBLE_XP_ENABLED: - coin_mult = 2 - - if existing and existing.vote_type == new: return "", 204 - - if existing: - if existing.vote_type == 0 and new != 0: - post.author.coins += coin_delta * coin_mult - post.author.truecoins += coin_delta - g.db.add(post.author) - existing.vote_type = new - g.db.add(existing) - elif existing.vote_type != 0 and new == 0: - post.author.coins -= coin_delta * coin_mult - post.author.truecoins -= coin_delta - g.db.add(post.author) - g.db.delete(existing) - else: - existing.vote_type = new - g.db.add(existing) - elif new != 0: - post.author.coins += coin_delta * coin_mult - post.author.truecoins += coin_delta - g.db.add(post.author) - - if new == 1 and (v.agendaposter or v.shadowbanned or (v.is_banned and not v.unban_utc) or (v.profile_url.startswith('/e/') and not v.customtitle and v.namecolor == DEFAULT_COLOR)): real = False - else: real = True - - vote = Vote(user_id=v.id, - vote_type=new, - submission_id=post_id, - app_id=v.client.application.id if v.client else None, - real = real - ) - g.db.add(vote) - - g.db.flush() - post.upvotes = g.db.query(Vote).filter_by(submission_id=post.id, vote_type=1).count() - post.downvotes = g.db.query(Vote).filter_by(submission_id=post.id, vote_type=-1).count() - post.realupvotes = g.db.query(Vote).filter_by(submission_id=post.id, real=True).count() - - if post.author.progressivestack \ - or post.sub in ('space','istory','dinos') \ - or post.domain.endswith('.win'): - post.realupvotes *= 2 - - g.db.add(post) - return "", 204 + return vote_post_comment(post_id, new, v, Submission, Vote) @app.post("/vote/comment//") @limiter.limit("5/second;60/minute;1000/hour;2000/day") @limiter.limit("5/second;60/minute;1000/hour;2000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @is_not_permabanned def vote_comment(comment_id, new, v): - - if new == "-1" and DISABLE_DOWNVOTES: abort(403, "forbidden.") - - if new not in ["-1", "0", "1"]: abort(400) - - if request.headers.get("Authorization") and v.id != BBBB_ID: abort(403) - - new = int(new) - comment = get_comment(comment_id) - - coin_delta = 1 - if v.id == comment.author_id: - coin_delta = 0 - - coin_mult = 1 - - g.db.commit() - existing = g.db.query(CommentVote).filter_by(user_id=v.id, comment_id=comment.id).one_or_none() - - if DOUBLE_XP_ENABLED > 0: - if not existing and int(time.time()) > DOUBLE_XP_ENABLED: - coin_mult = 2 - elif existing and existing.created_utc > DOUBLE_XP_ENABLED: - coin_mult = 2 - - if existing and existing.vote_type == new: return "", 204 - - if existing: - if existing.vote_type == 0 and new != 0: - comment.author.coins += coin_delta * coin_mult - comment.author.truecoins += coin_delta - g.db.add(comment.author) - existing.vote_type = new - g.db.add(existing) - elif existing.vote_type != 0 and new == 0: - comment.author.coins -= coin_delta * coin_mult - comment.author.truecoins -= coin_delta - g.db.add(comment.author) - g.db.delete(existing) - else: - existing.vote_type = new - g.db.add(existing) - elif new != 0: - comment.author.coins += coin_delta * coin_mult - comment.author.truecoins += coin_delta - g.db.add(comment.author) - - if new == 1 and (v.agendaposter or v.shadowbanned or (v.is_banned and not v.unban_utc) or (v.profile_url.startswith('/e/') and not v.customtitle and v.namecolor == DEFAULT_COLOR)): real = False - else: real = True - - vote = CommentVote(user_id=v.id, - vote_type=new, - comment_id=comment_id, - app_id=v.client.application.id if v.client else None, - real=real - ) - - g.db.add(vote) - - g.db.commit() - comment.upvotes = g.db.query(CommentVote).filter_by(comment_id=comment.id, vote_type=1).count() - comment.downvotes = g.db.query(CommentVote).filter_by(comment_id=comment.id, vote_type=-1).count() - comment.realupvotes = g.db.query(CommentVote).filter_by(comment_id=comment.id, real=True).count() - if comment.author.progressivestack: comment.realupvotes *= 2 - g.db.add(comment) - return "", 204 + return vote_post_comment(comment_id, new, v, Comment, CommentVote)