strava-ruby-client 0.4.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -1
- data/README.md +90 -88
- data/bin/strava-oauth-token +2 -2
- data/bin/strava-webhooks +2 -2
- data/lib/strava/api/client.rb +21 -2
- data/lib/strava/api/endpoints/routes.rb +2 -2
- data/lib/strava/api/endpoints/running_races.rb +0 -12
- data/lib/strava/api/endpoints/segments.rb +0 -46
- data/lib/strava/api/pagination.rb +60 -0
- data/lib/strava/api/ratelimit.rb +159 -0
- data/lib/strava/deep_copyable.rb +16 -0
- data/lib/strava/models/achievement.rb +1 -1
- data/lib/strava/models/activity.rb +48 -2
- data/lib/strava/models/activity_stats.rb +1 -1
- data/lib/strava/models/activity_total.rb +1 -1
- data/lib/strava/models/activity_zone.rb +1 -1
- data/lib/strava/models/athlete.rb +1 -2
- data/lib/strava/models/authorization.rb +1 -1
- data/lib/strava/models/club.rb +1 -1
- data/lib/strava/models/club_admin.rb +1 -1
- data/lib/strava/models/club_event.rb +1 -1
- data/lib/strava/models/club_member.rb +1 -1
- data/lib/strava/models/comment.rb +1 -1
- data/lib/strava/models/explorer_segment.rb +1 -1
- data/lib/strava/models/gear.rb +1 -1
- data/lib/strava/models/heart_rate_zone_ranges.rb +1 -1
- data/lib/strava/models/kudoser.rb +1 -1
- data/lib/strava/models/lap.rb +1 -1
- data/lib/strava/models/map.rb +1 -1
- data/lib/strava/models/mixins/http_response.rb +15 -0
- data/lib/strava/models/photo.rb +1 -1
- data/lib/strava/models/photos.rb +1 -1
- data/lib/strava/models/power_zone_ranges.rb +1 -1
- data/lib/strava/models/response.rb +9 -0
- data/lib/strava/models/route.rb +1 -1
- data/lib/strava/models/running_race.rb +1 -1
- data/lib/strava/models/segment.rb +1 -1
- data/lib/strava/models/segment_effort.rb +1 -1
- data/lib/strava/models/segment_stats.rb +1 -1
- data/lib/strava/models/similar_activities.rb +1 -1
- data/lib/strava/models/split.rb +1 -1
- data/lib/strava/models/stream.rb +1 -1
- data/lib/strava/models/stream_set.rb +1 -1
- data/lib/strava/models/timed_zone_range.rb +1 -1
- data/lib/strava/models/token.rb +1 -1
- data/lib/strava/models/trend.rb +1 -1
- data/lib/strava/models/upload.rb +1 -1
- data/lib/strava/models/zone_range.rb +1 -1
- data/lib/strava/models/zones.rb +1 -1
- data/lib/strava/version.rb +1 -1
- data/lib/strava/web/api_response.rb +17 -0
- data/lib/strava/web/client.rb +2 -2
- data/lib/strava/web/connection.rb +4 -4
- data/lib/strava/web/raise_response_error.rb +29 -0
- data/lib/strava/web/request.rb +3 -2
- data/lib/strava/web/response.rb +92 -0
- data/lib/strava/webhooks/models/subscription.rb +1 -1
- data/lib/strava-ruby-client.rb +9 -4
- metadata +17 -12
- data/lib/strava/models/segment_leaderboard.rb +0 -12
- data/lib/strava/models/segment_leaderboard_entry.rb +0 -14
- data/lib/strava/web/raise_error.rb +0 -31
data/lib/strava/web/client.rb
CHANGED
@@ -25,10 +25,10 @@ module Strava
|
|
25
25
|
options[:request] = request_options if request_options.any?
|
26
26
|
|
27
27
|
::Faraday::Connection.new(endpoint, options) do |connection|
|
28
|
-
connection.
|
29
|
-
connection.
|
30
|
-
connection.use
|
31
|
-
connection.
|
28
|
+
connection.request :multipart
|
29
|
+
connection.request :url_encoded
|
30
|
+
connection.use Strava::Web::RaiseResponseError
|
31
|
+
connection.response :json
|
32
32
|
connection.response :logger, logger if logger
|
33
33
|
connection.adapter ::Faraday.default_adapter
|
34
34
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Strava
|
4
|
+
module Web
|
5
|
+
class RaiseResponseError < ::Faraday::Middleware
|
6
|
+
CLIENT_ERROR_STATUSES = (400...600).freeze
|
7
|
+
|
8
|
+
def on_complete(env)
|
9
|
+
case env[:status]
|
10
|
+
when 404
|
11
|
+
raise Faraday::ResourceNotFound, response_values(env)
|
12
|
+
when 407
|
13
|
+
# mimic the behavior that we get with proxy requests with HTTPS
|
14
|
+
raise Faraday::ConnectionFailed, %(407 "Proxy Authentication Required ")
|
15
|
+
when CLIENT_ERROR_STATUSES
|
16
|
+
raise Strava::Errors::Fault, response_values(env)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def response_values(env)
|
21
|
+
{
|
22
|
+
status: env.status,
|
23
|
+
headers: env.response_headers,
|
24
|
+
body: env.body
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/strava/web/request.rb
CHANGED
@@ -25,7 +25,7 @@ module Strava
|
|
25
25
|
options = options.dup if options.key?(:request) || options.key?(:endpoint)
|
26
26
|
root = options.delete(:endpoint) || endpoint
|
27
27
|
path = [root, path].join('/')
|
28
|
-
|
28
|
+
http_response = connection.send(method) do |request|
|
29
29
|
case method
|
30
30
|
when :get, :delete
|
31
31
|
request.url(path, options)
|
@@ -35,7 +35,8 @@ module Strava
|
|
35
35
|
end
|
36
36
|
request.options.merge!(options.delete(:request)) if options.key?(:request)
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
|
+
Strava::Web::Response.new(http_response)
|
39
40
|
end
|
40
41
|
end
|
41
42
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Strava
|
4
|
+
module Web
|
5
|
+
#
|
6
|
+
# wrapper class as abstraction for API response returned from the Faraday Adapter
|
7
|
+
# working with a deep copy, in order to not mutate the original request itself
|
8
|
+
#
|
9
|
+
class Response
|
10
|
+
include Strava::DeepCopyable
|
11
|
+
|
12
|
+
attr_reader :http_response, :response
|
13
|
+
|
14
|
+
#
|
15
|
+
# @param [Faraday::Response] http_response
|
16
|
+
#
|
17
|
+
def initialize(http_response)
|
18
|
+
@http_response = deep_copy(http_response)
|
19
|
+
@response = conditional_response_upgrade!(http_response)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
#
|
25
|
+
# returns a modified deep copy of the Faraday::Response
|
26
|
+
#
|
27
|
+
# @param [Faraday::Response] http_response
|
28
|
+
#
|
29
|
+
# @return [Array, Hash{String => any}]
|
30
|
+
#
|
31
|
+
def conditional_response_upgrade!(http_response)
|
32
|
+
response = deep_copy(http_response)
|
33
|
+
|
34
|
+
case response.body
|
35
|
+
when Array
|
36
|
+
upgrade_array_body!(response)
|
37
|
+
when Hash
|
38
|
+
response.body['http_response'] = response
|
39
|
+
else
|
40
|
+
response.body
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# mutates the response when body is_a? Hash
|
46
|
+
#
|
47
|
+
# @param [Symbol] method_symbol
|
48
|
+
# @param [any] *args
|
49
|
+
# @param [Proc] &block
|
50
|
+
#
|
51
|
+
# @raise [NoMethodError]
|
52
|
+
# @return [any]
|
53
|
+
#
|
54
|
+
def operate_on_response_body!(method_symbol, *args, &block)
|
55
|
+
case @response.body
|
56
|
+
when Hash
|
57
|
+
@response.body.send(method_symbol, *args, &block)
|
58
|
+
else
|
59
|
+
raise NoMethodError
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# mutates all responses in the body
|
65
|
+
#
|
66
|
+
# @param [Faraday::Response] response from the Strava API
|
67
|
+
#
|
68
|
+
# @return [Array<Faraday::Response>]
|
69
|
+
#
|
70
|
+
def upgrade_array_body!(response)
|
71
|
+
response.body.map! do |body_elem|
|
72
|
+
body_elem ||= {}
|
73
|
+
body_elem['http_response'] = response
|
74
|
+
body_elem
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def method_missing(method_symbol, *args, &block)
|
79
|
+
case @response
|
80
|
+
when Array
|
81
|
+
@response.send(method_symbol, *args, &block)
|
82
|
+
else
|
83
|
+
operate_on_response_body!(method_symbol, *args, &block)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def respond_to_missing?(method_name, include_private = false)
|
88
|
+
super
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/lib/strava-ruby-client.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'faraday'
|
4
|
-
require '
|
4
|
+
require 'faraday/multipart'
|
5
5
|
require 'json'
|
6
6
|
require 'logger'
|
7
7
|
require 'hashie'
|
@@ -14,15 +14,18 @@ require 'active_support/concern'
|
|
14
14
|
|
15
15
|
require_relative 'strava/version'
|
16
16
|
require_relative 'strava/logger'
|
17
|
+
require_relative 'strava/deep_copyable'
|
17
18
|
|
18
19
|
require_relative 'strava/errors/fault'
|
19
20
|
|
21
|
+
require_relative 'strava/models/mixins/http_response'
|
20
22
|
require_relative 'strava/models/mixins/distance'
|
21
23
|
require_relative 'strava/models/mixins/elevation'
|
22
24
|
require_relative 'strava/models/mixins/time'
|
23
25
|
require_relative 'strava/models/mixins/start_date_local'
|
24
26
|
|
25
27
|
require_relative 'strava/models/model'
|
28
|
+
require_relative 'strava/models/response'
|
26
29
|
require_relative 'strava/models/token'
|
27
30
|
require_relative 'strava/models/athlete'
|
28
31
|
require_relative 'strava/models/map'
|
@@ -54,19 +57,19 @@ require_relative 'strava/models/kudoser'
|
|
54
57
|
require_relative 'strava/models/running_race'
|
55
58
|
require_relative 'strava/models/achievement'
|
56
59
|
require_relative 'strava/models/segment_stats'
|
57
|
-
require_relative 'strava/models/segment_leaderboard'
|
58
|
-
require_relative 'strava/models/segment_leaderboard_entry'
|
59
60
|
require_relative 'strava/models/explorer_segment'
|
60
61
|
require_relative 'strava/models/stream_set'
|
61
62
|
require_relative 'strava/models/stream'
|
62
63
|
require_relative 'strava/models/upload'
|
63
64
|
require_relative 'strava/models/authorization'
|
64
65
|
|
65
|
-
require_relative 'strava/web/
|
66
|
+
require_relative 'strava/web/raise_response_error'
|
66
67
|
require_relative 'strava/web/connection'
|
68
|
+
require_relative 'strava/web/api_response'
|
67
69
|
require_relative 'strava/web/request'
|
68
70
|
require_relative 'strava/web/config'
|
69
71
|
require_relative 'strava/web/client'
|
72
|
+
require_relative 'strava/web/response'
|
70
73
|
|
71
74
|
require_relative 'strava/oauth/config'
|
72
75
|
require_relative 'strava/oauth/client'
|
@@ -79,6 +82,7 @@ require_relative 'strava/webhooks/models/event'
|
|
79
82
|
|
80
83
|
require_relative 'strava/api/config'
|
81
84
|
require_relative 'strava/api/cursor'
|
85
|
+
require_relative 'strava/api/ratelimit'
|
82
86
|
|
83
87
|
require_relative 'strava/api/endpoints/activities'
|
84
88
|
require_relative 'strava/api/endpoints/athletes'
|
@@ -92,4 +96,5 @@ require_relative 'strava/api/endpoints/streams'
|
|
92
96
|
require_relative 'strava/api/endpoints/uploads'
|
93
97
|
require_relative 'strava/api/endpoints/oauth'
|
94
98
|
|
99
|
+
require_relative 'strava/api/pagination'
|
95
100
|
require_relative 'strava/api/client'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: strava-ruby-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Doubrovkine
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-12-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -30,28 +30,28 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: '2.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: '2.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: faraday-multipart
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
47
|
+
version: '1.0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
54
|
+
version: '1.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: hashie
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +94,9 @@ files:
|
|
94
94
|
- lib/strava/api/endpoints/segments.rb
|
95
95
|
- lib/strava/api/endpoints/streams.rb
|
96
96
|
- lib/strava/api/endpoints/uploads.rb
|
97
|
+
- lib/strava/api/pagination.rb
|
98
|
+
- lib/strava/api/ratelimit.rb
|
99
|
+
- lib/strava/deep_copyable.rb
|
97
100
|
- lib/strava/errors/fault.rb
|
98
101
|
- lib/strava/logger.rb
|
99
102
|
- lib/strava/models/achievement.rb
|
@@ -116,18 +119,18 @@ files:
|
|
116
119
|
- lib/strava/models/map.rb
|
117
120
|
- lib/strava/models/mixins/distance.rb
|
118
121
|
- lib/strava/models/mixins/elevation.rb
|
122
|
+
- lib/strava/models/mixins/http_response.rb
|
119
123
|
- lib/strava/models/mixins/start_date_local.rb
|
120
124
|
- lib/strava/models/mixins/time.rb
|
121
125
|
- lib/strava/models/model.rb
|
122
126
|
- lib/strava/models/photo.rb
|
123
127
|
- lib/strava/models/photos.rb
|
124
128
|
- lib/strava/models/power_zone_ranges.rb
|
129
|
+
- lib/strava/models/response.rb
|
125
130
|
- lib/strava/models/route.rb
|
126
131
|
- lib/strava/models/running_race.rb
|
127
132
|
- lib/strava/models/segment.rb
|
128
133
|
- lib/strava/models/segment_effort.rb
|
129
|
-
- lib/strava/models/segment_leaderboard.rb
|
130
|
-
- lib/strava/models/segment_leaderboard_entry.rb
|
131
134
|
- lib/strava/models/segment_stats.rb
|
132
135
|
- lib/strava/models/similar_activities.rb
|
133
136
|
- lib/strava/models/split.rb
|
@@ -142,11 +145,13 @@ files:
|
|
142
145
|
- lib/strava/oauth/client.rb
|
143
146
|
- lib/strava/oauth/config.rb
|
144
147
|
- lib/strava/version.rb
|
148
|
+
- lib/strava/web/api_response.rb
|
145
149
|
- lib/strava/web/client.rb
|
146
150
|
- lib/strava/web/config.rb
|
147
151
|
- lib/strava/web/connection.rb
|
148
|
-
- lib/strava/web/
|
152
|
+
- lib/strava/web/raise_response_error.rb
|
149
153
|
- lib/strava/web/request.rb
|
154
|
+
- lib/strava/web/response.rb
|
150
155
|
- lib/strava/webhooks/client.rb
|
151
156
|
- lib/strava/webhooks/config.rb
|
152
157
|
- lib/strava/webhooks/models/challenge.rb
|
@@ -165,14 +170,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
165
170
|
requirements:
|
166
171
|
- - ">="
|
167
172
|
- !ruby/object:Gem::Version
|
168
|
-
version: '2.
|
173
|
+
version: '2.7'
|
169
174
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
175
|
requirements:
|
171
176
|
- - ">="
|
172
177
|
- !ruby/object:Gem::Version
|
173
178
|
version: 1.3.6
|
174
179
|
requirements: []
|
175
|
-
rubygems_version: 3.
|
180
|
+
rubygems_version: 3.2.33
|
176
181
|
signing_key:
|
177
182
|
specification_version: 4
|
178
183
|
summary: Strava API Ruby client.
|
@@ -1,12 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Strava
|
4
|
-
module Models
|
5
|
-
class SegmentLeaderboard < Model
|
6
|
-
property 'effort_count'
|
7
|
-
property 'entry_count'
|
8
|
-
property 'kom_type'
|
9
|
-
property 'entries', transform_with: ->(v) { v.map { |r| SegmentLeaderboardEntry.new(r) } }
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Strava
|
4
|
-
module Models
|
5
|
-
class SegmentLeaderboardEntry < Model
|
6
|
-
include Mixins::Time
|
7
|
-
include Mixins::StartDateLocal
|
8
|
-
|
9
|
-
property 'athlete_name'
|
10
|
-
property 'start_date', transform_with: ->(v) { Time.parse(v) }
|
11
|
-
property 'rank'
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Strava
|
4
|
-
module Web
|
5
|
-
module Response
|
6
|
-
class RaiseError < ::Faraday::Response::Middleware
|
7
|
-
CLIENT_ERROR_STATUSES = (400...600).freeze
|
8
|
-
|
9
|
-
def on_complete(env)
|
10
|
-
case env[:status]
|
11
|
-
when 404
|
12
|
-
raise Faraday::ResourceNotFound, response_values(env)
|
13
|
-
when 407
|
14
|
-
# mimic the behavior that we get with proxy requests with HTTPS
|
15
|
-
raise Faraday::ConnectionFailed, %(407 "Proxy Authentication Required ")
|
16
|
-
when CLIENT_ERROR_STATUSES
|
17
|
-
raise Strava::Errors::Fault, response_values(env)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def response_values(env)
|
22
|
-
{
|
23
|
-
status: env.status,
|
24
|
-
headers: env.response_headers,
|
25
|
-
body: env.body
|
26
|
-
}
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|