strava-ruby-client 0.4.3 → 1.0.0
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.
- 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
|