def vote(cls, sub, obj, dir, ip, organic = False, cheater = False, timer=None): from admintools import valid_user, valid_thing, update_score from r2.lib.count import incr_sr_count from r2.lib.db import queries if timer is None: timer = SimpleSillyStub() sr = obj.subreddit_slow kind = obj.__class__.__name__.lower() karma = sub.karma(kind, sr) is_self_link = (kind == 'link' and getattr(obj,'is_self',False)) #check for old vote rel = cls.rel(sub, obj) oldvote = rel._fast_query(sub, obj, ['-1', '0', '1']).values() oldvote = filter(None, oldvote) timer.intermediate("pg_read_vote") amount = 1 if dir is True else 0 if dir is None else -1 is_new = False #old vote if len(oldvote): v = oldvote[0] oldamount = int(v._name) v._name = str(amount) #these still need to be recalculated old_valid_thing = getattr(v, 'valid_thing', False) v.valid_thing = (valid_thing(v, karma, cheater = cheater) and getattr(v,'valid_thing', False)) v.valid_user = (getattr(v, 'valid_user', False) and v.valid_thing and valid_user(v, sr, karma)) #new vote else: is_new = True oldamount = 0 v = rel(sub, obj, str(amount)) v.ip = ip old_valid_thing = v.valid_thing = valid_thing(v, karma, cheater = cheater) v.valid_user = (v.valid_thing and valid_user(v, sr, karma) and not is_self_link) if organic: v.organic = organic v._commit() timer.intermediate("pg_write_vote") up_change, down_change = score_changes(amount, oldamount) if not (is_new and obj.author_id == sub._id and amount == 1): # we don't do this if it's the author's initial automatic # vote, because we checked it in with _ups == 1 update_score(obj, up_change, down_change, v, old_valid_thing) timer.intermediate("pg_update_score") if v.valid_user: author = Account._byID(obj.author_id, data=True) author.incr_karma(kind, sr, up_change - down_change) timer.intermediate("pg_incr_karma") #update the sr's valid vote count if is_new and v.valid_thing and kind == 'link': if sub._id != obj.author_id: incr_sr_count(sr) timer.intermediate("incr_sr_counts") # now write it out to Cassandra. We'll write it out to both # this way for a while VotesByAccount.copy_from(v) timer.intermediate("cassavotes") queries.changed(v._thing2, True) timer.intermediate("changed") return v
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 vote(cls, sub, obj, dir, ip, organic=False, cheater=False): from admintools import valid_user, valid_thing, update_score from r2.lib.count import incr_sr_count from r2.lib.db import queries sr = obj.subreddit_slow kind = obj.__class__.__name__.lower() karma = sub.karma(kind, sr) is_self_link = (kind == 'link' and getattr(obj, 'is_self', False)) #check for old vote rel = cls.rel(sub, obj) oldvote = rel._fast_query(sub, obj, ['-1', '0', '1']).values() oldvote = filter(None, oldvote) amount = 1 if dir is True else 0 if dir is None else -1 is_new = False #old vote if len(oldvote): v = oldvote[0] oldamount = int(v._name) v._name = str(amount) #these still need to be recalculated old_valid_thing = getattr(v, 'valid_thing', False) v.valid_thing = (valid_thing(v, karma, cheater=cheater) and getattr(v, 'valid_thing', False)) v.valid_user = (getattr(v, 'valid_user', False) and v.valid_thing and valid_user(v, sr, karma)) #new vote else: is_new = True oldamount = 0 v = rel(sub, obj, str(amount)) v.ip = ip old_valid_thing = v.valid_thing = valid_thing(v, karma, cheater=cheater) v.valid_user = (v.valid_thing and valid_user(v, sr, karma) and not is_self_link) if organic: v.organic = organic v._commit() up_change, down_change = score_changes(amount, oldamount) if not (is_new and obj.author_id == sub._id and amount == 1): # we don't do this if it's the author's initial automatic # vote, because we checked it in with _ups == 1 update_score(obj, up_change, down_change, v, old_valid_thing) if v.valid_user: author = Account._byID(obj.author_id, data=True) author.incr_karma(kind, sr, up_change - down_change) #update the sr's valid vote count if is_new and v.valid_thing and kind == 'link': if sub._id != obj.author_id: incr_sr_count(sr) # now write it out to Cassandra. We'll write it out to both # this way for a while CassandraVote._copy_from(v) queries.changed(v._thing2, True) return v
def vote(cls, sub, obj, dir, ip, organic=False, cheater=False): from admintools import valid_user, valid_thing, update_score from r2.lib.count import incr_sr_count from r2.lib.db import queries sr = obj.subreddit_slow kind = obj.__class__.__name__.lower() karma = sub.karma(kind, sr) is_self_link = kind == "link" and getattr(obj, "is_self", False) # check for old vote rel = cls.rel(sub, obj) oldvote = rel._fast_query(sub, obj, ["-1", "0", "1"]).values() oldvote = filter(None, oldvote) amount = 1 if dir is True else 0 if dir is None else -1 is_new = False # old vote if len(oldvote): v = oldvote[0] oldamount = int(v._name) v._name = str(amount) # these still need to be recalculated old_valid_thing = getattr(v, "valid_thing", False) v.valid_thing = valid_thing(v, karma, cheater=cheater) and getattr(v, "valid_thing", False) v.valid_user = v.valid_user and v.valid_thing and valid_user(v, sr, karma) # new vote else: is_new = True oldamount = 0 v = rel(sub, obj, str(amount)) v.ip = ip old_valid_thing = v.valid_thing = valid_thing(v, karma, cheater=cheater) v.valid_user = v.valid_thing and valid_user(v, sr, karma) and not is_self_link if organic: v.organic = organic v._commit() v._fast_query_timestamp_touch(sub) up_change, down_change = score_changes(amount, oldamount) if not (is_new and obj.author_id == sub._id and amount == 1): # we don't do this if it's the author's initial automatic # vote, because we checked it in with _ups == 1 update_score(obj, up_change, down_change, v.valid_thing, old_valid_thing) if v.valid_user: author = Account._byID(obj.author_id, data=True) author.incr_karma(kind, sr, up_change - down_change) # update the sr's valid vote count if is_new and v.valid_thing and kind == "link": if sub._id != obj.author_id: incr_sr_count(sr) # now write it out to Cassandra. We'll write it out to both # this way for a while voter = v._thing1 votee = v._thing2 cvc = CassandraVote._rel(Account, votee.__class__) try: cv = cvc._fast_query(voter._id36, votee._id36) except tdb_cassandra.NotFound: cv = cvc(thing1_id=voter._id36, thing2_id=votee._id36) cv.name = v._name cv.valid_user, cv.valid_thing = v.valid_user, v.valid_thing cv.ip = v.ip if getattr(v, "organic", False) or hasattr(cv, "organic"): cv.organic = getattr(v, "organic", False) cv._commit() queries.changed(votee, True) return v
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
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