diff --git a/leaderboard/__init__.py b/leaderboard/__init__.py index 39ae457..433c63b 100644 --- a/leaderboard/__init__.py +++ b/leaderboard/__init__.py @@ -533,10 +533,7 @@ def leaders_in(self, leaderboard_name, current_page, **options): ending_offset = (starting_offset + page_size) - 1 raw_leader_data = self._range_method(self.redis_connection, self.leaderboard_name, int(starting_offset), int(ending_offset), withscores = False) - if raw_leader_data: - return self.ranked_in_list_in(self.leaderboard_name, raw_leader_data, **options) - else: - return [] + return self._parse_raw_members(self.leaderboard_name, raw_leader_data, **options) def all_leaders(self, **options): ''' @@ -554,11 +551,7 @@ def all_leaders_from(self, leaderboard_name, **options): @return the named leaderboard. ''' raw_leader_data = self._range_method(self.redis_connection, leaderboard_name, 0, -1, withscores = False) - - if raw_leader_data: - return self.ranked_in_list_in(leaderboard_name, raw_leader_data, **options) - else: - return [] + return self._parse_raw_members(leaderboard_name, raw_leader_data, **options) def members_from_score_range(self, minimum_score, maximum_score, **options): ''' @@ -584,11 +577,7 @@ def members_from_score_range_in(self, leaderboard_name, minimum_score, maximum_s raw_leader_data = self.redis_connection.zrevrangebyscore(leaderboard_name, maximum_score, minimum_score) else: raw_leader_data = self.redis_connection.zrangebyscore(leaderboard_name, minimum_score, maximum_score) - - if raw_leader_data: - return self.ranked_in_list_in(leaderboard_name, raw_leader_data, **options) - else: - return [] + return self._parse_raw_members(leaderboard_name, raw_leader_data, **options) def members_from_rank_range(self, starting_rank, ending_rank, **options): ''' @@ -623,10 +612,7 @@ def members_from_rank_range_in(self, leaderboard_name, starting_rank, ending_ran else: raw_leader_data = self.redis_connection.zrange(leaderboard_name, starting_rank, ending_rank, withscores = False) - if raw_leader_data: - return self.ranked_in_list_in(leaderboard_name, raw_leader_data, **options) - else: - return [] + return self._parse_raw_members(leaderboard_name, raw_leader_data, **options) def member_at(self, position, **options): ''' @@ -689,11 +675,7 @@ def around_me_in(self, leaderboard_name, member, **options): ending_offset = (starting_offset + page_size) - 1 raw_leader_data = self._range_method(self.redis_connection, self.leaderboard_name, int(starting_offset), int(ending_offset), withscores = False) - - if raw_leader_data: - return self.ranked_in_list_in(leaderboard_name, raw_leader_data, **options) - else: - return [] + return self._parse_raw_members(leaderboard_name, raw_leader_data, **options) def ranked_in_list(self, members, **options): ''' @@ -784,3 +766,20 @@ def _member_data_key(self, leaderboard_name): @return a key in the form of +leaderboard_name:member_data+ ''' return '%s:member_data' % leaderboard_name + + def _parse_raw_members(self, leaderboard_name, members, members_only = False, **options): + ''' + Parse the raw leaders data as returned from a given leader board query. Do associative lookups with the member to rank, score and potentially sort the results. + @param leaderboard_name [String] Name of the leaderboard. + @param members [List] A list of members as returned from a sorted set range query + @param members_only [bool] Set True to return the members as is, Default is False. + @param options [Hash] Options to be used when retrieving the page from the named leaderboard. + @return a list of members. + ''' + if members_only: + return [{'member': m} for m in members] + + if members: + return self.ranked_in_list_in(leaderboard_name, members, **options) + else: + return [] diff --git a/test/leaderboard/leaderboard_test.py b/test/leaderboard/leaderboard_test.py index 0cf2ab1..51c8943 100644 --- a/test/leaderboard/leaderboard_test.py +++ b/test/leaderboard/leaderboard_test.py @@ -303,6 +303,28 @@ def test_around_me(self): 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')