leaderboard 2.1.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.markdown +10 -0
- data/README.markdown +16 -0
- data/lib/leaderboard.rb +68 -0
- data/lib/leaderboard/version.rb +1 -1
- data/spec/leaderboard_spec.rb +45 -0
- data/spec/reverse_leaderboard_spec.rb +45 -0
- data/spec/version_spec.rb +1 -1
- metadata +4 -4
data/CHANGELOG.markdown
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## leaderboard 2.2.1 (2012-06-18)
|
4
|
+
|
5
|
+
* Fix for #17 - Leaderboard not compatible with redis 2.1.1. Redis' `zrangebyscore` and `zrevrangebyscore` methods do not return scores by default. No need to pass the option in the initial call.
|
6
|
+
|
7
|
+
## leaderboard 2.2.0 (2012-06-18)
|
8
|
+
|
9
|
+
* Added `members_from_score_range` and `members_from_score_range_in` methods. These will retrieve members from the leaderboard that fall within a given score range.
|
10
|
+
* Add `member_at` and `member_at_in` methods. These will retrieve a given member from the leaderboard at the specified position.
|
11
|
+
* `members` and `members_in` are now aliases for the `leaders` and `leaders_in` methods.
|
12
|
+
|
3
13
|
## leaderboard 2.1.0 (2012-06-11)
|
4
14
|
|
5
15
|
* Added ability to store optional member data alongside the leaderboard data.
|
data/README.markdown
CHANGED
@@ -174,6 +174,8 @@ Below is an example of retrieving the first page in the leaderboard without scor
|
|
174
174
|
=> [{:member=>"member_10"}, {:member=>"member_9"}, {:member=>"member_8"}, {:member=>"member_7"}, {:member=>"member_6"}, {:member=>"member_5"}, {:member=>"member_4"}, {:member=>"member_3"}, {:member=>"member_2"}, {:member=>"member_1"}]
|
175
175
|
```
|
176
176
|
|
177
|
+
You can also use the `members` and `members_in` methods as aliases for the `leaders` and `leaders_in` methods.
|
178
|
+
|
177
179
|
Add more members to your leaderboard:
|
178
180
|
|
179
181
|
```ruby
|
@@ -199,6 +201,20 @@ Get rank and score for an arbitrary list of members (e.g. friends) from the lead
|
|
199
201
|
=> [{:member=>"member_1", :rank=>56, :score=>1.0}, {:member=>"member_62", :rank=>34, :score=>62.0}, {:member=>"member_67", :rank=>29, :score=>67.0}]
|
200
202
|
```
|
201
203
|
|
204
|
+
Retrieve members from the leaderboard in a given score range:
|
205
|
+
|
206
|
+
```ruby
|
207
|
+
members = highscore_lb.members_from_score_range(4, 19)
|
208
|
+
=> [{:member=>"member_10", :rank=>47, :score=>10.0}, {:member=>"member_9", :rank=>48, :score=>9.0}, {:member=>"member_8", :rank=>49, :score=>8.0}, {:member=>"member_7", :rank=>50, :score=>7.0}, {:member=>"member_6", :rank=>51, :score=>6.0}, {:member=>"member_5", :rank=>52, :score=>5.0}, {:member=>"member_4", :rank=>53, :score=>4.0}]
|
209
|
+
```
|
210
|
+
|
211
|
+
Retrieve a single member from the leaderboard at a given position:
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
members = highscore_lb.member_at(4)
|
215
|
+
=> {:member=>"member_92", :rank=>4, :score=>92.0}
|
216
|
+
```
|
217
|
+
|
202
218
|
### Ranking multiple members in a leaderboard at once
|
203
219
|
|
204
220
|
Insert multiple data items for members and their associated scores:
|
data/lib/leaderboard.rb
CHANGED
@@ -489,6 +489,8 @@ class Leaderboard
|
|
489
489
|
leaders_in(@leaderboard_name, current_page, options)
|
490
490
|
end
|
491
491
|
|
492
|
+
alias_method :members, :leaders
|
493
|
+
|
492
494
|
# Retrieve a page of leaders from the named leaderboard.
|
493
495
|
#
|
494
496
|
# @param leaderboard_name [String] Name of the leaderboard.
|
@@ -531,6 +533,72 @@ class Leaderboard
|
|
531
533
|
return []
|
532
534
|
end
|
533
535
|
end
|
536
|
+
|
537
|
+
alias_method :members_in, :leaders_in
|
538
|
+
|
539
|
+
# Retrieve members from the leaderboard within a given score range.
|
540
|
+
#
|
541
|
+
# @param minimum_score [float] Minimum score (inclusive).
|
542
|
+
# @param maximum_score [float] Maximum score (inclusive).
|
543
|
+
# @param options [Hash] Options to be used when retrieving the data from the leaderboard.
|
544
|
+
#
|
545
|
+
# @return members from the leaderboard that fall within the given score range.
|
546
|
+
def members_from_score_range(minimum_score, maximum_score, options = {})
|
547
|
+
members_from_score_range_in(@leaderboard_name, minimum_score, maximum_score, options)
|
548
|
+
end
|
549
|
+
|
550
|
+
# Retrieve members from the named leaderboard within a given score range.
|
551
|
+
#
|
552
|
+
# @param leaderboard_name [String] Name of the leaderboard.
|
553
|
+
# @param minimum_score [float] Minimum score (inclusive).
|
554
|
+
# @param maximum_score [float] Maximum score (inclusive).
|
555
|
+
# @param options [Hash] Options to be used when retrieving the data from the leaderboard.
|
556
|
+
#
|
557
|
+
# @return members from the leaderboard that fall within the given score range.
|
558
|
+
def members_from_score_range_in(leaderboard_name, minimum_score, maximum_score, options = {})
|
559
|
+
leaderboard_options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS.dup
|
560
|
+
leaderboard_options.merge!(options)
|
561
|
+
|
562
|
+
raw_leader_data = @reverse ?
|
563
|
+
@redis_connection.zrangebyscore(leaderboard_name, minimum_score, maximum_score) :
|
564
|
+
@redis_connection.zrevrangebyscore(leaderboard_name, maximum_score, minimum_score)
|
565
|
+
|
566
|
+
if raw_leader_data
|
567
|
+
return ranked_in_list_in(leaderboard_name, raw_leader_data, leaderboard_options)
|
568
|
+
else
|
569
|
+
return []
|
570
|
+
end
|
571
|
+
end
|
572
|
+
|
573
|
+
# Retrieve a member at the specified index from the leaderboard.
|
574
|
+
#
|
575
|
+
# @param position [int] Position in leaderboard.
|
576
|
+
# @param options [Hash] Options to be used when retrieving the member from the leaderboard.
|
577
|
+
#
|
578
|
+
# @return a member from the leaderboard.
|
579
|
+
def member_at(position, options = {})
|
580
|
+
member_at_in(@leaderboard_name, position, options)
|
581
|
+
end
|
582
|
+
|
583
|
+
# Retrieve a member at the specified index from the leaderboard.
|
584
|
+
#
|
585
|
+
# @param leaderboard_name [String] Name of the leaderboard.
|
586
|
+
# @param position [int] Position in named leaderboard.
|
587
|
+
# @param options [Hash] Options to be used when retrieving the member from the named leaderboard.
|
588
|
+
#
|
589
|
+
# @return a page of leaders from the named leaderboard.
|
590
|
+
def member_at_in(leaderboard_name, position, options = {})
|
591
|
+
if position <= total_members_in(leaderboard_name)
|
592
|
+
leaderboard_options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS.dup
|
593
|
+
leaderboard_options.merge!(options)
|
594
|
+
page_size = validate_page_size(leaderboard_options[:page_size]) || @page_size
|
595
|
+
current_page = (position.to_f / page_size.to_f).ceil
|
596
|
+
offset = (position - 1) % page_size
|
597
|
+
|
598
|
+
leaders = leaders_in(leaderboard_name, current_page, options)
|
599
|
+
leaders[offset] if leaders
|
600
|
+
end
|
601
|
+
end
|
534
602
|
|
535
603
|
# Retrieve a page of leaders from the leaderboard around a given member.
|
536
604
|
#
|
data/lib/leaderboard/version.rb
CHANGED
data/spec/leaderboard_spec.rb
CHANGED
@@ -102,6 +102,20 @@ describe 'Leaderboard' do
|
|
102
102
|
leaders[-1][:score].to_i.should be(1)
|
103
103
|
end
|
104
104
|
|
105
|
+
it 'should return the correct list when calling members' do
|
106
|
+
rank_members_in_leaderboard(25)
|
107
|
+
|
108
|
+
@leaderboard.total_members.should be(25)
|
109
|
+
|
110
|
+
members = @leaderboard.members(1)
|
111
|
+
|
112
|
+
members.size.should be(25)
|
113
|
+
members[0][:member].should == 'member_25'
|
114
|
+
members[-2][:member].should == 'member_2'
|
115
|
+
members[-1][:member].should == 'member_1'
|
116
|
+
members[-1][:score].to_i.should be(1)
|
117
|
+
end
|
118
|
+
|
105
119
|
it 'should return the correct number of members when calling leaders with multiple pages' do
|
106
120
|
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1)
|
107
121
|
|
@@ -126,6 +140,26 @@ describe 'Leaderboard' do
|
|
126
140
|
leaders.size.should be(1)
|
127
141
|
end
|
128
142
|
|
143
|
+
it 'should allow you to retrieve members in a given score range' do
|
144
|
+
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
|
145
|
+
|
146
|
+
members = @leaderboard.members_from_score_range(10, 15, {:with_scores => false, :with_rank => false})
|
147
|
+
|
148
|
+
member_15 = {:member => 'member_15'}
|
149
|
+
members[0].should == member_15
|
150
|
+
|
151
|
+
member_10 = {:member => 'member_10'}
|
152
|
+
members[5].should == member_10
|
153
|
+
|
154
|
+
members = @leaderboard.members_from_score_range(10, 15, {:with_scores => true, :with_rank => true, :with_member_data => true})
|
155
|
+
|
156
|
+
member_15 = {:member => 'member_15', :rank => 11, :score => 15.0, :member_data => {'member_name' => 'Leaderboard member 15'}}
|
157
|
+
members[0].should == member_15
|
158
|
+
|
159
|
+
member_10 = {:member => 'member_10', :rank => 16, :score => 10.0, :member_data => {'member_name' => 'Leaderboard member 10'}}
|
160
|
+
members[5].should == member_10
|
161
|
+
end
|
162
|
+
|
129
163
|
it 'should allow you to retrieve leaders without scores and ranks' do
|
130
164
|
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
|
131
165
|
|
@@ -210,6 +244,17 @@ describe 'Leaderboard' do
|
|
210
244
|
leaders[0].should == member_26
|
211
245
|
end
|
212
246
|
|
247
|
+
it 'should return a single member when calling member_at' do
|
248
|
+
rank_members_in_leaderboard(50)
|
249
|
+
@leaderboard.member_at(1)[:rank].should == 1
|
250
|
+
@leaderboard.member_at(1)[:score].should == 50.0
|
251
|
+
@leaderboard.member_at(26)[:rank].should == 26
|
252
|
+
@leaderboard.member_at(50)[:rank].should == 50
|
253
|
+
@leaderboard.member_at(51).should be_nil
|
254
|
+
@leaderboard.member_at(1, :with_member_data => true)[:member_data].should == {'member_name' => 'Leaderboard member 50'}
|
255
|
+
@leaderboard.member_at(1, :use_zero_index_for_rank => true)[:rank].should == 0
|
256
|
+
end
|
257
|
+
|
213
258
|
it 'should return the correct information when calling around_me' do
|
214
259
|
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1)
|
215
260
|
|
@@ -33,6 +33,40 @@ describe 'Leaderboard (reverse option)' do
|
|
33
33
|
leaders[-1][:score].to_i.should be(25)
|
34
34
|
end
|
35
35
|
|
36
|
+
it 'should return the correct list when calling members' do
|
37
|
+
rank_members_in_leaderboard(25)
|
38
|
+
|
39
|
+
@leaderboard.total_members.should be(25)
|
40
|
+
|
41
|
+
members = @leaderboard.members(1)
|
42
|
+
|
43
|
+
members.size.should be(25)
|
44
|
+
members[0][:member].should == 'member_1'
|
45
|
+
members[-2][:member].should == 'member_24'
|
46
|
+
members[-1][:member].should == 'member_25'
|
47
|
+
members[-1][:score].to_i.should be(25)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should allow you to retrieve members in a given score range' do
|
51
|
+
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
|
52
|
+
|
53
|
+
members = @leaderboard.members_from_score_range(10, 15, {:with_scores => false, :with_rank => false})
|
54
|
+
|
55
|
+
member_10 = {:member => 'member_10'}
|
56
|
+
members[0].should == member_10
|
57
|
+
|
58
|
+
member_15 = {:member => 'member_15'}
|
59
|
+
members[5].should == member_15
|
60
|
+
|
61
|
+
members = @leaderboard.members_from_score_range(10, 15, {:with_scores => true, :with_rank => true, :with_member_data => true})
|
62
|
+
|
63
|
+
member_10 = {:member => 'member_10', :rank => 10, :score => 10.0, :member_data => {'member_name' => 'Leaderboard member 10'}}
|
64
|
+
members[0].should == member_10
|
65
|
+
|
66
|
+
member_15 = {:member => 'member_15', :rank => 15, :score => 15.0, :member_data => {'member_name' => 'Leaderboard member 15'}}
|
67
|
+
members[5].should == member_15
|
68
|
+
end
|
69
|
+
|
36
70
|
it 'should allow you to retrieve leaders without scores and ranks' do
|
37
71
|
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
|
38
72
|
|
@@ -81,6 +115,17 @@ describe 'Leaderboard (reverse option)' do
|
|
81
115
|
leaders[0].should == member_1
|
82
116
|
end
|
83
117
|
|
118
|
+
it 'should return a single member when calling member_at' do
|
119
|
+
rank_members_in_leaderboard(50)
|
120
|
+
@leaderboard.member_at(1)[:rank].should == 1
|
121
|
+
@leaderboard.member_at(1)[:score].should == 1.0
|
122
|
+
@leaderboard.member_at(26)[:rank].should == 26
|
123
|
+
@leaderboard.member_at(50)[:rank].should == 50
|
124
|
+
@leaderboard.member_at(51).should be_nil
|
125
|
+
@leaderboard.member_at(1, :with_member_data => true)[:member_data].should == {'member_name' => 'Leaderboard member 1'}
|
126
|
+
@leaderboard.member_at(1, :use_zero_index_for_rank => true)[:rank].should == 0
|
127
|
+
end
|
128
|
+
|
84
129
|
it 'should return the correct information when calling around_me' do
|
85
130
|
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1)
|
86
131
|
|
data/spec/version_spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: leaderboard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1
|
4
|
+
version: 2.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06-
|
12
|
+
date: 2012-06-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
@@ -97,7 +97,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
97
97
|
version: '0'
|
98
98
|
segments:
|
99
99
|
- 0
|
100
|
-
hash:
|
100
|
+
hash: -27523170013791394
|
101
101
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
102
|
none: false
|
103
103
|
requirements:
|
@@ -106,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
106
|
version: '0'
|
107
107
|
segments:
|
108
108
|
- 0
|
109
|
-
hash:
|
109
|
+
hash: -27523170013791394
|
110
110
|
requirements: []
|
111
111
|
rubyforge_project: leaderboard
|
112
112
|
rubygems_version: 1.8.23
|