"""Ranking based on both age and quality.! ! This is the algorithm Reddit uses to sort stories. We want there to be! churn, a constant stream of new programs hitting the hot page,! so this algorithm takes into account both the score of the scratchpad and the age.! See http://amix.dk/blog/post/19588! """! s = getattr(score, upvotes_name) - getattr(score, downvotes_name)! ! # Weight votes logarithmically - initial votes are worth a ton! order = math.log(max(abs(s), 1), 10)! ! sign = 1 if s > 0 else -1 if s < 0 else 0! ! # Seconds since this algorithm's start date ! date = getattr(score, created_name) or datetime.datetime.now()! seconds = epoch_seconds(date) - 1349108492! ! return round(order + sign * seconds / decay_seconds, 7) class TimeDependentScoreProperty(ndb.ComputedProperty):! ! def __init__(self, decay_seconds, upvotes_name="upvotes",! downvotes_name="downvotes", created_name="created", **kwargs):! super(TimeDependentScoreProperty, self).__init__(functools.partial(! time_dependent, decay_seconds, upvotes_name, downvotes_name,! created_name), **kwargs)!