leaderboard 2.1.0 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
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
  #
@@ -1,4 +1,4 @@
1
1
  class Leaderboard
2
2
  # Leaderboard version
3
- VERSION = '2.1.0'.freeze
3
+ VERSION = '2.2.1'.freeze
4
4
  end
@@ -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
@@ -2,6 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe 'Leaderboard::VERSION' do
4
4
  it 'should be the correct version' do
5
- Leaderboard::VERSION.should == '2.1.0'
5
+ Leaderboard::VERSION.should == '2.2.1'
6
6
  end
7
7
  end
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.0
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-11 00:00:00.000000000 Z
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: 248515504144092266
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: 248515504144092266
109
+ hash: -27523170013791394
110
110
  requirements: []
111
111
  rubyforge_project: leaderboard
112
112
  rubygems_version: 1.8.23