Skip to content

Commit 3942dd3

Browse files
committed
Added support for page_size for activity_comments.
1 parent f432e00 commit 3942dd3

19 files changed

+1745
-102
lines changed

CHANGELOG.md

Lines changed: 53 additions & 51 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -790,14 +790,32 @@ See [Strava::Errors::UploadError](lib/strava/errors/upload_failed_error.rb) for
790790

791791
### Pagination
792792

793-
Some Strava APIs, including [athlete-activities](#list-athlete-activities) support pagination when supplying an optional `page` and `per_page` parameter. By default the client retrieves one page of data, which Strava currently defaults to 30 items. You can paginate through more data by supplying a block and an optional `per_page` parameter. The underlying implementation makes page-sized calls and increments the `page` argument.
793+
Some Strava APIs, including [athlete-activities](#list-athlete-activities) support pagination when supplying an optional `page` and `per_page` parameter. By default the client retrieves one page of data, which Strava currently defaults to 30 items. If you supply `per_page`, the client will retrieve all pages. You can paginate through items incrementally by supplying a block. Use `limit` to limit the number of items returned. The underlying implementation makes page-sized calls and increments the `page` argument.
794794

795795
```ruby
796796
client.athlete_activities(per_page: 30) do |activity|
797797
activity # => Strava::Models::Activity
798798
end
799799
```
800800

801+
```ruby
802+
client.athlete_activities(per_page: 30) # => [Strava::Models::Activity], all pages
803+
client.athlete_activities(per_page: 30, limit: 50) # => [Strava::Models::Activity], all pages, stop at 50 items
804+
```
805+
806+
Some Strava APIs, including [activity-comments](#list-activity-comments) support cursor-based pagination when supplying optional `after_cursor` and `page_size` parameters. By default the client retrieves one page of data, which Strava currently defaults to 30 items. If you supply `page_size`, the client will retrieve all pages. You can paginate through items incrementally by supplying a block. Use `limit` to limit the number of items returned. The underlying implementation makes page-sized calls and uses the returned `cursor` as `after_cursor`.
807+
808+
```ruby
809+
client.activity_comments(id: 1982980795, page_size: 30) do |comment|
810+
comment # => Strava::Models::Comment
811+
end
812+
```
813+
814+
```ruby
815+
client.activity_comments(id: 1982980795, page_size: 30) # => [Strava::Models::Comment], all pages
816+
client.activity_comments(id: 1982980795, page_size: 30, limit: 100) # => [Strava::Models::Comment], paginated, stop at 100 items
817+
```
818+
801819
### OAuth
802820

803821
#### OAuth Workflow

UPGRADING.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,31 @@ This change fixes the `Hashie::Trash` serialization warning that occurred when u
9393

9494
See [#92](https://github.com/dblock/strava-ruby-client/pull/92) for details.
9595

96+
#### Always Paginate with `per_page` or `page_size`
97+
98+
The client will always paginate data if `per_page` or `page_size` are provided.
99+
100+
**Before (v2.x):**
101+
```ruby
102+
# one request for a page of 10 items
103+
client.activity_comments(id: 1982980795, page_size: 10) # => [Strava::Models::Comment]
104+
```
105+
106+
**After (v3.0.0):**
107+
```ruby
108+
# all pages, multiple requests, potentially more than 10 items
109+
client.activity_comments(id: 1982980795, page_size: 10) # => [Strava::Models::Comment]
110+
```
111+
112+
Use `limit` in combination with `page_size` to both paginate and retrieve a certain number of items.
113+
114+
```ruby
115+
# all pages, 10 items per page, no more than 20 items
116+
client.activity_comments(id: 1982980795, page_size: 10, limit: 20) # => [Strava::Models::Comment]
117+
```
118+
119+
See [#99](https://github.com/dblock/strava-ruby-client/pull/99) for details.
120+
96121
### Upgrading to >= 2.3.0
97122

98123
Faraday can optionally exclude HTTP method, path and query params from the errors raised. The client implementation options will now default to `Faraday::Response::RaiseError::DEFAULT_OPTIONS` with `include_request` set to `true`. You can change this behavior by setting `Strava::Web::RaiseResponseError::DEFAULT_OPTIONS`.

lib/strava/api/client.rb

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def config
4040
private
4141

4242
#
43-
# paginates requests
43+
# Paginates requests using per_page.
4444
#
4545
# @param [String] path url for request
4646
# @param [Hash] options hash containing settings
@@ -51,21 +51,54 @@ def config
5151
#
5252
# @return [Strava::Api::Pagination]
5353
#
54-
def paginate(path, options, model)
54+
def paginate(path, options, model, &block)
55+
raise ArgumentError, 'per_page' if options.key(:page_size)
56+
57+
paginate_with_cursor(path, options, model, &block)
58+
end
59+
60+
#
61+
# Paginates requests using a cursor, using per_page or page_size.
62+
#
63+
# @param [String] path url for request
64+
# @param [Hash] options hash containing settings
65+
# @param [Class] model by Class
66+
#
67+
# @example
68+
# paginate("activity/comments", {page_size: 72}, Strava::Models::Comment)
69+
# paginate("athlete/activities", {per_page: 72}, Strava::Models::Activity)
70+
#
71+
# @return [Strava::Api::Pagination]
72+
#
73+
def paginate_with_cursor(path, options, model)
74+
# avoid retrieving unnecessary items
75+
options = options.merge(per_page: options[:limit]) if options.key?(:per_page) && options.key(:limit) && options[:per_page] > options[:limit]
76+
options = options.merge(page_size: options[:limit]) if options.key?(:page_size) && options.key(:limit) && options[:page_size] > options[:limit]
5577
collection = []
5678
web_response = nil
57-
if block_given?
79+
if block_given? || options.key?(:page_size) || options.key(:per_page)
5880
Cursor.new(self, path, options).each do |page|
5981
web_response = page # response of the last request made
6082
page.each do |row|
83+
break if options.key?(:limit) && collection.size >= options[:limit]
84+
6185
m = model.new(row)
62-
yield m
86+
yield m if block_given?
6387
collection << m
6488
end
6589
end
6690
else
67-
web_response = get(path, options)
91+
page_options = if options.key?(:limit)
92+
options.dup.tap do |copy|
93+
copy[:page_size] = copy.delete(:limit)
94+
end
95+
else
96+
options
97+
end
98+
web_response = get(path, page_options)
6899
collection = web_response.map do |row|
100+
break if options.key?(:limit) && collection.size >= options[:limit]
101+
69102
model.new(row)
70103
end
71104
end

lib/strava/api/cursor.rb

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@ class Cursor
1010
def initialize(client, path, params = {})
1111
@client = client
1212
@path = path
13-
@params = params
13+
@params = params.key?(:limit) ? params.dup.tap { |p| p.delete :limit } : params
1414
end
1515

16-
def each
16+
def each(&block)
17+
params[:page_size] ? each_cursor(&block) : each_page(&block)
18+
end
19+
20+
private
21+
22+
def each_page
1723
next_page = 1
1824
loop do
1925
query = params.merge(page: next_page)
@@ -24,6 +30,24 @@ def each
2430
next_page += 1
2531
end
2632
end
33+
34+
def each_cursor
35+
cursor = nil
36+
query = params
37+
loop do
38+
response = client.get(path, query)
39+
break unless response.any?
40+
41+
yield response
42+
43+
break if response.size < params[:page_size]
44+
45+
cursor = response.last&.[]('cursor')
46+
break unless cursor.present?
47+
48+
query = params.merge(after_cursor: cursor)
49+
end
50+
end
2751
end
2852
end
2953
end

lib/strava/api/endpoints/activities.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,15 @@ def activity(id_or_options, options = {})
2929
# Activity id.
3030
# @option options [Integer] :page
3131
# Page number.
32+
# @option options [Integer] :page_size
33+
# Number of items per page. Defaults to 30.
3234
# @option options [Integer] :per_page
3335
# Number of items per page. Defaults to 30.
36+
# @deprecated use {page_size}
3437
#
3538
def activity_comments(id_or_options, options = {}, &block)
3639
id, options = parse_args(id_or_options, options)
37-
paginate "activities/#{id}/comments", options, Strava::Models::Comment, &block
40+
paginate_with_cursor "activities/#{id}/comments", options, Strava::Models::Comment, &block
3841
end
3942

4043
#

lib/strava/api/pagination.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ def initialize(collection, web_response)
2929
# @return [Strava::Web::ApiResponse]
3030
#
3131
def http_response
32-
@http_response ||=
33-
Strava::Web::ApiResponse.new(deep_copy(@web_response).http_response)
32+
@http_response ||= Strava::Web::ApiResponse.new(deep_copy(@web_response).http_response)
3433
end
3534

3635
#

spec/fixtures/strava/client/activity_comments_by_10.yml

Lines changed: 80 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)