def cast_vote(sub, obj, vote_info, timer, date): from r2.models.admintools import valid_user, valid_thing, update_score from r2.lib.count import incr_sr_count names_by_dir = {True: "1", None: "0", False: "-1"} # `vote` mimics the old pg vote rel interface so downstream code doesn't # need to change. (but it totally needn't stay that way forever!) vote = Storage( _thing1=sub, _thing2=obj, _name=names_by_dir[vote_info["dir"]], _date=date, valid_thing=True, valid_user=True, ip=vote_info["ip"], ) # these track how much ups/downs should change on `obj` ups_delta = 1 if int(vote._name) > 0 else 0 downs_delta = 1 if int(vote._name) < 0 else 0 # see if the user has voted on this thing before old_votes = VoteDetailsByThing.get_details(obj, [sub]) old_vote = None if old_votes: old_vote = old_votes[0] timer.intermediate("cass_read_vote") if old_vote: vote._date = datetime.utcfromtimestamp( old_vote["date"]).replace(tzinfo=pytz.UTC) vote.valid_thing = old_vote["valid_thing"] vote.valid_user = old_vote["valid_user"] vote.ip = old_vote["ip"] if vote._name == old_vote["direction"]: # the old vote and new vote are the same. bail out. return vote # remove the old vote from the score old_direction = int(old_vote["direction"]) ups_delta -= 1 if old_direction > 0 else 0 downs_delta -= 1 if old_direction < 0 else 0 # calculate valid_thing and valid_user sr = obj.subreddit_slow kind = obj.__class__.__name__.lower() karma = sub.karma(kind, sr) if vote.valid_thing: vote.valid_thing = valid_thing(vote, karma, vote_info["cheater"], vote_info["info"]) if vote.valid_user: vote.valid_user = vote.valid_thing and valid_user(vote, sr, karma) if kind == "link" and getattr(obj, "is_self", False): # self-posts do not generate karma vote.valid_user = False g.stats.simple_event("vote.valid_thing." + str(vote.valid_thing).lower()) g.stats.simple_event("vote.valid_user." + str(vote.valid_user).lower()) # update various score/karma/vote counts if not (not old_vote and obj.author_id == sub._id and vote._name == "1"): # newly created objects start out with _ups = 1, so we skip updating # their score here if this is the author's own initial vote on it. old_valid_thing = old_vote["valid_thing"] if old_vote else True update_score(obj, ups_delta, downs_delta, vote, old_valid_thing) timer.intermediate("pg_update_score") if vote.valid_user: author = Account._byID(obj.author_id, data=True) author.incr_karma(kind, sr, ups_delta - downs_delta) timer.intermediate("pg_incr_karma") if not old_vote and vote.valid_thing and kind == "link": if sub._id != obj.author_id: incr_sr_count(sr) timer.intermediate("incr_sr_counts") # write the vote to cassandra VotesByAccount.copy_from(vote, vote_info["info"]) timer.intermediate("cassavotes") num_votes = vote._thing2._ups + vote._thing2._downs if num_votes < 20 or num_votes % 10 == 0: # always update the search index if the thing has fewer than 20 votes # when the thing has more votes queue an update less often vote._thing2.update_search_index(boost_only=True) timer.intermediate("update_search_index") event_data = vote_info.get("event_data") if event_data: g.events.vote_event(vote, old_vote, event_data["context"], event_data["sensitive"]) return vote
def cast_vote(sub, obj, dir, ip, vote_info, cheater, timer, date): from r2.models.admintools import valid_user, valid_thing, update_score from r2.lib.count import incr_sr_count from r2.lib.db import queries names_by_dir = {True: "1", None: "0", False: "-1"} # `vote` mimics the old pg vote rel interface so downstream code doesn't # need to change. (but it totally needn't stay that way forever!) vote = Storage( _thing1=sub, _thing2=obj, _name=names_by_dir[dir], _date=date, valid_thing=True, valid_user=True, ip=ip, ) # these track how much ups/downs should change on `obj` ups_delta = 1 if int(vote._name) > 0 else 0 downs_delta = 1 if int(vote._name) < 0 else 0 # see if the user has voted on this thing before pgrel = Vote.rel(sub, obj) pgoldvote = pgrel._fast_query(sub, obj, ["-1", "0", "1"]).values() try: pgoldvote = filter(None, pgoldvote)[0] except IndexError: pgoldvote = None timer.intermediate("pg_read_vote") if pgoldvote: # old_vote is mimicking `{Link,Comment}VoteDetailsByThing` here because # that will eventually be exactly what it is old_vote = { "direction": pgoldvote._name, "valid_thing": pgoldvote.valid_thing, "valid_user": pgoldvote.valid_user, "ip": getattr(pgoldvote, "ip", None), } vote.valid_thing = old_vote["valid_thing"] vote.valid_user = old_vote["valid_user"] if vote._name == old_vote["direction"]: # the old vote and new vote are the same. bail out. return vote # remove the old vote from the score old_direction = int(old_vote["direction"]) ups_delta -= 1 if old_direction > 0 else 0 downs_delta -= 1 if old_direction < 0 else 0 else: old_vote = None # calculate valid_thing and valid_user sr = obj.subreddit_slow kind = obj.__class__.__name__.lower() karma = sub.karma(kind, sr) if vote.valid_thing: vote.valid_thing = valid_thing(vote, karma, cheater, vote_info) if vote.valid_user: vote.valid_user = vote.valid_thing and valid_user(vote, sr, karma) if kind == "link" and getattr(obj, "is_self", False): # self-posts do not generate karma vote.valid_user = False g.stats.simple_event("vote.valid_thing." + str(vote.valid_thing).lower()) g.stats.simple_event("vote.valid_user." + str(vote.valid_user).lower()) # write out the new/modified vote to postgres if pgoldvote: pgvote = pgoldvote pgvote._name = vote._name else: pgvote = pgrel(sub, obj, vote._name, date=vote._date, ip=ip) pgvote.valid_thing = vote.valid_thing pgvote.valid_user = vote.valid_user pgvote._commit() timer.intermediate("pg_write_vote") # update various score/karma/vote counts if not (not old_vote and obj.author_id == sub._id and vote._name == "1"): # newly created objects start out with _ups = 1, so we skip updating # their score here if this is the author's own initial vote on it. old_valid_thing = old_vote["valid_thing"] if old_vote else True update_score(obj, ups_delta, downs_delta, vote, old_valid_thing) timer.intermediate("pg_update_score") if vote.valid_user: author = Account._byID(obj.author_id, data=True) author.incr_karma(kind, sr, ups_delta - downs_delta) timer.intermediate("pg_incr_karma") if not old_vote and vote.valid_thing and kind == "link": if sub._id != obj.author_id: incr_sr_count(sr) timer.intermediate("incr_sr_counts") # write the vote to cassandra VotesByAccount.copy_from(vote, vote_info) timer.intermediate("cassavotes") # update the search index queries.changed(vote._thing2, boost_only=True) timer.intermediate("changed") return vote
def cast_vote(sub, obj, vote_info, timer, date): from r2.models.admintools import valid_user, valid_thing, update_score from r2.lib.count import incr_sr_count names_by_dir = {True: "1", None: "0", False: "-1"} # `vote` mimics the old pg vote rel interface so downstream code doesn't # need to change. (but it totally needn't stay that way forever!) vote = Storage( _thing1=sub, _thing2=obj, _name=names_by_dir[vote_info["dir"]], _date=date, valid_thing=True, valid_user=True, ip=vote_info["ip"], ) # these track how much ups/downs should change on `obj` ups_delta = 1 if int(vote._name) > 0 else 0 downs_delta = 1 if int(vote._name) < 0 else 0 # see if the user has voted on this thing before old_votes = VoteDetailsByThing.get_details(obj, [sub]) old_vote = None if old_votes: old_vote = old_votes[0] timer.intermediate("cass_read_vote") if old_vote: vote._date = datetime.utcfromtimestamp( old_vote["date"]).replace(tzinfo=pytz.UTC) vote.valid_thing = old_vote["valid_thing"] vote.valid_user = old_vote["valid_user"] vote.ip = old_vote["ip"] if vote._name == old_vote["direction"]: # the old vote and new vote are the same. bail out. return vote # remove the old vote from the score old_direction = int(old_vote["direction"]) ups_delta -= 1 if old_direction > 0 else 0 downs_delta -= 1 if old_direction < 0 else 0 # calculate valid_thing and valid_user sr = obj.subreddit_slow kind = obj.__class__.__name__.lower() karma = sub.karma(kind, sr) if vote.valid_thing: vote.valid_thing = valid_thing(vote, karma, vote_info["cheater"], vote_info["info"]) if vote.valid_user: vote.valid_user = vote.valid_thing and valid_user(vote, sr, karma) if kind == "link" and getattr(obj, "is_self", False): # self-posts do not generate karma vote.valid_user = False g.stats.simple_event("vote.valid_thing." + str(vote.valid_thing).lower()) g.stats.simple_event("vote.valid_user." + str(vote.valid_user).lower()) # update various score/karma/vote counts if not (not old_vote and obj.author_id == sub._id and vote._name == "1"): # newly created objects start out with _ups = 1, so we skip updating # their score here if this is the author's own initial vote on it. old_valid_thing = old_vote["valid_thing"] if old_vote else True update_score(obj, ups_delta, downs_delta, vote, old_valid_thing) timer.intermediate("pg_update_score") if vote.valid_user: author = Account._byID(obj.author_id, data=True) author.incr_karma(kind, sr, ups_delta - downs_delta) timer.intermediate("pg_incr_karma") if not old_vote and vote.valid_thing and kind == "link": if sub._id != obj.author_id: incr_sr_count(sr) timer.intermediate("incr_sr_counts") # write the vote to cassandra VotesByAccount.copy_from(vote, vote_info["info"]) timer.intermediate("cassavotes") vote._thing2.update_search_index(boost_only=True) timer.intermediate("update_search_index") if "event" in vote_info and vote_info["event"]: g.events.vote_event(vote, old_vote, event_base=vote_info["event"]) return vote