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 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