def test_can_set_member_data_namespace_option(self): self.leaderboard = Leaderboard('name', member_data_namespace='md') self.__rank_members_in_leaderboard() self.leaderboard.redis_connection.exists( "name:member_data").should.be.false self.leaderboard.redis_connection.exists("name:md").should.be.true
def test_init_uses_connection(self): lb = Leaderboard('lb0', connection=Redis(db=1)) lb.redis_connection.connection_pool.connection_kwargs[ 'db'].should.equal(1) lb = Leaderboard('lb1', connection=StrictRedis(db=1)) lb.redis_connection.connection_pool.connection_kwargs[ 'db'].should.equal(1)
def match_result_bot(self, user1, user2, match_info): user1_obj = User.objects.get(idUser=user1['userID']) scoreDiff = int(user1['score']) - int(user2['score']) if scoreDiff > 0: user1_obj.winCount += 1 udiff = 30 user1_obj.trophiesCount += udiff else: user1_obj.loseCount += 1 udiff = 30 user1_obj.trophiesCount -= udiff user1_obj.save() highscore_lb = Leaderboard('Bazuka_V1') highscore_lb.rank_member(user1_obj.username, user1_obj.trophiesCount, user1_obj.idUser) responseData = { 'user1': { 'userID': user1_obj.idUser, 'trophy_sum': user1_obj.trophiesCount, 'trophy_diff': udiff }, 'user2': { 'userID': -1, 'trophy_sum': 0, 'trophy_diff': 0 }, 'winner': int(match_info['winner']), 'roomID': match_info['roomID'] } return responseData
def test_global_member_data_option(self): self.leaderboard = Leaderboard('name', global_member_data=True) self.__rank_members_in_leaderboard() self.leaderboard.redis_connection.exists( "name:member_data").should.be.false self.leaderboard.redis_connection.exists("member_data").should.be.true
def get(self, request, game, user_id): """ Returns the scores around the user """ scoreboard = Leaderboard(game) scores = scoreboard.around_me(user_id) return {"meta": {}, "scores": scores if scores else []}
def get_queryset(self): highscores = Leaderboard('highscores') page = int(self.kwargs["page"]) users = highscores.leaders(page) user_ids = [] for user in users: user_ids.append(user["member"]) return User.objects.filter(id__in=user_ids).order_by("-skill_point")
def test_init_uses_connection_pooling(self): lb0 = Leaderboard('lb0', db=0) lb1 = Leaderboard('lb1', db=0) lb2 = Leaderboard('lb2', db=1) lb0.redis_connection.connection_pool.should.equal( lb1.redis_connection.connection_pool) lb0.redis_connection.connection_pool.should_not.equal( lb2.redis_connection.connection_pool)
def get_leaders(request): if request.method == 'GET': # data = request.data # userID = data['userID'] # deviceID = data['deviceID'] highscore_lb = Leaderboard('Bazuka_V1') top_100 = highscore_lb.top(100) responseData = {"top": top_100} return JsonResponse(responseData, status=status.HTTP_200_OK, encoder=MyEncoder)
def get(self, request, game, page=1): """ Returns the high scores @todo: pagination """ scoreboard = Leaderboard(game) scores = scoreboard.leaders(int(page)) total_pages = scoreboard.total_pages() return { "meta": { "total_pages": int(total_pages) }, "scores": scores if scores else [] }
def highscores(request, game="trivia", page=1): """ displays the scoreboard table """ template_name = 'scoreboard/highscores.html' # You can set the default page size #Leaderboard.DEFAULT_PAGE_SIZE = 2 page = int(page) scoreboard = Leaderboard(game) scores = scoreboard.leaders(int(page)) if not scores: scores = [] total_pages = int(scoreboard.total_pages()) # Pagination values has_next = True if (page < total_pages) else False has_prev = True if (page != 1) else False next_page = page + 1 if has_next else page prev_page = page - 1 if has_prev else page # hashmap to get the score instance quickly score_list = {} # Collect the user ids user_ids = [] for score in scores: user_ids.append(score["member"]) score_list[int(score["member"])] = score # Fetch users in question users = User.objects.filter(pk__in=user_ids) for user in users: score_list[user.pk]["user"] = user context = { 'scores': scores, 'total_pages': total_pages, 'game': game, 'page': page, 'has_next': has_next, 'has_prev': has_prev, 'next_page': next_page, 'prev_page': prev_page, } return render(request, template_name, context=context)
def main(): parser = argparse.ArgumentParser() parser.add_argument('--mode', choices=AVAILABLE_MODES, required=True) parser.add_argument('--count', type=check_positive, default=None) parser.add_argument('--user_id', default=None) parser.add_argument('--country', default=None) args = parser.parse_args() mode = args.mode count = args.count user_id = args.user_id country = args.country leaderboard = Leaderboard(mode, count, country, user_id) result = leaderboard.get_records() print(result)
def test_global_member_data_option(self): self.leaderboard = Leaderboard('name', global_member_data=True) self.__rank_members_in_leaderboard() self.leaderboard.redis_connection.exists( "name:member_data").should.be.false self.leaderboard.redis_connection.exists( "member_data").should.be.true
def get(self, request, *args, **kwargs): if request.GET.get("month") is None: today = datetime.datetime.today() month = str(today.month) + "-" + str(today.year) else: month = request.GET.get("month") monthly_highscores = Leaderboard(month + "_highscores", host="redis") page = int(self.kwargs["page"]) users = monthly_highscores.leaders(page) response = [] for user_id in users: user = User.objects.get(id=user_id["member"]) response.append({ "id": user.id, "username": user.username, "skill_point": user_id["score"], "profile_photo": user.profile_photo if user.profile_photo else None }) return Response(response, status=status.HTTP_200_OK)
def get_active_leaderboard(game, stat): if game not in ['ctv', 'ntb']: raise Exception("Unsupported game: %s" % game) if stat not in ['sc', 'tm']: raise Exception("Unsupported stat type: %s" % stat) #last_sun, last_sat = last_sun_sat() #active_week = (last_sat + datetime.timedelta(days=1)).strftime("%Y_%m_%d") lb = Leaderboard('%s_%s' % (game, stat), host=settings.LEADERBOARD_REDIS_HOST) return lb
async def add_leaderboard(self, ctx, leaderboard, points=100): """Add a new leaderboard.""" points = float(points) if leaderboard in self.bot.lboards.keys(): await ctx.send('Leaderboard already exists!') return self.bot.lboards[leaderboard] = Leaderboard( leaderboard, page_size=10, password=self.bot.redis_key) logging.info('Added the leaderboard "%s" with %f points', leaderboard, points)
def handle(self, *args, **options): # All time leaderboard highscores = Leaderboard('highscores') users = User.objects.filter() for user in users: highscores.rank_member(user.id, user.skill_point) # Monthly leaderboards monthly_scores = MonthlyScore.objects.filter() for monthly in monthly_scores: monthly_highscores = Leaderboard(str(monthly.month.month) + '-' + str(monthly.month.year) + '_highscores', host="redis") monthly_highscores.rank_member(monthly.user.id, monthly.skill_point)
def update_username(request): if request.method == 'POST': data = request.POST userID = (data.get('userID', default=None)) username = data.get('username', default=None) user = None if userID is not None: user = User.objects.get(idUser=userID) user.username = username user.save() highscore_lb = Leaderboard('Bazuka_V1') highscore_lb.rank_member(user.username, user.trophiesCount, user.idUser) responseData = { 'userID': userID, 'deviceID': user.deviceID, 'username': username } return JsonResponse(responseData, status=status.HTTP_200_OK)
def post(self, request, game, page=1): """ Creates new rankings Params: game: game identifier user_id: pk of the user score: positive integer Returns: 1 on creation, 0 on updation """ user_id = request.POST.get('user_id') score = request.POST.get('score') try: user = User.objects.get(pk=user_id) except: return Http404('User Not Found') scoreboard = Leaderboard(game) status = scoreboard.rank_member(user.id, int(score)) return {"status": status}
def handle(self, *args, **options): global supported code = options['code'] field = options['field'] user_pk = options['user_pk'] user = User.objects.get(pk=user_pk) lb_key = leaderboard_key_for(user) print("\nZeroing scores for game %s for field %s for user %s" % (game_model_map[code].__name__, field, user_pk)) model = game_model_map[code] if field == 'sc': lb_score = Leaderboard('%s_sc' % (code,), host=settings.LEADERBOARD_REDIS_HOST) model.objects.filter(user=user).update(stat_score=0) lb_score.rank_member(lb_key, 0) elif field == 'tm': lb_time = Leaderboard('%s_tm' % (code,), host=settings.LEADERBOARD_REDIS_HOST) model.objects.filter(user=user).update(stat_time_secs=0) lb_time.rank_member(lb_key, 0)
def handle(self, *args, **options): global supported code = options['code'] if code == '-1': to_do = supported else: if code not in supported: raise Exception("Unrecognized code:%s" % code) to_do = [code] for game in to_do: print("\nDeleting all scores for game %s" % game_model_map[game].__name__) model = game_model_map[game] model.objects.all().delete() lb_score = Leaderboard('%s_sc' % (game, ), host=settings.LEADERBOARD_REDIS_HOST) lb_time = Leaderboard('%s_tm' % (game, ), host=settings.LEADERBOARD_REDIS_HOST) lb_score.delete_leaderboard() lb_time.delete_leaderboard()
def setUp(self): self.leaderboard = Leaderboard('name')
class LeaderboardTest(unittest.TestCase): def setUp(self): self.leaderboard = Leaderboard('name') def tearDown(self): self.leaderboard.redis_connection.flushdb() Leaderboard.MEMBER_KEY = 'member' Leaderboard.SCORE_KEY = 'score' Leaderboard.RANK_KEY = 'rank' Leaderboard.MEMBER_DATA_KEY = 'member_data' def test_version(self): Leaderboard.VERSION.should.equal('3.5.0') def test_init_with_defaults(self): 'name'.should.equal(self.leaderboard.leaderboard_name) len(self.leaderboard.options).should.be(1) self.leaderboard.options['connection_pool'].should.be.a(ConnectionPool) self.leaderboard.redis_connection.should.be.a(Redis) self.leaderboard.DEFAULT_PAGE_SIZE.should.equal( self.leaderboard.page_size) def test_init_sets_page_size_to_default_if_set_to_invalid_value(self): self.leaderboard = Leaderboard('name', page_size=0) self.leaderboard.page_size.should.equal(Leaderboard.DEFAULT_PAGE_SIZE) def test_init_uses_connection_pooling(self): lb0 = Leaderboard('lb0', db=0) lb1 = Leaderboard('lb1', db=0) lb2 = Leaderboard('lb2', db=1) lb0.redis_connection.connection_pool.should.equal( lb1.redis_connection.connection_pool) lb0.redis_connection.connection_pool.should_not.equal( lb2.redis_connection.connection_pool) def test_init_uses_connection(self): lb = Leaderboard('lb0', connection=Redis(db=1)) lb.redis_connection.connection_pool.connection_kwargs[ 'db'].should.equal(1) lb = Leaderboard('lb1', connection=StrictRedis(db=1)) lb.redis_connection.connection_pool.connection_kwargs[ 'db'].should.equal(1) def test_delete_leaderboard(self): self.__rank_members_in_leaderboard() self.leaderboard.redis_connection.exists('name').should.be.true self.leaderboard.delete_leaderboard() self.leaderboard.redis_connection.exists('name').should.be.false def test_member_data_for(self): self.__rank_members_in_leaderboard() self.leaderboard.member_data_for('member_1').should.eql( str({'member_name': 'Leaderboard member 1'})) def test_members_data_for(self): self.__rank_members_in_leaderboard() members_data = self.leaderboard.members_data_for( ['member_1', 'member_3']) members_data[0].should.eql(str({'member_name': 'Leaderboard member 1'})) members_data[1].should.eql(str({'member_name': 'Leaderboard member 3'})) def test_update_member_data(self): self.__rank_members_in_leaderboard() self.leaderboard.update_member_data( 'member_1', {'member_name': 'Updated Leaderboard member 1'}) self.leaderboard.member_data_for('member_1').should.eql( str({'member_name': 'Updated Leaderboard member 1'})) def test_remove_member_data(self): self.__rank_members_in_leaderboard() self.leaderboard.remove_member_data('member_1') self.leaderboard.member_data_for('member_1').should.be(None) def test_total_members(self): self.__rank_members_in_leaderboard() self.leaderboard.total_members().should.equal(5) def test_remove_member(self): self.__rank_members_in_leaderboard() self.leaderboard.total_members().should.equal(5) self.leaderboard.remove_member('member_1') self.leaderboard.total_members().should.equal(4) def test_remove_member_also_removes_member_data(self): self.__rank_members_in_leaderboard() self.leaderboard.redis_connection.exists( "name:member_data").should.be.true len(self.leaderboard.redis_connection.hgetall( "name:member_data")).should.equal(5) self.leaderboard.total_members().should.equal(5) self.leaderboard.remove_member('member_1') self.leaderboard.redis_connection.exists( "name:member_data").should.be.true len(self.leaderboard.redis_connection.hgetall( "name:member_data")).should.equal(4) self.leaderboard.total_members().should.equal(4) def test_total_pages(self): self.__rank_members_in_leaderboard(27) self.leaderboard.total_members().should.equal(26) self.leaderboard.total_pages().should.equal(2) def test_total_members_in_score_range(self): self.__rank_members_in_leaderboard() self.leaderboard.total_members_in_score_range(2, 4).should.equal(3) def test_score_for(self): self.__rank_members_in_leaderboard() self.leaderboard.score_for('member_5').should.equal(5.0) self.leaderboard.score_for('jones').should.be(None) def test_check_member(self): self.__rank_members_in_leaderboard() self.leaderboard.check_member('member_3').should.be.true self.leaderboard.check_member('member_6').should.be.false def test_rank_for(self): self.__rank_members_in_leaderboard() self.leaderboard.rank_for('member_5').should.equal(1) def test_change_score_for(self): self.__rank_members_in_leaderboard() self.leaderboard.change_score_for('member_1', 99) self.leaderboard.rank_for('member_1').should.equal(1) self.leaderboard.score_for('member_1').should.equal(100.0) def test_change_score_for_and_member_data_for_a_member(self): self.leaderboard.change_score_for('member_1', 5, 'optional-data') self.leaderboard.score_for('member_1').should.equal(5.0) self.leaderboard.member_data_for('member_1').should.equal( 'optional-data') def test_score_and_rank_for(self): self.__rank_members_in_leaderboard() score_and_rank = self.leaderboard.score_and_rank_for('member_3') score_and_rank['member'].should.equal('member_3') score_and_rank['score'].should.equal(3.0) score_and_rank['rank'].should.equal(3) score_and_rank = self.leaderboard.score_and_rank_for('jones') score_and_rank['member'].should.equal('jones') score_and_rank['score'].should.be(None) score_and_rank['rank'].should.be(None) def test_remove_members_in_score_range(self): self.__rank_members_in_leaderboard() self.leaderboard.total_members().should.equal(5) self.leaderboard.remove_members_in_score_range(2, 4) self.leaderboard.total_members().should.equal(2) def test_remove_members_outside_rank(self): self.__rank_members_in_leaderboard() self.leaderboard.total_members().should.equal(5) self.leaderboard.remove_members_outside_rank(3).should.equal(2) leaders = self.leaderboard.leaders(1) len(leaders).should.equal(3) leaders[0]['member'].should.equal('member_5') leaders[2]['member'].should.equal('member_3') self.leaderboard.order = Leaderboard.ASC self.__rank_members_in_leaderboard() self.leaderboard.total_members().should.equal(5) self.leaderboard.remove_members_outside_rank(3).should.equal(2) leaders = self.leaderboard.leaders(1) len(leaders).should.equal(3) leaders[0]['member'].should.equal('member_1') leaders[2]['member'].should.equal('member_3') def test_page_for(self): self.leaderboard.page_for('jones').should.equal(0) self.__rank_members_in_leaderboard(21) self.leaderboard.page_for('member_17').should.equal(1) self.leaderboard.page_for('member_11').should.equal(1) self.leaderboard.page_for('member_10').should.equal(1) self.leaderboard.page_for('member_1').should.equal(1) self.leaderboard.page_for('member_17', 10).should.equal(1) self.leaderboard.page_for('member_11', 10).should.equal(1) self.leaderboard.page_for('member_10', 10).should.equal(2) self.leaderboard.page_for('member_1', 10).should.equal(2) def test_page_for_with_sort_option_ASC(self): self.leaderboard.order = Leaderboard.ASC self.leaderboard.page_for('jones').should.equal(0) self.__rank_members_in_leaderboard(21) self.leaderboard.page_for('member_10', 10).should.equal(1) self.leaderboard.page_for('member_1', 10).should.equal(1) self.leaderboard.page_for('member_17', 10).should.equal(2) self.leaderboard.page_for('member_11', 10).should.equal(2) def test_percentile_for(self): self.__rank_members_in_leaderboard(13) self.leaderboard.percentile_for('member_1').should.eql(0.0) self.leaderboard.percentile_for('member_2').should.eql(9.0) self.leaderboard.percentile_for('member_3').should.eql(17.0) self.leaderboard.percentile_for('member_4').should.eql(25.0) self.leaderboard.percentile_for('member_12').should.eql(92.0) def test_score_for_percentile(self): self.__rank_members_in_leaderboard(6) self.leaderboard.score_for_percentile(0).should.eql(1.0) self.leaderboard.score_for_percentile(75).should.eql(4.0) self.leaderboard.score_for_percentile(87.5).should.eql(4.5) self.leaderboard.score_for_percentile(93.75).should.eql(4.75) self.leaderboard.score_for_percentile(100).should.eql(5.0) def test_score_for_percentile_with_sort_option_ASC(self): self.leaderboard.order = Leaderboard.ASC self.__rank_members_in_leaderboard(6) self.leaderboard.score_for_percentile(0).should.eql(5.0) self.leaderboard.score_for_percentile(75).should.eql(2.0) self.leaderboard.score_for_percentile(87.5).should.eql(1.5) self.leaderboard.score_for_percentile(93.75).should.eql(1.25) self.leaderboard.score_for_percentile(100).should.eql(1.0) def test_expire_leaderboard(self): self.__rank_members_in_leaderboard() self.leaderboard.expire_leaderboard(3) ttl = self.leaderboard.redis_connection.ttl( self.leaderboard.leaderboard_name) ttl.should.be.greater_than(1) ttl = self.leaderboard.redis_connection.ttl( '%s:member_data' % self.leaderboard.leaderboard_name) ttl.should.be.greater_than(1) def test_expire_leaderboard_at(self): self.__rank_members_in_leaderboard() self.leaderboard.expire_leaderboard_at(int(time.time() + 10)) ttl = self.leaderboard.redis_connection.ttl( self.leaderboard.leaderboard_name) ttl.should.be.lower_than(11) ttl = self.leaderboard.redis_connection.ttl( '%s:member_data' % self.leaderboard.leaderboard_name) ttl.should.be.lower_than(11) def test_leaders(self): self.__rank_members_in_leaderboard(27) leaders = self.leaderboard.leaders(1) len(leaders).should.equal(25) leaders[0]['member'].should.equal('member_26') leaders[0]['rank'].should.equal(1) leaders[24]['member'].should.equal('member_2') leaders = self.leaderboard.leaders(2) len(leaders).should.equal(1) leaders[0]['member'].should.equal('member_1') leaders[0]['rank'].should.equal(26) leaders = self.leaderboard.leaders(1, page_size=5) len(leaders).should.equal(5) def test_leaders_with_optional_member_data(self): self.__rank_members_in_leaderboard() leaders = self.leaderboard.leaders(1, with_member_data=True) len(leaders).should.equal(5) leaders[0]['member'].should.equal('member_5') leaders[0]['member_data'].should.equal( str({'member_name': 'Leaderboard member 5'})) def test_leaders_return_type(self): leaders = self.leaderboard.leaders(1) type(leaders).should.equal(type([])) leaders.should.equal([]) def test_ranked_in_list_with_sort_by(self): self.__rank_members_in_leaderboard(26) leaders = self.leaderboard.ranked_in_list( ['member_25', 'member_1', 'member_15'], sort_by='score') len(leaders).should.equal(3) leaders[0]['member'].should.equal('member_1') leaders[1]['member'].should.equal('member_15') leaders[2]['member'].should.equal('member_25') leaders = self.leaderboard.ranked_in_list( ['member_25', 'member_1', 'member_15'], sort_by='rank') len(leaders).should.be(3) leaders[0]['member'].should.equal('member_25') leaders[1]['member'].should.equal('member_15') leaders[2]['member'].should.equal('member_1') def test_ranked_in_list(self): self.__rank_members_in_leaderboard(27) leaders = self.leaderboard.ranked_in_list( ['member_1', 'member_15', 'member_25']) len(leaders).should.be(3) leaders[0]['member'].should.equal('member_1') leaders[1]['member'].should.equal('member_15') leaders[2]['member'].should.equal('member_25') def test_ranked_in_list_with_unknown_member(self): self.__rank_members_in_leaderboard(27) leaders = self.leaderboard.ranked_in_list(['jones']) len(leaders).should.be(1) leaders[0]['member'].should.equal('jones') leaders[0]['score'].should.be(None) leaders[0]['rank'].should.be(None) def test_all_leaders(self): self.__rank_members_in_leaderboard(26) leaders = self.leaderboard.all_leaders() len(leaders).should.be(25) leaders[0]['member'].should.equal('member_25') def test_members_from_score_range(self): self.__rank_members_in_leaderboard(26) members = self.leaderboard.members_from_score_range(10, 15) member_15 = {'member': 'member_15', 'score': 15.0, 'rank': 11} members[0].should.eql(member_15) member_10 = {'member': 'member_10', 'score': 10.0, 'rank': 16} members[5].should.eql(member_10) def test_members_from_rank_range(self): self.__rank_members_in_leaderboard(26) members = self.leaderboard.members_from_rank_range(5, 9) len(members).should.be(5) members[0]['member'].should.eql('member_21') members[0]['score'].should.equal(21.0) members[4]['member'].should.eql('member_17') members = self.leaderboard.members_from_rank_range(1, 1) len(members).should.equal(1) members[0]['member'].should.eql('member_25') members = self.leaderboard.members_from_rank_range(1, 26) len(members).should.equal(25) members[0]['member'].should.eql('member_25') members[0]['score'].should.equal(25.0) members[24]['member'].should.eql('member_1') def test_member_at(self): self.__rank_members_in_leaderboard(51) self.leaderboard.member_at(1)['rank'].should.equal(1) self.leaderboard.member_at(1)['score'].should.equal(50.0) self.leaderboard.member_at(26)['rank'].should.equal(26) self.leaderboard.member_at(50)['rank'].should.equal(50) self.leaderboard.member_at(51).should.equal(None) self.leaderboard.member_at( 1, with_member_data=True)['member_data'].should.eql( str({'member_name': 'Leaderboard member 50'})) self.leaderboard.member_at(-5).should.equal(None) def test_around_me(self): self.__rank_members_in_leaderboard(Leaderboard.DEFAULT_PAGE_SIZE * 3 + 2) self.leaderboard.total_members().should.be( Leaderboard.DEFAULT_PAGE_SIZE * 3 + 1) leaders_around_me = self.leaderboard.around_me('member_30') (len(leaders_around_me) / 2).should.equal(self.leaderboard.page_size / 2) leaders_around_me = self.leaderboard.around_me('member_1') len(leaders_around_me).should.equal(self.leaderboard.page_size / 2 + 1) leaders_around_me = self.leaderboard.around_me('member_76') (len(leaders_around_me) / 2).should.equal(self.leaderboard.page_size / 2) def test_members_only(self): exp = [{'member': 'member_%d' % x} for x in reversed(range(1, 27))] self.__rank_members_in_leaderboard(27) leaders = self.leaderboard.leaders(1, members_only=True) leaders.should.equal(exp[0:25]) leaders = self.leaderboard.leaders(2, members_only=True) leaders.should.equal(exp[25:26]) members = self.leaderboard.all_leaders(members_only=True) members.should.equal(exp) members = self.leaderboard.members_from_score_range(10, 15, members_only=True) members.should.equal(exp[11:17]) members = self.leaderboard.members_from_rank_range(5, 9, members_only=True) members.should.equal(exp[4:9]) leaders_around_me = self.leaderboard.around_me('member_25', page_size=3, members_only=True) leaders_around_me.should.equal(exp[0:3]) def test_merge_leaderboards(self): foo_leaderboard = Leaderboard('foo') bar_leaderboard = Leaderboard('bar') foo_leaderboard.rank_member('foo_1', 1) foo_leaderboard.rank_member('foo_2', 2) bar_leaderboard.rank_member('bar_1', 1) bar_leaderboard.rank_member('bar_2', 2) bar_leaderboard.rank_member('bar_3', 5) foo_leaderboard.merge_leaderboards('foobar', ['bar'], aggregate='SUM') foobar_leaderboard = Leaderboard('foobar') foobar_leaderboard.total_members().should.equal(5) foobar_leaderboard.leaders(1)[0]['member'].should.equal('bar_3') def test_intersect_leaderboards(self): foo_leaderboard = Leaderboard('foo') bar_leaderboard = Leaderboard('bar') foo_leaderboard.rank_member('foo_1', 1) foo_leaderboard.rank_member('foo_2', 2) foo_leaderboard.rank_member('bar_3', 6) bar_leaderboard.rank_member('bar_1', 3) bar_leaderboard.rank_member('foo_1', 4) bar_leaderboard.rank_member('bar_3', 5) foo_leaderboard.intersect_leaderboards('foobar', ['bar'], aggregate='SUM') foobar_leaderboard = Leaderboard('foobar') foobar_leaderboard.total_members().should.equal(2) foobar_leaderboard.leaders(1)[0]['member'].should.equal('bar_3') def test_rank_member_if(self): def highscore_check(self, member, current_score, score, member_data, leaderboard_options): if (current_score is None): return True if (score > current_score): return True return False self.leaderboard.total_members().should.equal(0) self.leaderboard.rank_member_if(highscore_check, 'david', 1337) self.leaderboard.total_members().should.equal(1) self.leaderboard.score_for('david').should.equal(1337.0) self.leaderboard.rank_member_if(highscore_check, 'david', 1336) self.leaderboard.score_for('david').should.equal(1337.0) self.leaderboard.rank_member_if(highscore_check, 'david', 1338) self.leaderboard.score_for('david').should.equal(1338.0) def test_rank_members(self): self.leaderboard.total_members().should.equal(0) self.leaderboard.rank_members(['member_1', 1000, 'member_2', 3000]) self.leaderboard.total_members().should.equal(2) def test_rank_member_across(self): self.leaderboard.rank_member_across(['highscores', 'more_highscores'], 'david', 50000, {'member_name': 'david'}) len(self.leaderboard.leaders_in('highscores', 1)).should.equal(1) len(self.leaderboard.leaders_in('more_highscores', 1)).should.equal(1) def test_custom_keys_for_member_score_rank_and_member_data(self): Leaderboard.MEMBER_KEY = 'member_custom' Leaderboard.SCORE_KEY = 'score_custom' Leaderboard.RANK_KEY = 'rank_custom' Leaderboard.MEMBER_DATA_KEY = 'member_data_custom' self.__rank_members_in_leaderboard(26) leaders = self.leaderboard.leaders(1, with_member_data=True) len(leaders).should.equal(25) leaders[0]['member_custom'].should.equal('member_25') leaders[0]['score_custom'].should.equal(25.0) leaders[0]['rank_custom'].should.equal(1) leaders[0]['member_data_custom'].should.equal( "{'member_name': 'Leaderboard member 25'}") def test_can_use_StrictRedis_class_for_connection(self): lb = Leaderboard('lb1', connection=StrictRedis(db=0)) lb.rank_member('david', 50.1) lb.score_for('david').should.equal(50.1) lb.rank_for('david').should.equal(1) len(lb.leaders(1)).should.equal(1) def test_can_set_member_data_namespace_option(self): self.leaderboard = Leaderboard('name', member_data_namespace='md') self.__rank_members_in_leaderboard() self.leaderboard.redis_connection.exists( "name:member_data").should.be.false self.leaderboard.redis_connection.exists("name:md").should.be.true def test_global_member_data_option(self): self.leaderboard = Leaderboard('name', global_member_data=True) self.__rank_members_in_leaderboard() self.leaderboard.redis_connection.exists( "name:member_data").should.be.false self.leaderboard.redis_connection.exists("member_data").should.be.true def test_retrieve_a_given_set_of_members_from_the_leaderboard_in_a_range_from_1_to_the_number_given( self): self.__rank_members_in_leaderboard(26) members = self.leaderboard.top(5) len(members).should.equal(5) members[0]['member'].should.equal('member_25') members[0]['score'].should.equal(25.0) members[4]['member'].should.equal('member_21') members = self.leaderboard.top(1) len(members).should.equal(1) members[0]['member'].should.equal('member_25') members = self.leaderboard.top(26) len(members).should.equal(25) members[0]['member'].should.equal('member_25') members[0]['score'].should.equal(25.0) members[24]['member'].should.equal('member_1') def test_retrieve_a_given_set_of_members_from_the_named_leaderboard_in_a_range_from_1_to_the_number_given( self): self.__rank_members_in_leaderboard(26) members = self.leaderboard.top_in('name', 5) len(members).should.equal(5) members[0]['member'].should.equal('member_25') members[0]['score'].should.equal(25.0) members[4]['member'].should.equal('member_21') members = self.leaderboard.top_in('name', 1) len(members).should.equal(1) members[0]['member'].should.equal('member_25') members = self.leaderboard.top_in('name', 26) len(members).should.equal(25) members[0]['member'].should.equal('member_25') members[0]['score'].should.equal(25.0) members[24]['member'].should.equal('member_1') def test_retrieve_a_given_set_of_members_from_the_leaderboard_in_a_range_from_1_to_the_number_given_with_sort_option_ASC( self): self.leaderboard.order = Leaderboard.ASC self.__rank_members_in_leaderboard(26) members = self.leaderboard.top(5) len(members).should.equal(5) members[0]['member'].should.equal('member_1') members[0]['score'].should.equal(1.0) members[4]['member'].should.equal('member_5') members = self.leaderboard.top(1) len(members).should.equal(1) members[0]['member'].should.equal('member_1') members = self.leaderboard.top(26) len(members).should.equal(25) members[0]['member'].should.equal('member_1') members[0]['score'].should.equal(1.0) members[24]['member'].should.equal('member_25') def test_retrieve_a_given_set_of_members_from_the_named_leaderboard_in_a_range_from_1_to_the_number_given_with_sort_option_ASC( self): self.leaderboard.order = Leaderboard.ASC self.__rank_members_in_leaderboard(26) members = self.leaderboard.top_in('name', 5) len(members).should.equal(5) members[0]['member'].should.equal('member_1') members[0]['score'].should.equal(1.0) members[4]['member'].should.equal('member_5') members = self.leaderboard.top_in('name', 1) len(members).should.equal(1) members[0]['member'].should.equal('member_1') members = self.leaderboard.top_in('name', 26) len(members).should.equal(25) members[0]['member'].should.equal('member_1') members[0]['score'].should.equal(1.0) members[24]['member'].should.equal('member_25') def test_allow_you_to_include_or_exclude_missing_members_using_the_include_missing_option( self): self.__rank_members_in_leaderboard(26) leaders = self.leaderboard.ranked_in_list( ['member_1', 'member_15', 'member_25', 'member_200']) len(leaders).should.equal(4) leaders[0]['member'].should.equal('member_1') leaders[1]['member'].should.equal('member_15') leaders[2]['member'].should.equal('member_25') leaders[3]['member'].should.equal('member_200') leaders = self.leaderboard.ranked_in_list( ['member_1', 'member_15', 'member_25', 'member_200'], include_missing=False) len(leaders).should.equal(3) leaders[0]['member'].should.equal('member_1') leaders[1]['member'].should.equal('member_15') leaders[2]['member'].should.equal('member_25') def __rank_members_in_leaderboard(self, members_to_add=6): for index in range(1, members_to_add): self.leaderboard.rank_member( 'member_%s' % index, index, {'member_name': 'Leaderboard member %s' % index})
def test_intersect_leaderboards(self): foo_leaderboard = Leaderboard("foo") bar_leaderboard = Leaderboard("bar") foo_leaderboard.rank_member("foo_1", 1) foo_leaderboard.rank_member("foo_2", 2) foo_leaderboard.rank_member("bar_3", 6) bar_leaderboard.rank_member("bar_1", 3) bar_leaderboard.rank_member("foo_1", 4) bar_leaderboard.rank_member("bar_3", 5) foo_leaderboard.intersect_leaderboards("foobar", ["bar"], aggregate="SUM") foobar_leaderboard = Leaderboard("foobar") foobar_leaderboard.total_members().should.equal(2) foobar_leaderboard.leaders(1)[0]["member"].should.equal("bar_3")
class LeaderboardTest(unittest.TestCase): def setUp(self): self.leaderboard = Leaderboard("name") def tearDown(self): self.leaderboard.redis_connection.flushdb() Leaderboard.MEMBER_KEY = "member" Leaderboard.SCORE_KEY = "score" Leaderboard.RANK_KEY = "rank" Leaderboard.MEMBER_DATA_KEY = "member_data" def test_version(self): Leaderboard.VERSION.should.equal("3.0.0") def test_init_with_defaults(self): "name".should.equal(self.leaderboard.leaderboard_name) len(self.leaderboard.options).should.be(1) self.leaderboard.options["connection_pool"].should.be.a(ConnectionPool) self.leaderboard.redis_connection.should.be.a(Redis) self.leaderboard.DEFAULT_PAGE_SIZE.should.equal(self.leaderboard.page_size) def test_init_sets_page_size_to_default_if_set_to_invalid_value(self): self.leaderboard = Leaderboard("name", page_size=0) self.leaderboard.page_size.should.equal(Leaderboard.DEFAULT_PAGE_SIZE) def test_init_uses_connection_pooling(self): lb0 = Leaderboard("lb0", db=0) lb1 = Leaderboard("lb1", db=0) lb2 = Leaderboard("lb2", db=1) lb0.redis_connection.connection_pool.should.equal(lb1.redis_connection.connection_pool) lb0.redis_connection.connection_pool.should_not.equal(lb2.redis_connection.connection_pool) def test_init_uses_connection(self): lb = Leaderboard("lb0", connection=Redis(db=1)) lb.redis_connection.connection_pool.connection_kwargs["db"].should.equal(1) lb = Leaderboard("lb1", connection=StrictRedis(db=1)) lb.redis_connection.connection_pool.connection_kwargs["db"].should.equal(1) def test_delete_leaderboard(self): self.__rank_members_in_leaderboard() self.leaderboard.redis_connection.exists("name").should.be.true self.leaderboard.delete_leaderboard() self.leaderboard.redis_connection.exists("name").should.be.false def test_member_data_for(self): self.__rank_members_in_leaderboard() self.leaderboard.member_data_for("member_1").should.eql(str({"member_name": "Leaderboard member 1"})) def test_update_member_data(self): self.__rank_members_in_leaderboard() self.leaderboard.update_member_data("member_1", {"member_name": "Updated Leaderboard member 1"}) self.leaderboard.member_data_for("member_1").should.eql(str({"member_name": "Updated Leaderboard member 1"})) def test_remove_member_data(self): self.__rank_members_in_leaderboard() self.leaderboard.remove_member_data("member_1") self.leaderboard.member_data_for("member_1").should.be(None) def test_total_members(self): self.__rank_members_in_leaderboard() self.leaderboard.total_members().should.equal(5) def test_remove_member(self): self.__rank_members_in_leaderboard() self.leaderboard.total_members().should.equal(5) self.leaderboard.remove_member("member_1") self.leaderboard.total_members().should.equal(4) def test_remove_member_also_removes_member_data(self): self.__rank_members_in_leaderboard() self.leaderboard.redis_connection.exists("name:member_data").should.be.true len(self.leaderboard.redis_connection.hgetall("name:member_data")).should.equal(5) self.leaderboard.total_members().should.equal(5) self.leaderboard.remove_member("member_1") self.leaderboard.redis_connection.exists("name:member_data").should.be.true len(self.leaderboard.redis_connection.hgetall("name:member_data")).should.equal(4) self.leaderboard.total_members().should.equal(4) def test_total_pages(self): self.__rank_members_in_leaderboard(27) self.leaderboard.total_members().should.equal(26) self.leaderboard.total_pages().should.equal(2) def test_total_members_in_score_range(self): self.__rank_members_in_leaderboard() self.leaderboard.total_members_in_score_range(2, 4).should.equal(3) def test_score_for(self): self.__rank_members_in_leaderboard() self.leaderboard.score_for("member_5").should.equal(5.0) self.leaderboard.score_for("jones").should.be(None) def test_check_member(self): self.__rank_members_in_leaderboard() self.leaderboard.check_member("member_3").should.be.true self.leaderboard.check_member("member_6").should.be.false def test_rank_for(self): self.__rank_members_in_leaderboard() self.leaderboard.rank_for("member_5").should.equal(1) def test_change_score_for(self): self.__rank_members_in_leaderboard() self.leaderboard.change_score_for("member_1", 99) self.leaderboard.rank_for("member_1").should.equal(1) self.leaderboard.score_for("member_1").should.equal(100.0) def test_score_and_rank_for(self): self.__rank_members_in_leaderboard() score_and_rank = self.leaderboard.score_and_rank_for("member_3") score_and_rank["member"].should.equal("member_3") score_and_rank["score"].should.equal(3.0) score_and_rank["rank"].should.equal(3) score_and_rank = self.leaderboard.score_and_rank_for("jones") score_and_rank["member"].should.equal("jones") score_and_rank["score"].should.be(None) score_and_rank["rank"].should.be(None) def test_remove_members_in_score_range(self): self.__rank_members_in_leaderboard() self.leaderboard.total_members().should.equal(5) self.leaderboard.remove_members_in_score_range(2, 4) self.leaderboard.total_members().should.equal(2) def test_remove_members_outside_rank(self): self.__rank_members_in_leaderboard() self.leaderboard.total_members().should.equal(5) self.leaderboard.remove_members_outside_rank(3).should.equal(2) leaders = self.leaderboard.leaders(1) len(leaders).should.equal(3) leaders[0]["member"].should.equal("member_5") leaders[2]["member"].should.equal("member_3") self.leaderboard.order = Leaderboard.ASC self.__rank_members_in_leaderboard() self.leaderboard.total_members().should.equal(5) self.leaderboard.remove_members_outside_rank(3).should.equal(2) leaders = self.leaderboard.leaders(1) len(leaders).should.equal(3) leaders[0]["member"].should.equal("member_1") leaders[2]["member"].should.equal("member_3") def test_page_for(self): self.leaderboard.page_for("jones").should.equal(0) self.__rank_members_in_leaderboard(21) self.leaderboard.page_for("member_17").should.equal(1) self.leaderboard.page_for("member_11").should.equal(1) self.leaderboard.page_for("member_10").should.equal(1) self.leaderboard.page_for("member_1").should.equal(1) self.leaderboard.page_for("member_17", 10).should.equal(1) self.leaderboard.page_for("member_11", 10).should.equal(1) self.leaderboard.page_for("member_10", 10).should.equal(2) self.leaderboard.page_for("member_1", 10).should.equal(2) def test_page_for_with_sort_option_ASC(self): self.leaderboard.order = Leaderboard.ASC self.leaderboard.page_for("jones").should.equal(0) self.__rank_members_in_leaderboard(21) self.leaderboard.page_for("member_10", 10).should.equal(1) self.leaderboard.page_for("member_1", 10).should.equal(1) self.leaderboard.page_for("member_17", 10).should.equal(2) self.leaderboard.page_for("member_11", 10).should.equal(2) def test_percentile_for(self): self.__rank_members_in_leaderboard(13) self.leaderboard.percentile_for("member_1").should.eql(0) self.leaderboard.percentile_for("member_2").should.eql(9) self.leaderboard.percentile_for("member_3").should.eql(17) self.leaderboard.percentile_for("member_4").should.eql(25) self.leaderboard.percentile_for("member_12").should.eql(92) def test_score_for_percentile(self): self.__rank_members_in_leaderboard(6) self.leaderboard.score_for_percentile(0).should.eql(1.0) self.leaderboard.score_for_percentile(75).should.eql(4.0) self.leaderboard.score_for_percentile(87.5).should.eql(4.5) self.leaderboard.score_for_percentile(93.75).should.eql(4.75) self.leaderboard.score_for_percentile(100).should.eql(5.0) def test_score_for_percentile_with_sort_option_ASC(self): self.leaderboard.order = Leaderboard.ASC self.__rank_members_in_leaderboard(6) self.leaderboard.score_for_percentile(0).should.eql(5.0) self.leaderboard.score_for_percentile(75).should.eql(2.0) self.leaderboard.score_for_percentile(87.5).should.eql(1.5) self.leaderboard.score_for_percentile(93.75).should.eql(1.25) self.leaderboard.score_for_percentile(100).should.eql(1.0) def test_expire_leaderboard(self): self.__rank_members_in_leaderboard() self.leaderboard.expire_leaderboard(3) ttl = self.leaderboard.redis_connection.ttl(self.leaderboard.leaderboard_name) ttl.should.be.greater_than(1) ttl = self.leaderboard.redis_connection.ttl("%s:member_data" % self.leaderboard.leaderboard_name) ttl.should.be.greater_than(1) def test_expire_leaderboard_at(self): self.__rank_members_in_leaderboard() self.leaderboard.expire_leaderboard_at(int(time.time() + 10)) ttl = self.leaderboard.redis_connection.ttl(self.leaderboard.leaderboard_name) ttl.should.be.lower_than(11) ttl = self.leaderboard.redis_connection.ttl("%s:member_data" % self.leaderboard.leaderboard_name) ttl.should.be.lower_than(11) def test_leaders(self): self.__rank_members_in_leaderboard(27) leaders = self.leaderboard.leaders(1) len(leaders).should.equal(25) leaders[0]["member"].should.equal("member_26") leaders[0]["rank"].should.equal(1) leaders[24]["member"].should.equal("member_2") leaders = self.leaderboard.leaders(2) len(leaders).should.equal(1) leaders[0]["member"].should.equal("member_1") leaders[0]["rank"].should.equal(26) leaders = self.leaderboard.leaders(1, page_size=5) len(leaders).should.equal(5) def test_leaders_with_optional_member_data(self): self.__rank_members_in_leaderboard() leaders = self.leaderboard.leaders(1, with_member_data=True) len(leaders).should.equal(5) leaders[0]["member"].should.equal("member_5") leaders[0]["member_data"].should.be(str({"member_name": "Leaderboard member 5"})) def test_leaders_return_type(self): leaders = self.leaderboard.leaders(1) type(leaders).should.equal(type([])) leaders.should.equal([]) def test_ranked_in_list_with_sort_by(self): self.__rank_members_in_leaderboard(26) leaders = self.leaderboard.ranked_in_list(["member_25", "member_1", "member_15"], sort_by="score") len(leaders).should.equal(3) leaders[0]["member"].should.equal("member_1") leaders[1]["member"].should.equal("member_15") leaders[2]["member"].should.equal("member_25") leaders = self.leaderboard.ranked_in_list(["member_25", "member_1", "member_15"], sort_by="rank") len(leaders).should.be(3) leaders[0]["member"].should.equal("member_25") leaders[1]["member"].should.equal("member_15") leaders[2]["member"].should.equal("member_1") def test_ranked_in_list(self): self.__rank_members_in_leaderboard(27) leaders = self.leaderboard.ranked_in_list(["member_1", "member_15", "member_25"]) len(leaders).should.be(3) leaders[0]["member"].should.equal("member_1") leaders[1]["member"].should.equal("member_15") leaders[2]["member"].should.equal("member_25") def test_ranked_in_list_with_unknown_member(self): self.__rank_members_in_leaderboard(27) leaders = self.leaderboard.ranked_in_list(["jones"]) len(leaders).should.be(1) leaders[0]["member"].should.equal("jones") leaders[0]["score"].should.be(None) leaders[0]["rank"].should.be(None) def test_all_leaders(self): self.__rank_members_in_leaderboard(26) leaders = self.leaderboard.all_leaders() len(leaders).should.be(25) leaders[0]["member"].should.equal("member_25") def test_members_from_score_range(self): self.__rank_members_in_leaderboard(26) members = self.leaderboard.members_from_score_range(10, 15) member_15 = {"member": "member_15", "score": 15.0, "rank": 11} members[0].should.eql(member_15) member_10 = {"member": "member_10", "score": 10.0, "rank": 16} members[5].should.eql(member_10) def test_members_from_rank_range(self): self.__rank_members_in_leaderboard(26) members = self.leaderboard.members_from_rank_range(5, 9) len(members).should.be(5) members[0]["member"].should.eql("member_21") members[0]["score"].should.equal(21.0) members[4]["member"].should.eql("member_17") members = self.leaderboard.members_from_rank_range(1, 1) len(members).should.equal(1) members[0]["member"].should.eql("member_25") members = self.leaderboard.members_from_rank_range(1, 26) len(members).should.equal(25) members[0]["member"].should.eql("member_25") members[0]["score"].should.equal(25) members[24]["member"].should.eql("member_1") def test_member_at(self): self.__rank_members_in_leaderboard(51) self.leaderboard.member_at(1)["rank"].should.equal(1) self.leaderboard.member_at(1)["score"].should.equal(50.0) self.leaderboard.member_at(26)["rank"].should.equal(26) self.leaderboard.member_at(50)["rank"].should.equal(50) self.leaderboard.member_at(51).should.equal(None) self.leaderboard.member_at(1, with_member_data=True)["member_data"].should.eql( str({"member_name": "Leaderboard member 50"}) ) def test_around_me(self): self.__rank_members_in_leaderboard(Leaderboard.DEFAULT_PAGE_SIZE * 3 + 2) self.leaderboard.total_members().should.be(Leaderboard.DEFAULT_PAGE_SIZE * 3 + 1) leaders_around_me = self.leaderboard.around_me("member_30") (len(leaders_around_me) / 2).should.equal(self.leaderboard.page_size / 2) leaders_around_me = self.leaderboard.around_me("member_1") len(leaders_around_me).should.equal(self.leaderboard.page_size / 2 + 1) leaders_around_me = self.leaderboard.around_me("member_76") (len(leaders_around_me) / 2).should.equal(self.leaderboard.page_size / 2) def test_members_only(self): exp = [{"member": "member_%d" % x} for x in reversed(range(1, 27))] self.__rank_members_in_leaderboard(27) leaders = self.leaderboard.leaders(1, members_only=True) leaders.should.equal(exp[0:25]) leaders = self.leaderboard.leaders(2, members_only=True) leaders.should.equal(exp[25:26]) members = self.leaderboard.all_leaders(members_only=True) members.should.equal(exp) members = self.leaderboard.members_from_score_range(10, 15, members_only=True) members.should.equal(exp[11:17]) members = self.leaderboard.members_from_rank_range(5, 9, members_only=True) members.should.equal(exp[4:9]) leaders_around_me = self.leaderboard.around_me("member_25", page_size=3, members_only=True) leaders_around_me.should.equal(exp[0:3]) def test_merge_leaderboards(self): foo_leaderboard = Leaderboard("foo") bar_leaderboard = Leaderboard("bar") foo_leaderboard.rank_member("foo_1", 1) foo_leaderboard.rank_member("foo_2", 2) bar_leaderboard.rank_member("bar_1", 1) bar_leaderboard.rank_member("bar_2", 2) bar_leaderboard.rank_member("bar_3", 5) foo_leaderboard.merge_leaderboards("foobar", ["bar"], aggregate="SUM") foobar_leaderboard = Leaderboard("foobar") foobar_leaderboard.total_members().should.equal(5) foobar_leaderboard.leaders(1)[0]["member"].should.equal("bar_3") def test_intersect_leaderboards(self): foo_leaderboard = Leaderboard("foo") bar_leaderboard = Leaderboard("bar") foo_leaderboard.rank_member("foo_1", 1) foo_leaderboard.rank_member("foo_2", 2) foo_leaderboard.rank_member("bar_3", 6) bar_leaderboard.rank_member("bar_1", 3) bar_leaderboard.rank_member("foo_1", 4) bar_leaderboard.rank_member("bar_3", 5) foo_leaderboard.intersect_leaderboards("foobar", ["bar"], aggregate="SUM") foobar_leaderboard = Leaderboard("foobar") foobar_leaderboard.total_members().should.equal(2) foobar_leaderboard.leaders(1)[0]["member"].should.equal("bar_3") def test_rank_member_if(self): def highscore_check(self, member, current_score, score, member_data, leaderboard_options): if current_score is None: return True if score > current_score: return True return False self.leaderboard.total_members().should.equal(0) self.leaderboard.rank_member_if(highscore_check, "david", 1337) self.leaderboard.total_members().should.equal(1) self.leaderboard.score_for("david").should.equal(1337.0) self.leaderboard.rank_member_if(highscore_check, "david", 1336) self.leaderboard.score_for("david").should.equal(1337.0) self.leaderboard.rank_member_if(highscore_check, "david", 1338) self.leaderboard.score_for("david").should.equal(1338.0) def test_rank_members(self): self.leaderboard.total_members().should.equal(0) self.leaderboard.rank_members(["member_1", 1000, "member_2", 3000]) self.leaderboard.total_members().should.equal(2) def test_rank_member_across(self): self.leaderboard.rank_member_across(["highscores", "more_highscores"], "david", 50000, {"member_name": "david"}) len(self.leaderboard.leaders_in("highscores", 1)).should.equal(1) len(self.leaderboard.leaders_in("more_highscores", 1)).should.equal(1) def test_custom_keys_for_member_score_rank_and_member_data(self): Leaderboard.MEMBER_KEY = "member_custom" Leaderboard.SCORE_KEY = "score_custom" Leaderboard.RANK_KEY = "rank_custom" Leaderboard.MEMBER_DATA_KEY = "member_data_custom" self.__rank_members_in_leaderboard(26) leaders = self.leaderboard.leaders(1, with_member_data=True) len(leaders).should.equal(25) leaders[0]["member_custom"].should.equal("member_25") leaders[0]["score_custom"].should.equal(25) leaders[0]["rank_custom"].should.equal(1) leaders[0]["member_data_custom"].should.equal("{'member_name': 'Leaderboard member 25'}") def test_can_use_StrictRedis_class_for_connection(self): lb = Leaderboard("lb1", connection=StrictRedis(db=0)) lb.rank_member("david", 50.1) lb.score_for("david").should.equal(50.1) lb.rank_for("david").should.equal(1) len(lb.leaders(1)).should.equal(1) def test_can_set_member_data_namespace_option(self): self.leaderboard = Leaderboard("name", member_data_namespace="md") self.__rank_members_in_leaderboard() self.leaderboard.redis_connection.exists("name:member_data").should.be.false self.leaderboard.redis_connection.exists("name:md").should.be.true def __rank_members_in_leaderboard(self, members_to_add=6): for index in range(1, members_to_add): self.leaderboard.rank_member("member_%s" % index, index, {"member_name": "Leaderboard member %s" % index})
def test_intersect_leaderboards(self): foo_leaderboard = Leaderboard('foo') bar_leaderboard = Leaderboard('bar') foo_leaderboard.rank_member('foo_1', 1) foo_leaderboard.rank_member('foo_2', 2) foo_leaderboard.rank_member('bar_3', 6) bar_leaderboard.rank_member('bar_1', 3) bar_leaderboard.rank_member('foo_1', 4) bar_leaderboard.rank_member('bar_3', 5) foo_leaderboard.intersect_leaderboards( 'foobar', ['bar'], aggregate='SUM') foobar_leaderboard = Leaderboard('foobar') foobar_leaderboard.total_members().should.equal(2) foobar_leaderboard.leaders(1)[0]['member'].should.equal('bar_3')
from leaderboard_app.models import Player from itertools import islice from faker import Faker import random from leaderboard.leaderboard import Leaderboard from leaderboard_app.utils import * import json highscore_leaderboard = Leaderboard("highscore") fake = Faker() country_codes = ['TR', 'US', 'FR', 'ES', 'IT'] def bulk_create(size): batch_size = 200 objs = (Player(display_name=fake.name(), country_iso_code=random.choice(country_codes), points=i) for i in range(int(size))) while True: batch = list(islice(objs, batch_size)) if not batch: break Player.objects.bulk_create(batch, batch_size) def iterative_create(size): objs = (Player(display_name=fake.name(), country_iso_code=random.choice(country_codes), points=i) for i in range(int(size)))
def test_merge_leaderboards(self): foo_leaderboard = Leaderboard("foo") bar_leaderboard = Leaderboard("bar") foo_leaderboard.rank_member("foo_1", 1) foo_leaderboard.rank_member("foo_2", 2) bar_leaderboard.rank_member("bar_1", 1) bar_leaderboard.rank_member("bar_2", 2) bar_leaderboard.rank_member("bar_3", 5) foo_leaderboard.merge_leaderboards("foobar", ["bar"], aggregate="SUM") foobar_leaderboard = Leaderboard("foobar") foobar_leaderboard.total_members().should.equal(5) foobar_leaderboard.leaders(1)[0]["member"].should.equal("bar_3")
def get(self, request, *args, **kwargs): highscores = Leaderboard('highscores') return Response({"total_pages": highscores.total_pages()})
def test_init_sets_page_size_to_default_if_set_to_invalid_value(self): self.leaderboard = Leaderboard('name', page_size=0) self.leaderboard.page_size.should.equal(Leaderboard.DEFAULT_PAGE_SIZE)
def setUp(self): self.leaderboard = Leaderboard('name', decode_responses=True)
class LeaderboardTest(unittest.TestCase): def setUp(self): self.leaderboard = Leaderboard('name', decode_responses=True) def tearDown(self): self.leaderboard.redis_connection.flushdb() Leaderboard.MEMBER_KEY = 'member' Leaderboard.SCORE_KEY = 'score' Leaderboard.RANK_KEY = 'rank' Leaderboard.MEMBER_DATA_KEY = 'member_data' def test_version(self): Leaderboard.VERSION.should.equal('3.7.3') def test_init_with_defaults(self): 'name'.should.equal(self.leaderboard.leaderboard_name) len(self.leaderboard.options).should.be(2) self.leaderboard.options['connection_pool'].should.be.a(ConnectionPool) self.leaderboard.redis_connection.should.be.a(Redis) self.leaderboard.DEFAULT_PAGE_SIZE.should.equal( self.leaderboard.page_size) def test_init_sets_page_size_to_default_if_set_to_invalid_value(self): self.leaderboard = Leaderboard('name', page_size=0) self.leaderboard.page_size.should.equal(Leaderboard.DEFAULT_PAGE_SIZE) def test_init_uses_connection_pooling(self): lb0 = Leaderboard('lb0', db=0) lb1 = Leaderboard('lb1', db=0) lb2 = Leaderboard('lb2', db=1) lb0.redis_connection.connection_pool.should.equal( lb1.redis_connection.connection_pool) lb0.redis_connection.connection_pool.should_not.equal( lb2.redis_connection.connection_pool) def test_init_uses_connection(self): lb = Leaderboard('lb0', connection=Redis(db=1)) lb.redis_connection.connection_pool.connection_kwargs[ 'db'].should.equal(1) lb = Leaderboard('lb1', connection=StrictRedis(db=1)) lb.redis_connection.connection_pool.connection_kwargs[ 'db'].should.equal(1) def test_delete_leaderboard(self): self.__rank_members_in_leaderboard() self.leaderboard.redis_connection.exists('name').should.be.true self.leaderboard.delete_leaderboard() self.leaderboard.redis_connection.exists('name').should.be.false def test_member_data_for(self): self.__rank_members_in_leaderboard() self.leaderboard.member_data_for('member_1').should.eql( str({'member_name': 'Leaderboard member 1'})) def test_members_data_for(self): self.__rank_members_in_leaderboard() members_data = self.leaderboard.members_data_for(['member_1', 'member_3']) members_data[0].should.eql(str({'member_name': 'Leaderboard member 1'})) members_data[1].should.eql(str({'member_name': 'Leaderboard member 3'})) def test_update_member_data(self): self.__rank_members_in_leaderboard() self.leaderboard.update_member_data( 'member_1', { 'member_name': 'Updated Leaderboard member 1'}) self.leaderboard.member_data_for('member_1').should.eql( str({'member_name': 'Updated Leaderboard member 1'})) def test_remove_member_data(self): self.__rank_members_in_leaderboard() self.leaderboard.remove_member_data('member_1') self.leaderboard.member_data_for('member_1').should.be(None) def test_total_members(self): self.__rank_members_in_leaderboard() self.leaderboard.total_members().should.equal(5) def test_remove_member(self): self.__rank_members_in_leaderboard() self.leaderboard.total_members().should.equal(5) self.leaderboard.remove_member('member_1') self.leaderboard.total_members().should.equal(4) def test_remove_member_also_removes_member_data(self): self.__rank_members_in_leaderboard() self.leaderboard.redis_connection.exists( "name:member_data").should.be.true len(self.leaderboard.redis_connection.hgetall( "name:member_data")).should.equal(5) self.leaderboard.total_members().should.equal(5) self.leaderboard.remove_member('member_1') self.leaderboard.redis_connection.exists( "name:member_data").should.be.true len(self.leaderboard.redis_connection.hgetall( "name:member_data")).should.equal(4) self.leaderboard.total_members().should.equal(4) def test_total_pages(self): self.__rank_members_in_leaderboard(27) self.leaderboard.total_members().should.equal(26) self.leaderboard.total_pages().should.equal(2) def test_total_members_in_score_range(self): self.__rank_members_in_leaderboard() self.leaderboard.total_members_in_score_range(2, 4).should.equal(3) def test_score_for(self): self.__rank_members_in_leaderboard() self.leaderboard.score_for('member_5').should.equal(5.0) self.leaderboard.score_for('jones').should.be(None) def test_check_member(self): self.__rank_members_in_leaderboard() self.leaderboard.check_member('member_3').should.be.true self.leaderboard.check_member('member_6').should.be.false def test_rank_for(self): self.__rank_members_in_leaderboard() self.leaderboard.rank_for('member_5').should.equal(1) def test_change_score_for(self): self.__rank_members_in_leaderboard() self.leaderboard.change_score_for('member_1', 99) self.leaderboard.rank_for('member_1').should.equal(1) self.leaderboard.score_for('member_1').should.equal(100.0) def test_change_score_for_and_member_data_for_a_member(self): self.leaderboard.change_score_for('member_1', 5, 'optional-data') self.leaderboard.score_for('member_1').should.equal(5.0) self.leaderboard.member_data_for('member_1').should.equal('optional-data') def test_score_and_rank_for(self): self.__rank_members_in_leaderboard() score_and_rank = self.leaderboard.score_and_rank_for('member_3') score_and_rank['member'].should.equal('member_3') score_and_rank['score'].should.equal(3.0) score_and_rank['rank'].should.equal(3) score_and_rank = self.leaderboard.score_and_rank_for('jones') score_and_rank['member'].should.equal('jones') score_and_rank['score'].should.be(None) score_and_rank['rank'].should.be(None) def test_remove_members_in_score_range(self): self.__rank_members_in_leaderboard() self.leaderboard.total_members().should.equal(5) self.leaderboard.remove_members_in_score_range(2, 4) self.leaderboard.total_members().should.equal(2) def test_remove_members_outside_rank(self): self.__rank_members_in_leaderboard() self.leaderboard.total_members().should.equal(5) self.leaderboard.remove_members_outside_rank(3).should.equal(2) leaders = self.leaderboard.leaders(1) len(leaders).should.equal(3) leaders[0]['member'].should.equal('member_5') leaders[2]['member'].should.equal('member_3') self.leaderboard.order = Leaderboard.ASC self.__rank_members_in_leaderboard() self.leaderboard.total_members().should.equal(5) self.leaderboard.remove_members_outside_rank(3).should.equal(2) leaders = self.leaderboard.leaders(1) len(leaders).should.equal(3) leaders[0]['member'].should.equal('member_1') leaders[2]['member'].should.equal('member_3') def test_page_for(self): self.leaderboard.page_for('jones').should.equal(0) self.__rank_members_in_leaderboard(21) self.leaderboard.page_for('member_17').should.equal(1) self.leaderboard.page_for('member_11').should.equal(1) self.leaderboard.page_for('member_10').should.equal(1) self.leaderboard.page_for('member_1').should.equal(1) self.leaderboard.page_for('member_17', 10).should.equal(1) self.leaderboard.page_for('member_11', 10).should.equal(1) self.leaderboard.page_for('member_10', 10).should.equal(2) self.leaderboard.page_for('member_1', 10).should.equal(2) def test_page_for_with_sort_option_ASC(self): self.leaderboard.order = Leaderboard.ASC self.leaderboard.page_for('jones').should.equal(0) self.__rank_members_in_leaderboard(21) self.leaderboard.page_for('member_10', 10).should.equal(1) self.leaderboard.page_for('member_1', 10).should.equal(1) self.leaderboard.page_for('member_17', 10).should.equal(2) self.leaderboard.page_for('member_11', 10).should.equal(2) def test_percentile_for(self): self.__rank_members_in_leaderboard(13) self.leaderboard.percentile_for('member_1').should.eql(0.0) self.leaderboard.percentile_for('member_2').should.eql(9.0) self.leaderboard.percentile_for('member_3').should.eql(17.0) self.leaderboard.percentile_for('member_4').should.eql(25.0) self.leaderboard.percentile_for('member_12').should.eql(92.0) def test_score_for_percentile(self): self.__rank_members_in_leaderboard(6) self.leaderboard.score_for_percentile(0).should.eql(1.0) self.leaderboard.score_for_percentile(75).should.eql(4.0) self.leaderboard.score_for_percentile(87.5).should.eql(4.5) self.leaderboard.score_for_percentile(93.75).should.eql(4.75) self.leaderboard.score_for_percentile(100).should.eql(5.0) def test_score_for_percentile_with_sort_option_ASC(self): self.leaderboard.order = Leaderboard.ASC self.__rank_members_in_leaderboard(6) self.leaderboard.score_for_percentile(0).should.eql(5.0) self.leaderboard.score_for_percentile(75).should.eql(2.0) self.leaderboard.score_for_percentile(87.5).should.eql(1.5) self.leaderboard.score_for_percentile(93.75).should.eql(1.25) self.leaderboard.score_for_percentile(100).should.eql(1.0) def test_expire_leaderboard(self): self.__rank_members_in_leaderboard() self.leaderboard.expire_leaderboard(3) ttl = self.leaderboard.redis_connection.ttl( self.leaderboard.leaderboard_name) ttl.should.be.greater_than(1) ttl = self.leaderboard.redis_connection.ttl( '%s:member_data' % self.leaderboard.leaderboard_name) ttl.should.be.greater_than(1) def test_expire_leaderboard_at(self): self.__rank_members_in_leaderboard() self.leaderboard.expire_leaderboard_at(int(time.time() + 10)) ttl = self.leaderboard.redis_connection.ttl( self.leaderboard.leaderboard_name) ttl.should.be.lower_than(11) ttl = self.leaderboard.redis_connection.ttl( '%s:member_data' % self.leaderboard.leaderboard_name) ttl.should.be.lower_than(11) def test_leaders(self): self.__rank_members_in_leaderboard(27) leaders = self.leaderboard.leaders(1) len(leaders).should.equal(25) leaders[0]['member'].should.equal('member_26') leaders[0]['rank'].should.equal(1) leaders[24]['member'].should.equal('member_2') leaders = self.leaderboard.leaders(2) len(leaders).should.equal(1) leaders[0]['member'].should.equal('member_1') leaders[0]['rank'].should.equal(26) leaders = self.leaderboard.leaders(1, page_size=5) len(leaders).should.equal(5) def test_leaders_with_optional_member_data(self): self.__rank_members_in_leaderboard() leaders = self.leaderboard.leaders(1, with_member_data=True) len(leaders).should.equal(5) leaders[0]['member'].should.equal('member_5') leaders[0]['member_data'].should.equal( str({'member_name': 'Leaderboard member 5'})) def test_leaders_return_type(self): leaders = self.leaderboard.leaders(1) type(leaders).should.equal(type([])) leaders.should.equal([]) def test_ranked_in_list_with_sort_by(self): self.__rank_members_in_leaderboard(26) leaders = self.leaderboard.ranked_in_list( ['member_25', 'member_1', 'member_15'], sort_by='score') len(leaders).should.equal(3) leaders[0]['member'].should.equal('member_1') leaders[1]['member'].should.equal('member_15') leaders[2]['member'].should.equal('member_25') leaders = self.leaderboard.ranked_in_list( ['member_25', 'member_1', 'member_15'], sort_by='rank') len(leaders).should.be(3) leaders[0]['member'].should.equal('member_25') leaders[1]['member'].should.equal('member_15') leaders[2]['member'].should.equal('member_1') def test_ranked_in_list(self): self.__rank_members_in_leaderboard(27) leaders = self.leaderboard.ranked_in_list( ['member_1', 'member_15', 'member_25']) len(leaders).should.be(3) leaders[0]['member'].should.equal('member_1') leaders[1]['member'].should.equal('member_15') leaders[2]['member'].should.equal('member_25') leaders = self.leaderboard.ranked_in_list( ['member_200'], include_missing=False, with_member_data=True) len(leaders).should.be(0) def test_ranked_in_list_with_unknown_member(self): self.__rank_members_in_leaderboard(27) leaders = self.leaderboard.ranked_in_list(['jones']) len(leaders).should.be(1) leaders[0]['member'].should.equal('jones') leaders[0]['score'].should.be(None) leaders[0]['rank'].should.be(None) def test_all_leaders(self): self.__rank_members_in_leaderboard(26) leaders = self.leaderboard.all_leaders() len(leaders).should.be(25) leaders[0]['member'].should.equal('member_25') def test_members_from_score_range(self): self.__rank_members_in_leaderboard(26) members = self.leaderboard.members_from_score_range(10, 15) member_15 = { 'member': 'member_15', 'score': 15.0, 'rank': 11 } members[0].should.eql(member_15) member_10 = { 'member': 'member_10', 'score': 10.0, 'rank': 16 } members[5].should.eql(member_10) def test_members_from_rank_range(self): self.__rank_members_in_leaderboard(26) members = self.leaderboard.members_from_rank_range(5, 9) len(members).should.be(5) members[0]['member'].should.eql('member_21') members[0]['score'].should.equal(21.0) members[4]['member'].should.eql('member_17') members = self.leaderboard.members_from_rank_range(1, 1) len(members).should.equal(1) members[0]['member'].should.eql('member_25') members = self.leaderboard.members_from_rank_range(1, 26) len(members).should.equal(25) members[0]['member'].should.eql('member_25') members[0]['score'].should.equal(25.0) members[24]['member'].should.eql('member_1') def test_member_at(self): self.__rank_members_in_leaderboard(51) self.leaderboard.member_at(1)['rank'].should.equal(1) self.leaderboard.member_at(1)['score'].should.equal(50.0) self.leaderboard.member_at(26)['rank'].should.equal(26) self.leaderboard.member_at(50)['rank'].should.equal(50) self.leaderboard.member_at(51).should.equal(None) self.leaderboard.member_at(1, with_member_data=True)['member_data'].should.eql( str({'member_name': 'Leaderboard member 50'})) self.leaderboard.member_at(-5).should.equal(None) def test_around_me(self): self.__rank_members_in_leaderboard( Leaderboard.DEFAULT_PAGE_SIZE * 3 + 2) self.leaderboard.total_members().should.be( Leaderboard.DEFAULT_PAGE_SIZE * 3 + 1) leaders_around_me = self.leaderboard.around_me('member_30') (len(leaders_around_me) // 2).should.equal(self.leaderboard.page_size // 2) leaders_around_me = self.leaderboard.around_me('member_1') len(leaders_around_me).should.equal(self.leaderboard.page_size // 2 + 1) leaders_around_me = self.leaderboard.around_me('member_76') (len(leaders_around_me) // 2).should.equal(self.leaderboard.page_size // 2) leaders_around_me = self.leaderboard.around_me('member_76', page_size=1) (len(leaders_around_me) // 2).should.equal(0) def test_members_only(self): exp = [{'member': 'member_%d' % x} for x in reversed(range(1, 27))] self.__rank_members_in_leaderboard(27) leaders = self.leaderboard.leaders(1, members_only=True) leaders.should.equal(exp[0:25]) leaders = self.leaderboard.leaders(2, members_only=True) leaders.should.equal(exp[25:26]) members = self.leaderboard.all_leaders(members_only=True) members.should.equal(exp) members = self.leaderboard.members_from_score_range( 10, 15, members_only=True) members.should.equal(exp[11:17]) members = self.leaderboard.members_from_rank_range( 5, 9, members_only=True) members.should.equal(exp[4:9]) leaders_around_me = self.leaderboard.around_me( 'member_25', page_size=3, members_only=True) leaders_around_me.should.equal(exp[0:3]) def test_merge_leaderboards(self): foo_leaderboard = Leaderboard('foo') bar_leaderboard = Leaderboard('bar') foo_leaderboard.rank_member('foo_1', 1) foo_leaderboard.rank_member('foo_2', 2) bar_leaderboard.rank_member('bar_1', 1) bar_leaderboard.rank_member('bar_2', 2) bar_leaderboard.rank_member('bar_3', 5) foo_leaderboard.merge_leaderboards('foobar', ['bar'], aggregate='SUM') foobar_leaderboard = Leaderboard('foobar') foobar_leaderboard.total_members().should.equal(5) foobar_leaderboard.leaders(1)[0]['member'].should.equal('bar_3') def test_intersect_leaderboards(self): foo_leaderboard = Leaderboard('foo') bar_leaderboard = Leaderboard('bar') foo_leaderboard.rank_member('foo_1', 1) foo_leaderboard.rank_member('foo_2', 2) foo_leaderboard.rank_member('bar_3', 6) bar_leaderboard.rank_member('bar_1', 3) bar_leaderboard.rank_member('foo_1', 4) bar_leaderboard.rank_member('bar_3', 5) foo_leaderboard.intersect_leaderboards( 'foobar', ['bar'], aggregate='SUM') foobar_leaderboard = Leaderboard('foobar') foobar_leaderboard.total_members().should.equal(2) foobar_leaderboard.leaders(1)[0]['member'].should.equal('bar_3') def test_rank_member_if(self): def highscore_check( self, member, current_score, score, member_data, leaderboard_options): if (current_score is None): return True if (score > current_score): return True return False self.leaderboard.total_members().should.equal(0) self.leaderboard.rank_member_if(highscore_check, 'david', 1337) self.leaderboard.total_members().should.equal(1) self.leaderboard.score_for('david').should.equal(1337.0) self.leaderboard.rank_member_if(highscore_check, 'david', 1336) self.leaderboard.score_for('david').should.equal(1337.0) self.leaderboard.rank_member_if(highscore_check, 'david', 1338) self.leaderboard.score_for('david').should.equal(1338.0) def test_rank_members(self): self.leaderboard.total_members().should.equal(0) self.leaderboard.rank_members(['member_1', 1000, 'member_2', 3000]) self.leaderboard.total_members().should.equal(2) def test_rank_member_across(self): self.leaderboard.rank_member_across( ['highscores', 'more_highscores'], 'david', 50000, {'member_name': 'david'}) len(self.leaderboard.leaders_in('highscores', 1)).should.equal(1) len(self.leaderboard.leaders_in('more_highscores', 1)).should.equal(1) def test_custom_keys_for_member_score_rank_and_member_data(self): Leaderboard.MEMBER_KEY = 'member_custom' Leaderboard.SCORE_KEY = 'score_custom' Leaderboard.RANK_KEY = 'rank_custom' Leaderboard.MEMBER_DATA_KEY = 'member_data_custom' self.__rank_members_in_leaderboard(26) leaders = self.leaderboard.leaders(1, with_member_data=True) len(leaders).should.equal(25) leaders[0]['member_custom'].should.equal('member_25') leaders[0]['score_custom'].should.equal(25.0) leaders[0]['rank_custom'].should.equal(1) leaders[0]['member_data_custom'].should.equal( "{'member_name': 'Leaderboard member 25'}") def test_can_use_StrictRedis_class_for_connection(self): lb = Leaderboard('lb1', connection=StrictRedis(db=0)) lb.rank_member('david', 50.1) lb.score_for('david').should.equal(50.1) lb.rank_for('david').should.equal(1) len(lb.leaders(1)).should.equal(1) def test_can_set_member_data_namespace_option(self): self.leaderboard = Leaderboard('name', member_data_namespace='md') self.__rank_members_in_leaderboard() self.leaderboard.redis_connection.exists( "name:member_data").should.be.false self.leaderboard.redis_connection.exists("name:md").should.be.true def test_global_member_data_option(self): self.leaderboard = Leaderboard('name', global_member_data=True) self.__rank_members_in_leaderboard() self.leaderboard.redis_connection.exists( "name:member_data").should.be.false self.leaderboard.redis_connection.exists( "member_data").should.be.true def test_retrieve_a_given_set_of_members_from_the_leaderboard_in_a_range_from_1_to_the_number_given(self): self.__rank_members_in_leaderboard(26) members = self.leaderboard.top(5) len(members).should.equal(5) members[0]['member'].should.equal('member_25') members[0]['score'].should.equal(25.0) members[4]['member'].should.equal('member_21') members = self.leaderboard.top(1) len(members).should.equal(1) members[0]['member'].should.equal('member_25') members = self.leaderboard.top(26) len(members).should.equal(25) members[0]['member'].should.equal('member_25') members[0]['score'].should.equal(25.0) members[24]['member'].should.equal('member_1') def test_retrieve_a_given_set_of_members_from_the_named_leaderboard_in_a_range_from_1_to_the_number_given(self): self.__rank_members_in_leaderboard(26) members = self.leaderboard.top_in('name', 5) len(members).should.equal(5) members[0]['member'].should.equal('member_25') members[0]['score'].should.equal(25.0) members[4]['member'].should.equal('member_21') members = self.leaderboard.top_in('name', 1) len(members).should.equal(1) members[0]['member'].should.equal('member_25') members = self.leaderboard.top_in('name', 26) len(members).should.equal(25) members[0]['member'].should.equal('member_25') members[0]['score'].should.equal(25.0) members[24]['member'].should.equal('member_1') def test_retrieve_a_given_set_of_members_from_the_leaderboard_in_a_range_from_1_to_the_number_given_with_sort_option_ASC(self): self.leaderboard.order = Leaderboard.ASC self.__rank_members_in_leaderboard(26) members = self.leaderboard.top(5) len(members).should.equal(5) members[0]['member'].should.equal('member_1') members[0]['score'].should.equal(1.0) members[4]['member'].should.equal('member_5') members = self.leaderboard.top(1) len(members).should.equal(1) members[0]['member'].should.equal('member_1') members = self.leaderboard.top(26) len(members).should.equal(25) members[0]['member'].should.equal('member_1') members[0]['score'].should.equal(1.0) members[24]['member'].should.equal('member_25') def test_retrieve_a_given_set_of_members_from_the_named_leaderboard_in_a_range_from_1_to_the_number_given_with_sort_option_ASC(self): self.leaderboard.order = Leaderboard.ASC self.__rank_members_in_leaderboard(26) members = self.leaderboard.top_in('name', 5) len(members).should.equal(5) members[0]['member'].should.equal('member_1') members[0]['score'].should.equal(1.0) members[4]['member'].should.equal('member_5') members = self.leaderboard.top_in('name', 1) len(members).should.equal(1) members[0]['member'].should.equal('member_1') members = self.leaderboard.top_in('name', 26) len(members).should.equal(25) members[0]['member'].should.equal('member_1') members[0]['score'].should.equal(1.0) members[24]['member'].should.equal('member_25') def test_allow_you_to_include_or_exclude_missing_members_using_the_include_missing_option(self): self.__rank_members_in_leaderboard(26) leaders = self.leaderboard.ranked_in_list( ['member_1', 'member_15', 'member_25', 'member_200']) len(leaders).should.equal(4) leaders[0]['member'].should.equal('member_1') leaders[1]['member'].should.equal('member_15') leaders[2]['member'].should.equal('member_25') leaders[3]['member'].should.equal('member_200') leaders = self.leaderboard.ranked_in_list( ['member_1', 'member_15', 'member_25', 'member_200'], include_missing=False) len(leaders).should.equal(3) leaders[0]['member'].should.equal('member_1') leaders[1]['member'].should.equal('member_15') leaders[2]['member'].should.equal('member_25') def test_total_scores_in(self): self.__rank_members_in_leaderboard(26) self.leaderboard.total_scores().should.equal(325.0) def test_ranked_in_list_with_include_missing_sort_by_rank_and_missing_members(self): self.__rank_members_in_leaderboard(27) leaders = self.leaderboard.ranked_in_list( ['member_1', 'member_81', 'member_25'], sort_by='rank') len(leaders).should.equal(3) leaders[0]['member'].should.equal('member_25') leaders[1]['member'].should.equal('member_1') leaders[2]['member'].should.equal('member_81') self.leaderboard.order = Leaderboard.ASC leaders = self.leaderboard.ranked_in_list( ['member_1', 'member_81', 'member_25'], sort_by='rank') len(leaders).should.equal(3) leaders[0]['member'].should.equal('member_81') leaders[1]['member'].should.equal('member_1') leaders[2]['member'].should.equal('member_25') def test_ranked_in_list_with_include_missing_sort_by_score_and_missing_members(self): self.__rank_members_in_leaderboard(27) leaders = self.leaderboard.ranked_in_list( ['member_1', 'member_81', 'member_25'], sort_by='score') len(leaders).should.equal(3) leaders[0]['member'].should.equal('member_1') leaders[1]['member'].should.equal('member_25') leaders[2]['member'].should.equal('member_81') self.leaderboard.order = Leaderboard.ASC leaders = self.leaderboard.ranked_in_list( ['member_1', 'member_81', 'member_25'], sort_by='rank') len(leaders).should.equal(3) leaders[0]['member'].should.equal('member_81') leaders[1]['member'].should.equal('member_1') leaders[2]['member'].should.equal('member_25') def test_ranked_in_list_with_include_missing_sort_by_score_and_negative_and_zero_score(self): self.__rank_members_in_leaderboard() self.leaderboard.rank_member('member_-1', -1) self.leaderboard.rank_member('member_0', 0) leaders = self.leaderboard.ranked_in_list( ['member_-1', 'member_0', 'member_1', 'member_3', 'member_200'], sort_by='score') len(leaders).should.equal(5) leaders[0]['member'].should.equal('member_-1') leaders[1]['member'].should.equal('member_0') leaders[2]['member'].should.equal('member_1') leaders[3]['member'].should.equal('member_3') leaders[4]['member'].should.equal('member_200') def __rank_members_in_leaderboard(self, members_to_add=6): for index in range(1, members_to_add): self.leaderboard.rank_member( 'member_%s' % index, index, { 'member_name': 'Leaderboard member %s' % index})
def test_merge_leaderboards(self): foo_leaderboard = Leaderboard('foo') bar_leaderboard = Leaderboard('bar') foo_leaderboard.rank_member('foo_1', 1) foo_leaderboard.rank_member('foo_2', 2) bar_leaderboard.rank_member('bar_1', 1) bar_leaderboard.rank_member('bar_2', 2) bar_leaderboard.rank_member('bar_3', 5) foo_leaderboard.merge_leaderboards('foobar', ['bar'], aggregate='SUM') foobar_leaderboard = Leaderboard('foobar') foobar_leaderboard.total_members().should.equal(5) foobar_leaderboard.leaders(1)[0]['member'].should.equal('bar_3')
def handle(self, *args, **options): global supported code = options['code'] if code == '-1': to_do = supported else: if code not in supported: raise Exception("Unrecognized code:%s" % code) to_do = [code] for game in to_do: print("\nProcessing game %s" % game_model_map[game].__name__) model = game_model_map[game] lb_score = Leaderboard('%s_sc' % (game, ), host=settings.LEADERBOARD_REDIS_HOST) lb_time = Leaderboard('%s_tm' % (game, ), host=settings.LEADERBOARD_REDIS_HOST) lb_score.delete_leaderboard() lb_time.delete_leaderboard() # iterate all users who has data us_count = User.objects.count() count = 1 for us in User.objects.all(): #print("Processing user %d of %d" % (count, us_count)) # find and set best score best = model.objects.filter(user=us, current_best=True) if best.count() > 0: best = best[0].stat_score lb_score.rank_member(leaderboard_key_for(us), best) # compute time and set time = model.objects.filter(user=us) if time.count() > 0: time_played = time.aggregate( Sum('stat_time_secs'))['stat_time_secs__sum'] lb_time.rank_member(leaderboard_key_for(us), time_played) count += 1
def update_match_result(request): if request.method == 'POST': data = request.POST user1ID = data.get('user1ID', default=None) user2ID = data.get('user2ID', default=None) roomID = data.get('roomID', default=None) user1Score = data.get('user1Score', default=None) user2Score = data.get('user2Score', default=None) scoreDiff = abs(int(user1Score) - int(user2Score)) if user1ID is None or user2ID is None: return Response('invalid userID', status=status.HTTP_400_BAD_REQUEST) userID = [user1ID, user2ID] winner = data.get('winner', default=None) turn = data.get('turn', default=None) u1diff = None u2diff = None if winner is None or turn is None: return Response('invalid userID', status=status.HTTP_400_BAD_REQUEST) if int(user2ID) == -2: user = User.objects.get(idUser=user1ID) if user.winCount != 0 or user.loseCount != 0: responseData = { 'user1': { 'userID': user.idUser, 'trophy_sum': user.trophiesCount, 'trophy_diff': 0 }, 'user2': { 'userID': -1, 'trophy_sum': 0, 'trophy_diff': 0 }, 'winner': int(winner), 'roomID': roomID } return JsonResponse(responseData, status=status.HTTP_200_OK) else: udiff = None if int(user1Score) > int(user2Score): user.winCount += 1 udiff = calculate_trophy(user.trophiesCount, user.level, True, int(turn), scoreDiff) user.trophiesCount += udiff else: user.loseCount += 1 udiff = calculate_trophy(user.trophiesCount, user.level, False, int(turn), scoreDiff) user.trophiesCount += udiff user.save() highscore_lb = Leaderboard('Bazuka_V1') highscore_lb.rank_member(user.username, user.trophiesCount, user.idUser) responseData = { 'user1': { 'userID': user.idUser, 'trophy_sum': user.trophiesCount, 'trophy_diff': udiff }, 'user2': { 'userID': -1, 'trophy_sum': 0, 'trophy_diff': 0 }, 'winner': int(winner), 'roomID': roomID } return JsonResponse(responseData, status=status.HTTP_200_OK) elif int(user2ID) == -1: user = User.objects.get(idUser=user1ID) udiff = None if int(user1Score) > int(user2Score): user.winCount += 1 udiff = calculate_trophy(user.trophiesCount, user.level, True, int(turn), scoreDiff) user.trophiesCount += udiff else: user.loseCount += 1 udiff = calculate_trophy(user.trophiesCount, user.level, False, int(turn), scoreDiff) user.trophiesCount += udiff user.save() highscore_lb = Leaderboard('Bazuka_V1') highscore_lb.rank_member(user.username, user.trophiesCount, user.idUser) responseData = { 'user1': { 'userID': user.idUser, 'trophy_sum': user.trophiesCount, 'trophy_diff': udiff }, 'user2': { 'userID': -1, 'trophy_sum': 0, 'trophy_diff': 0 }, 'winner': int(winner), 'roomID': roomID } return JsonResponse(responseData, status=status.HTTP_200_OK) else: user1 = User.objects.get(idUser=userID[int(winner)]) user2 = User.objects.get(idUser=userID[1 - int(winner)]) if int(user1Score) == -1 or int(user2Score) == -1: user1.winCount += 1 u1diff = 20 user1.trophiesCount += u1diff user2.loseCount += 1 u2diff = -10 if user2.trophiesCount < 10: u2diff = -user2.trophiesCount user2.trophiesCount += u2diff else: user1.winCount += 1 u1diff = calculate_trophy(user1.trophiesCount, user1.level, True, int(turn), scoreDiff) user1.trophiesCount += u1diff user2.loseCount += 1 u2diff = calculate_trophy(user2.trophiesCount, user2.level, False, int(turn), scoreDiff) user2.trophiesCount += u2diff user1.save() user2.save() highscore_lb = Leaderboard('Bazuka_V1') highscore_lb.rank_member(user1.username, user1.trophiesCount, user1.idUser) highscore_lb.rank_member(user2.username, user2.trophiesCount, user2.idUser) responseData = { 'user1': { 'userID': user1.idUser, 'trophy_sum': user1.trophiesCount, 'trophy_diff': u1diff }, 'user2': { 'userID': user2.idUser, 'trophy_sum': user2.trophiesCount, 'trophy_diff': u2diff }, 'winner': 0, 'roomID': roomID } return JsonResponse(responseData, status=status.HTTP_200_OK)
def test_intersect_leaderboards(self): foo_leaderboard = Leaderboard('foo') bar_leaderboard = Leaderboard('bar') foo_leaderboard.rank_member('foo_1', 1) foo_leaderboard.rank_member('foo_2', 2) foo_leaderboard.rank_member('bar_3', 6) bar_leaderboard.rank_member('bar_1', 3) bar_leaderboard.rank_member('foo_1', 4) bar_leaderboard.rank_member('bar_3', 5) foo_leaderboard.intersect_leaderboards('foobar', ['bar'], aggregate='SUM') foobar_leaderboard = Leaderboard('foobar') foobar_leaderboard.total_members().should.equal(2) foobar_leaderboard.leaders(1)[0]['member'].should.equal('bar_3')
def test_can_use_StrictRedis_class_for_connection(self): lb = Leaderboard('lb1', connection=StrictRedis(db=0)) lb.rank_member('david', 50.1) lb.score_for('david').should.equal(50.1) lb.rank_for('david').should.equal(1) len(lb.leaders(1)).should.equal(1)
def setUp(self): self.leaderboard = Leaderboard("name")
def reward_punish_users(match_id): match = Match.objects.get(id=match_id) today = datetime.today() highscores = Leaderboard('highscores') monthly_highscores = Leaderboard( str(today.month) + '-' + str(today.year) + '_highscores') score_total = match.home_team_score + match.away_team_score games = Game.objects.filter(match=match) odds = {} for game in games: odds[game.string] = game.odd winning_games = [] # MS1 MSX MS2 CS1-X CS2-X CS1-2 if match.home_team_score > match.away_team_score: winning_games.append('ms1') winning_games.append('cs1-x') winning_games.append('cs1-2') elif match.away_team_score > match.home_team_score: winning_games.append('ms2') winning_games.append('cs2-x') winning_games.append('cs1-2') else: winning_games.append('msx') winning_games.append('cs1-x') winning_games.append('cs2-x') # H1 HX H2 home_score = match.home_team_score away_score = match.away_team_score if match.handicap == "0": pass elif match.handicap.startswith("-"): away_score = away_score + int(match.handicap[-1]) if home_score > away_score: winning_games.append("h1") elif away_score > home_score: winning_games.append("h2") else: winning_games.append("hx") else: home_score = home_score + int(match.handicap) if home_score > away_score: winning_games.append("h1") elif away_score > home_score: winning_games.append("h2") else: winning_games.append("hx") # KGVAR KGYOK if match.home_team_score > 0 and match.away_team_score > 0: winning_games.append('kgvar') else: winning_games.append('kgyok') # TEK CIFT if score_total % 2 == 0: winning_games.append('tccift') else: winning_games.append('tctek') # TG 0-1 2-3 4-6 7+ if score_total < 2: winning_games.append('tg0-1') elif score_total < 4: winning_games.append('tg2-3') elif score_total < 7: winning_games.append('tg4-6') else: winning_games.append('tg7+') # 1.5 ALT UST if score_total < 2: winning_games.append('au1,5-alt') else: winning_games.append('au1,5-ust') # 2.5 ALT UST if score_total < 3: winning_games.append('au2,5-alt') else: winning_games.append('au2,5-ust') # 3.5 ALT UST if score_total < 4: winning_games.append('au3,5-alt') else: winning_games.append('au3,5-ust') # IY 1.5 ALT UST if (match.home_first_half_score + match.away_first_half_score) < 2: winning_games.append('iyau1,5-alt') else: winning_games.append('iyau1,5-ust') # IY1 IY0 IY2 if match.home_first_half_score > match.away_first_half_score: winning_games.append("iy1") elif match.home_first_half_score == match.away_first_half_score: winning_games.append("iy0") else: winning_games.append("iy2") # IY/MS if match.home_first_half_score > match.away_first_half_score: if match.home_team_score > match.away_team_score: winning_games.append("iyms1/1") elif match.home_team_score == match.away_team_score: winning_games.append("iyms1/x") else: winning_games.append("iyms1/2") elif match.home_first_half_score == match.away_first_half_score: if match.home_team_score > match.away_team_score: winning_games.append("iymsx/1") elif match.home_team_score == match.away_team_score: winning_games.append("iymsx/x") else: winning_games.append("iymsx/2") else: if match.home_team_score > match.away_team_score: winning_games.append("iyms2/1") elif match.home_team_score == match.away_team_score: winning_games.append("iyms2/x") else: winning_games.append("iyms2/2") # Rewarding and punishing users for game in GAMES_LIST: if game in winning_games: predictions = Prediction.objects.filter(game=game, match=match) for prediction in predictions: user = User.objects.get(id=prediction.user.id) user.skill_point = user.skill_point + odds[game] * 10.0 # Updating all time leaderboard highscores.rank_member(user.id, user.skill_point) # Updating monthly leaderboard monthly = MonthlyScore.objects.filter(month__month=today.month) if monthly.exists(): monthly = monthly.first() monthly.skill_point += odds[game] * 10.0 monthly.save() else: monthly = MonthlyScore.objects.create( user=user, skill_point=(odds[game] * 10.0), month=today) monthly_highscores.rank_member(user.id, monthly.skill_point) user.save() # Trophy progression successful_predictions = SuccessCount.objects.filter( user=user, league=match.league) if successful_predictions.exists(): successful_predictions = successful_predictions.first() successful_predictions.count += 1 successful_predictions.save() trophy_type = TrophyType.objects.filter( league=match.league, count=successful_predictions.count) if trophy_type.exists(): trophy_type = trophy_type.first() Trophy.objects.create( user=user, text=trophy_type.text, league=trophy_type.league, description=trophy_type.description, image=trophy_type.image) else: SuccessCount.objects.create(user=user, league=match.league, count=1) else: predictions = Prediction.objects.filter(game=game) for prediction in predictions: user = User.objects.get(id=prediction.user.id) user.skill_point = user.skill_point - odds[game] * 0.1 highscores.rank_member(user.id, user.skill_point) user.save() monthly = MonthlyScore.objects.filter(month__month=today.month) if monthly.exists(): monthly = monthly.first() monthly.skill_point += odds[game] * -0.1 monthly.save() else: monthly = MonthlyScore.objects.create( user=user, skill_point=(odds[game] * -0.1), month=today) monthly_highscores.rank_member(user.id, monthly.skill_point) return winning_games