strava-ruby-client 0.4.0 → 0.4.3
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 +15 -0
- data/README.md +27 -7
- data/bin/strava-oauth-token +2 -1
- data/bin/strava-webhooks +5 -4
- data/lib/strava/api/client.rb +2 -0
- data/lib/strava/api/config.rb +2 -0
- data/lib/strava/api/cursor.rb +3 -3
- data/lib/strava/api/endpoints/activities.rb +2 -0
- data/lib/strava/api/endpoints/athletes.rb +2 -0
- data/lib/strava/api/endpoints/clubs.rb +17 -0
- data/lib/strava/api/endpoints/gears.rb +2 -0
- data/lib/strava/api/endpoints/oauth.rb +2 -0
- data/lib/strava/api/endpoints/routes.rb +2 -0
- data/lib/strava/api/endpoints/running_races.rb +2 -0
- data/lib/strava/api/endpoints/segment_efforts.rb +2 -0
- data/lib/strava/api/endpoints/segments.rb +2 -0
- data/lib/strava/api/endpoints/streams.rb +5 -3
- data/lib/strava/api/endpoints/uploads.rb +2 -0
- data/lib/strava/errors/fault.rb +2 -0
- data/lib/strava/logger.rb +3 -1
- data/lib/strava/models/achievement.rb +2 -0
- data/lib/strava/models/activity.rb +6 -7
- data/lib/strava/models/activity_stats.rb +2 -0
- data/lib/strava/models/activity_total.rb +2 -0
- data/lib/strava/models/activity_zone.rb +2 -0
- data/lib/strava/models/athlete.rb +3 -0
- data/lib/strava/models/authorization.rb +2 -0
- data/lib/strava/models/club.rb +2 -0
- data/lib/strava/models/club_admin.rb +2 -0
- data/lib/strava/models/club_event.rb +30 -0
- data/lib/strava/models/club_member.rb +2 -0
- data/lib/strava/models/comment.rb +2 -0
- data/lib/strava/models/explorer_segment.rb +2 -0
- data/lib/strava/models/gear.rb +5 -0
- data/lib/strava/models/heart_rate_zone_ranges.rb +2 -0
- data/lib/strava/models/kudoser.rb +2 -0
- data/lib/strava/models/lap.rb +3 -1
- data/lib/strava/models/map.rb +2 -0
- data/lib/strava/models/mixins/distance.rb +6 -4
- data/lib/strava/models/mixins/elevation.rb +2 -0
- data/lib/strava/models/mixins/start_date_local.rb +70 -0
- data/lib/strava/models/mixins/time.rb +9 -7
- data/lib/strava/models/model.rb +2 -0
- data/lib/strava/models/photo.rb +2 -0
- data/lib/strava/models/photos.rb +2 -0
- data/lib/strava/models/power_zone_ranges.rb +2 -0
- data/lib/strava/models/route.rb +2 -0
- data/lib/strava/models/running_race.rb +2 -0
- data/lib/strava/models/segment.rb +2 -0
- data/lib/strava/models/segment_effort.rb +3 -1
- data/lib/strava/models/segment_leaderboard.rb +2 -0
- data/lib/strava/models/segment_leaderboard_entry.rb +3 -1
- data/lib/strava/models/segment_stats.rb +2 -0
- data/lib/strava/models/similar_activities.rb +2 -0
- data/lib/strava/models/split.rb +2 -0
- data/lib/strava/models/stream.rb +2 -0
- data/lib/strava/models/stream_set.rb +2 -0
- data/lib/strava/models/timed_zone_range.rb +2 -0
- data/lib/strava/models/token.rb +2 -0
- data/lib/strava/models/trend.rb +2 -0
- data/lib/strava/models/upload.rb +2 -0
- data/lib/strava/models/zone_range.rb +2 -0
- data/lib/strava/models/zones.rb +2 -0
- data/lib/strava/oauth/client.rb +2 -0
- data/lib/strava/oauth/config.rb +2 -0
- data/lib/strava/version.rb +3 -1
- data/lib/strava/web/client.rb +2 -0
- data/lib/strava/web/config.rb +2 -0
- data/lib/strava/web/connection.rb +2 -0
- data/lib/strava/web/raise_error.rb +4 -2
- data/lib/strava/web/request.rb +2 -0
- data/lib/strava/webhooks/client.rb +2 -0
- data/lib/strava/webhooks/config.rb +2 -0
- data/lib/strava/webhooks/models/challenge.rb +2 -0
- data/lib/strava/webhooks/models/event.rb +2 -0
- data/lib/strava/webhooks/models/subscription.rb +2 -0
- data/lib/strava-ruby-client.rb +5 -0
- metadata +12 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f1fd53d322d249bebc5d46c0edaaf9fd6d8831ba2c23134c0450203e078965d6
|
|
4
|
+
data.tar.gz: fa26523a8f6d1987700b414131bd0a754154f734cdf7f21be6988de2fd1a1271
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 65e071fafa80e86f019290774a902a53837bc9a6f4aa15f50306bdf0807fdd929a509638832109cfe2e4380dfa921a4e205623252b4651ab780d6109dfd1f3a7
|
|
7
|
+
data.tar.gz: d0cada36caa3cd5beac43605a3efc55ea79f4603184fdfa1df614418a6b9a59e6b8cff7365b0e6f9bc59ddf036d288480d18d81e5165f35f69b2c912502759b7
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
### 0.4.3 (2022/03/21)
|
|
2
|
+
|
|
3
|
+
* [#51](https://github.com/dblock/strava-ruby-client/pull/51): Ensure support for large Integer IDs - [@simonneutert](https://github.com/simonneutert).
|
|
4
|
+
* [#53](https://github.com/dblock/strava-ruby-client/pull/53): Upgraded to RuboCop 1.26.0 - [@dblock](https://github.com/dblock).
|
|
5
|
+
* [#46](https://github.com/dblock/strava-ruby-client/pull/46): Add missing `activity:read` scope from `strava-oauth-token` - [@xaviershay](https://github.com/xaviershay).
|
|
6
|
+
|
|
7
|
+
### 0.4.2 (2021/10/03)
|
|
8
|
+
|
|
9
|
+
* [#45](https://github.com/dblock/strava-ruby-client/pull/45): Added `Gear#frame_type` `#retired` `#weight` - [@deuber](https://github.com/deuber).
|
|
10
|
+
|
|
11
|
+
### 0.4.1 (2021/07/11)
|
|
12
|
+
|
|
13
|
+
* [#37](https://github.com/dblock/strava-ruby-client/pull/38): Added `Club#club_events` - [@simonneutert](https://github.com/simonneutert).
|
|
14
|
+
* [#34](https://github.com/dblock/strava-ruby-client/pull/34): Added `Athlete#ftp` - [@virae](https://github.com/virae).
|
|
15
|
+
|
|
1
16
|
### 0.4.0 (2020/05/09)
|
|
2
17
|
|
|
3
18
|
* [#29](https://github.com/dblock/strava-ruby-client/pull/29): Cache `Faraday::Connection` for persistent adapters - [@dblock](https://github.com/dblock).
|
data/README.md
CHANGED
|
@@ -2,7 +2,7 @@ Strava Ruby Client
|
|
|
2
2
|
==================
|
|
3
3
|
|
|
4
4
|
[](https://badge.fury.io/rb/strava-ruby-client)
|
|
5
|
-
[](https://github.com/dblock/strava-ruby-client/actions/workflows/test.yml)
|
|
6
6
|
|
|
7
7
|
A complete Ruby client for the [Strava API v3](https://developers.strava.com).
|
|
8
8
|
|
|
@@ -29,6 +29,7 @@ Unlike other clients, including [strava-api-v3](https://github.com/jaredholdcrof
|
|
|
29
29
|
- [Update Athlete](#update-athlete)
|
|
30
30
|
- [Clubs](#clubs)
|
|
31
31
|
- [List Club Activities](#list-club-activities)
|
|
32
|
+
- [List Club Events](#list-club-events)
|
|
32
33
|
- [List Club Administrators](#list-club-administrators)
|
|
33
34
|
- [Get Club](#get-club)
|
|
34
35
|
- [List Club Members](#list-club-members)
|
|
@@ -357,6 +358,20 @@ activity.name # => 'Afternoon Run'
|
|
|
357
358
|
|
|
358
359
|
See [Strava::Models::Activity](lib/strava/models/activity.rb) for all available properties. Note that Strava does not return activity or athlete ID via this API.
|
|
359
360
|
|
|
361
|
+
#### List Club Events
|
|
362
|
+
|
|
363
|
+
Retrieve recent Events from a specific club.
|
|
364
|
+
|
|
365
|
+
```ruby
|
|
366
|
+
events = client.club_events(108605) # => Array[Strava::Models::ClubEvent]
|
|
367
|
+
|
|
368
|
+
event = events.first # => Strava::Models::ClubEvent
|
|
369
|
+
|
|
370
|
+
event.title # => 'First Group Event Ever! Yippieh!'
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
See [Strava::Models::ClubEvent](lib/strava/models/club_event.rb) for all available properties.
|
|
374
|
+
|
|
360
375
|
#### List Club Administrators
|
|
361
376
|
|
|
362
377
|
Returns a list of the administrators of a given club.
|
|
@@ -417,15 +432,19 @@ See [Strava::Models::Club](lib/strava/models/club.rb) for all available properti
|
|
|
417
432
|
Returns an equipment using its identifier.
|
|
418
433
|
|
|
419
434
|
```ruby
|
|
420
|
-
gear = client.gear('
|
|
435
|
+
gear = client.gear(id: 'b2338517') # => Strava::Models::Gear
|
|
421
436
|
|
|
422
|
-
gear.id # => '
|
|
423
|
-
gear.name # => '
|
|
437
|
+
gear.id # => 'b2338517'
|
|
438
|
+
gear.name # => 'Trek'
|
|
424
439
|
gear.distance # => 380939.0
|
|
425
440
|
gear.distance_s # => '380.94km'
|
|
426
|
-
gear.brand_name # => '
|
|
427
|
-
gear.model_name # => '
|
|
428
|
-
gear.description # => '
|
|
441
|
+
gear.brand_name # => 'Trek'
|
|
442
|
+
gear.model_name # => 'Madone'
|
|
443
|
+
gear.description # => 'white'
|
|
444
|
+
gear.primary # => 'false'
|
|
445
|
+
gear.frame_type # => '3'
|
|
446
|
+
gear.weight # => '9'
|
|
447
|
+
gear.retired # => 'false'
|
|
429
448
|
```
|
|
430
449
|
|
|
431
450
|
See [Strava::Models::Gear](lib/strava/models/gear.rb) for all available properties.
|
|
@@ -1058,6 +1077,7 @@ $ STRAVA_CLIENT_ID=... STRAVA_CLIENT_SECRET=... strava-oauth-token
|
|
|
1058
1077
|
|
|
1059
1078
|
* [Slava: Strava integration with Slack](https://slava.playplay.io), [source](https://github.com/dblock/slack-strava).
|
|
1060
1079
|
* [Jekyll Blog at run.dblock.org](https://run.dblock.org), [source](https://github.com/dblock/run.dblock.org)
|
|
1080
|
+
* [Secret Strava](https://steele.blue/secret-strava/), [source](https://github.com/mattdsteele/secret-strava)
|
|
1061
1081
|
|
|
1062
1082
|
## Resources
|
|
1063
1083
|
|
data/bin/strava-oauth-token
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
require 'dotenv/load'
|
|
4
5
|
require 'strava-ruby-client'
|
|
@@ -38,7 +39,7 @@ end
|
|
|
38
39
|
redirect_url = client.authorize_url(
|
|
39
40
|
redirect_uri: 'http://localhost:4242/',
|
|
40
41
|
response_type: 'code',
|
|
41
|
-
scope: 'read_all,activity:read_all,profile:read_all,profile:write,activity:write'
|
|
42
|
+
scope: 'read_all,activity:read,activity:read_all,profile:read_all,profile:write,activity:write'
|
|
42
43
|
)
|
|
43
44
|
|
|
44
45
|
server.logger.info "opening browser at #{redirect_url}\n"
|
data/bin/strava-webhooks
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
require 'dotenv/load'
|
|
4
5
|
require 'strava-ruby-client'
|
|
5
6
|
require 'webrick'
|
|
6
7
|
|
|
7
|
-
logger = ::Logger.new(
|
|
8
|
+
logger = ::Logger.new($stdout)
|
|
8
9
|
logger.level = Logger::INFO
|
|
9
10
|
|
|
10
11
|
client = Strava::Webhooks::Client.new(
|
|
@@ -14,7 +15,7 @@ client = Strava::Webhooks::Client.new(
|
|
|
14
15
|
)
|
|
15
16
|
|
|
16
17
|
case ARGV[0]
|
|
17
|
-
when 'create'
|
|
18
|
+
when 'create'
|
|
18
19
|
callback_url = ARGV[1]
|
|
19
20
|
raise 'Missing callback_url.' unless callback_url
|
|
20
21
|
|
|
@@ -37,11 +38,11 @@ when 'handle'
|
|
|
37
38
|
|
|
38
39
|
server.mount_proc '/' do |req, res|
|
|
39
40
|
case req.request_method
|
|
40
|
-
when 'GET'
|
|
41
|
+
when 'GET'
|
|
41
42
|
challenge = Strava::Webhooks::Models::Challenge.new(req.query)
|
|
42
43
|
res.content_type = 'application/json'
|
|
43
44
|
res.body = challenge.response.to_json
|
|
44
|
-
when 'POST'
|
|
45
|
+
when 'POST'
|
|
45
46
|
event = Strava::Webhooks::Models::Event.new(JSON.parse(req.body))
|
|
46
47
|
server.logger.info event
|
|
47
48
|
res.content_type = 'application/json'
|
data/lib/strava/api/client.rb
CHANGED
data/lib/strava/api/config.rb
CHANGED
data/lib/strava/api/cursor.rb
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Strava
|
|
2
4
|
module Api
|
|
3
5
|
class Cursor
|
|
4
6
|
include Enumerable
|
|
5
7
|
|
|
6
|
-
attr_reader :client
|
|
7
|
-
attr_reader :path
|
|
8
|
-
attr_reader :params
|
|
8
|
+
attr_reader :client, :path, :params
|
|
9
9
|
|
|
10
10
|
def initialize(client, path, params = {})
|
|
11
11
|
@client = client
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Strava
|
|
2
4
|
module Api
|
|
3
5
|
module Endpoints
|
|
@@ -17,6 +19,21 @@ module Strava
|
|
|
17
19
|
paginate "clubs/#{id}/activities", options, Strava::Models::Activity, &block
|
|
18
20
|
end
|
|
19
21
|
|
|
22
|
+
#
|
|
23
|
+
# List club / group events.
|
|
24
|
+
#
|
|
25
|
+
# @option options [String] :id
|
|
26
|
+
# Club id.
|
|
27
|
+
# @option options [Integer] :page
|
|
28
|
+
# Page number.
|
|
29
|
+
# @option options [Integer] :per_page
|
|
30
|
+
# Number of items per page. Defaults to 30.
|
|
31
|
+
#
|
|
32
|
+
def club_events(id_or_options, options = {}, &block)
|
|
33
|
+
id, options = parse_args(id_or_options, options)
|
|
34
|
+
paginate "clubs/#{id}/group_events", options, Strava::Models::ClubEvent, &block
|
|
35
|
+
end
|
|
36
|
+
|
|
20
37
|
#
|
|
21
38
|
# List club administrators.
|
|
22
39
|
#
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Strava
|
|
2
4
|
module Api
|
|
3
5
|
module Endpoints
|
|
@@ -16,7 +18,7 @@ module Strava
|
|
|
16
18
|
id, options = parse_args(id_or_options, options)
|
|
17
19
|
query = options.dup
|
|
18
20
|
query[:key_by_type] = true unless options.key?(:key_by_type)
|
|
19
|
-
query[:keys] = options[:keys].join(',') if options[:keys]
|
|
21
|
+
query[:keys] = options[:keys].join(',') if options[:keys].is_a?(Array)
|
|
20
22
|
Strava::Models::StreamSet.new(get("activities/#{id}/streams", query))
|
|
21
23
|
end
|
|
22
24
|
|
|
@@ -34,7 +36,7 @@ module Strava
|
|
|
34
36
|
id, options = parse_args(id_or_options, options)
|
|
35
37
|
query = options.dup
|
|
36
38
|
query[:key_by_type] = true unless options.key?(:key_by_type)
|
|
37
|
-
query[:keys] = options[:keys].join(',') if options[:keys]
|
|
39
|
+
query[:keys] = options[:keys].join(',') if options[:keys].is_a?(Array)
|
|
38
40
|
Strava::Models::StreamSet.new(get("segment_efforts/#{id}/streams", query))
|
|
39
41
|
end
|
|
40
42
|
|
|
@@ -52,7 +54,7 @@ module Strava
|
|
|
52
54
|
id, options = parse_args(id_or_options, options)
|
|
53
55
|
query = options.dup
|
|
54
56
|
query[:key_by_type] = true unless options.key?(:key_by_type)
|
|
55
|
-
query[:keys] = options[:keys].join(',') if options[:keys]
|
|
57
|
+
query[:keys] = options[:keys].join(',') if options[:keys].is_a?(Array)
|
|
56
58
|
Strava::Models::StreamSet.new(get("segments/#{id}/streams", query))
|
|
57
59
|
end
|
|
58
60
|
end
|
data/lib/strava/errors/fault.rb
CHANGED
data/lib/strava/logger.rb
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Strava
|
|
2
4
|
module Models
|
|
3
5
|
class Activity < Model
|
|
4
|
-
include Mixins::Distance
|
|
5
6
|
include Mixins::Time
|
|
7
|
+
include Mixins::Distance
|
|
6
8
|
include Mixins::Elevation
|
|
9
|
+
include Mixins::StartDateLocal
|
|
7
10
|
|
|
8
11
|
property 'id'
|
|
9
12
|
property 'resource_state'
|
|
@@ -16,7 +19,6 @@ module Strava
|
|
|
16
19
|
property 'external_id'
|
|
17
20
|
property 'upload_id'
|
|
18
21
|
property 'start_date', transform_with: ->(v) { Time.parse(v) }
|
|
19
|
-
property 'start_date_local', transform_with: ->(v) { Time.parse(v) }
|
|
20
22
|
property 'timezone'
|
|
21
23
|
property 'utc_offset'
|
|
22
24
|
property 'start_latlng'
|
|
@@ -99,15 +101,14 @@ module Strava
|
|
|
99
101
|
|
|
100
102
|
def type_emoji
|
|
101
103
|
case type
|
|
102
|
-
when 'Run' then '🏃'
|
|
103
|
-
when 'Ride' then '🚴'
|
|
104
|
+
when 'Run', 'VirtualRun' then '🏃'
|
|
105
|
+
when 'Ride', 'EBikeRide', 'VirtualRide' then '🚴'
|
|
104
106
|
when 'Swim' then '🏊'
|
|
105
107
|
when 'Walk' then '🚶'
|
|
106
108
|
when 'AlpineSki' then '⛷️'
|
|
107
109
|
when 'BackcountrySki' then '🎿️'
|
|
108
110
|
# when 'Canoeing' then ''
|
|
109
111
|
# when 'Crossfit' then ''
|
|
110
|
-
when 'EBikeRide' then '🚴'
|
|
111
112
|
# when 'Elliptical' then ''
|
|
112
113
|
# when 'Hike' then ''
|
|
113
114
|
when 'IceSkate' then '⛸️'
|
|
@@ -123,8 +124,6 @@ module Strava
|
|
|
123
124
|
# when 'StairStepper' then ''
|
|
124
125
|
# when 'StandUpPaddling' then ''
|
|
125
126
|
when 'Surfing' then '🏄'
|
|
126
|
-
when 'VirtualRide' then '🚴'
|
|
127
|
-
when 'VirtualRun' then '🏃'
|
|
128
127
|
when 'WeightTraining' then '🏋️'
|
|
129
128
|
# when 'Windsurf' then ''
|
|
130
129
|
when 'Wheelchair' then '♿'
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Strava
|
|
2
4
|
module Models
|
|
3
5
|
class Athlete < Model
|
|
@@ -27,6 +29,7 @@ module Strava
|
|
|
27
29
|
property 'date_preference'
|
|
28
30
|
property 'measurement_preference'
|
|
29
31
|
property 'clubs', transform_with: ->(v) { v.map { |r| Strava::Models::Club.new(r) } }
|
|
32
|
+
property 'ftp'
|
|
30
33
|
property 'weight'
|
|
31
34
|
property 'bikes', transform_with: ->(v) { v.map { |r| Strava::Models::Gear.new(r) } }
|
|
32
35
|
property 'shoes', transform_with: ->(v) { v.map { |r| Strava::Models::Gear.new(r) } }
|
data/lib/strava/models/club.rb
CHANGED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Strava
|
|
4
|
+
module Models
|
|
5
|
+
class ClubEvent < Model
|
|
6
|
+
property 'id'
|
|
7
|
+
property 'resource_state'
|
|
8
|
+
property 'title'
|
|
9
|
+
property 'club_id'
|
|
10
|
+
property 'club', transform_with: ->(c) { Strava::Models::Club.new(c) }
|
|
11
|
+
property 'organizing_athlete', transform_with: ->(oa) { Strava::Models::Athlete.new(oa) }
|
|
12
|
+
property 'activity_type'
|
|
13
|
+
property 'created_at', transform_with: ->(v) { Time.parse(v) }
|
|
14
|
+
property 'route_id'
|
|
15
|
+
property 'route', transform_with: ->(r) { Strava::Models::Route.new(r) }
|
|
16
|
+
property 'women_only'
|
|
17
|
+
property 'private'
|
|
18
|
+
property 'skill_levels'
|
|
19
|
+
property 'terrain'
|
|
20
|
+
property 'upcoming_occurrences', transform_with: ->(upcoming) { upcoming.map { |o| Time.parse(o) } }
|
|
21
|
+
property 'zone'
|
|
22
|
+
property 'address'
|
|
23
|
+
property 'start_latlng'
|
|
24
|
+
|
|
25
|
+
def strava_url
|
|
26
|
+
"https://www.strava.com/clubs/#{club_id}/group_events/#{id}"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/lib/strava/models/gear.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Strava
|
|
2
4
|
module Models
|
|
3
5
|
class Gear < Model
|
|
@@ -11,6 +13,9 @@ module Strava
|
|
|
11
13
|
property 'brand_name'
|
|
12
14
|
property 'model_name'
|
|
13
15
|
property 'description'
|
|
16
|
+
property 'frame_type'
|
|
17
|
+
property 'weight'
|
|
18
|
+
property 'retired'
|
|
14
19
|
end
|
|
15
20
|
end
|
|
16
21
|
end
|
data/lib/strava/models/lap.rb
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Strava
|
|
2
4
|
module Models
|
|
3
5
|
class Lap < Model
|
|
4
6
|
include Mixins::Time
|
|
5
7
|
include Mixins::Distance
|
|
6
8
|
include Mixins::Elevation
|
|
9
|
+
include Mixins::StartDateLocal
|
|
7
10
|
|
|
8
11
|
property 'id'
|
|
9
12
|
property 'resource_state'
|
|
@@ -11,7 +14,6 @@ module Strava
|
|
|
11
14
|
property 'activity', transform_with: ->(v) { Strava::Models::Activity.new(v) }
|
|
12
15
|
property 'athlete', transform_with: ->(v) { Strava::Models::Athlete.new(v) }
|
|
13
16
|
property 'start_date', transform_with: ->(v) { Time.parse(v) }
|
|
14
|
-
property 'start_date_local', transform_with: ->(v) { Time.parse(v) }
|
|
15
17
|
property 'start_index'
|
|
16
18
|
property 'end_index'
|
|
17
19
|
property 'average_speed'
|
data/lib/strava/models/map.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Strava
|
|
2
4
|
module Models
|
|
3
5
|
module Mixins
|
|
@@ -21,7 +23,7 @@ module Strava
|
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def distance_in_miles_s
|
|
24
|
-
return unless distance
|
|
26
|
+
return unless distance&.positive?
|
|
25
27
|
|
|
26
28
|
format('%gmi', format('%.2f', distance_in_miles))
|
|
27
29
|
end
|
|
@@ -31,13 +33,13 @@ module Strava
|
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
def distance_in_yards_s
|
|
34
|
-
return unless distance
|
|
36
|
+
return unless distance&.positive?
|
|
35
37
|
|
|
36
38
|
format('%gyd', format('%.1f', distance_in_yards))
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
def distance_in_meters_s
|
|
40
|
-
return unless distance
|
|
42
|
+
return unless distance&.positive?
|
|
41
43
|
|
|
42
44
|
format('%gm', format('%d', distance_in_meters))
|
|
43
45
|
end
|
|
@@ -47,7 +49,7 @@ module Strava
|
|
|
47
49
|
end
|
|
48
50
|
|
|
49
51
|
def distance_in_kilometers_s
|
|
50
|
-
return unless distance
|
|
52
|
+
return unless distance&.positive?
|
|
51
53
|
|
|
52
54
|
format('%gkm', format('%.2f', distance_in_kilometers))
|
|
53
55
|
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Strava
|
|
4
|
+
module Models
|
|
5
|
+
module Mixins
|
|
6
|
+
module StartDateLocal
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
property 'start_date_local', transform_with: ->(v) { ::Time.parse(v) }
|
|
11
|
+
|
|
12
|
+
def start_date_local
|
|
13
|
+
extracted_datetime = self['start_date_local']
|
|
14
|
+
# some strava object do not contain a timezone property i.e. `Lap`
|
|
15
|
+
timezone_shift = conditional_timezone(extracted_datetime)
|
|
16
|
+
::Time.new(extracted_datetime.year,
|
|
17
|
+
extracted_datetime.month,
|
|
18
|
+
extracted_datetime.day,
|
|
19
|
+
extracted_datetime.hour,
|
|
20
|
+
extracted_datetime.min,
|
|
21
|
+
extracted_datetime.sec,
|
|
22
|
+
timezone_shift)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def conditional_timezone(extracted_datetime)
|
|
28
|
+
if key?(:timezone)
|
|
29
|
+
if timezone.include?('+')
|
|
30
|
+
timezone_shift_string('+')
|
|
31
|
+
elsif timezone.include?('-')
|
|
32
|
+
timezone_shift_string('-')
|
|
33
|
+
else
|
|
34
|
+
raise ArgumentError 'No operator of timezone correction detectable!'
|
|
35
|
+
end
|
|
36
|
+
else
|
|
37
|
+
calculate_timezone(extracted_datetime)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def calculate_timezone(extracted_datetime)
|
|
42
|
+
if start_date == extracted_datetime
|
|
43
|
+
timezone_diff_shift_string(0, '-')
|
|
44
|
+
elsif extracted_datetime < start_date
|
|
45
|
+
timezone_diff_shift_string((extracted_datetime - start_date), '-')
|
|
46
|
+
elsif extracted_datetime > start_date
|
|
47
|
+
timezone_diff_shift_string((extracted_datetime - start_date), '+')
|
|
48
|
+
else
|
|
49
|
+
raise ArgumentError 'No operator of timezone correction detectable!'
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def timezone_shift_string(operator)
|
|
54
|
+
diff_hours = timezone.split(operator).last.to_i
|
|
55
|
+
"#{operator}#{format_int_leading_zero(diff_hours)}:00"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def timezone_diff_shift_string(time_diff, operator)
|
|
59
|
+
diff_hours = (time_diff.abs / 3600).to_i
|
|
60
|
+
"#{operator}#{format_int_leading_zero(diff_hours)}:00"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def format_int_leading_zero(int)
|
|
64
|
+
format('%02d', int)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Strava
|
|
2
4
|
module Models
|
|
3
5
|
module Mixins
|
|
@@ -28,11 +30,11 @@ module Strava
|
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
def pace_per_100_yards_s
|
|
31
|
-
convert_meters_per_second_to_pace average_speed, :
|
|
33
|
+
convert_meters_per_second_to_pace average_speed, :'100yd'
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
def pace_per_100_meters_s
|
|
35
|
-
convert_meters_per_second_to_pace average_speed, :
|
|
37
|
+
convert_meters_per_second_to_pace average_speed, :'100m'
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
def pace_per_kilometer_s
|
|
@@ -40,13 +42,13 @@ module Strava
|
|
|
40
42
|
end
|
|
41
43
|
|
|
42
44
|
def kilometer_per_hour_s
|
|
43
|
-
return unless average_speed
|
|
45
|
+
return unless average_speed&.positive?
|
|
44
46
|
|
|
45
47
|
format('%.1fkm/h', average_speed * 3.6)
|
|
46
48
|
end
|
|
47
49
|
|
|
48
50
|
def miles_per_hour_s
|
|
49
|
-
return unless average_speed
|
|
51
|
+
return unless average_speed&.positive?
|
|
50
52
|
|
|
51
53
|
format('%.1fmph', average_speed * 2.23694)
|
|
52
54
|
end
|
|
@@ -73,13 +75,13 @@ module Strava
|
|
|
73
75
|
# Convert speed (m/s) to pace (min/mile or min/km) in the format of 'x:xx'
|
|
74
76
|
# http://yizeng.me/2017/02/25/convert-speed-to-pace-programmatically-using-ruby
|
|
75
77
|
def convert_meters_per_second_to_pace(speed, unit = :mi)
|
|
76
|
-
return unless speed
|
|
78
|
+
return unless speed&.positive?
|
|
77
79
|
|
|
78
80
|
total_seconds = case unit
|
|
79
81
|
when :mi then 1609.344 / speed
|
|
80
82
|
when :km then 1000 / speed
|
|
81
|
-
when :
|
|
82
|
-
when :
|
|
83
|
+
when :'100yd' then 91.44 / speed
|
|
84
|
+
when :'100m' then 100 / speed
|
|
83
85
|
end
|
|
84
86
|
minutes, seconds = total_seconds.divmod(60)
|
|
85
87
|
seconds = seconds.round
|
data/lib/strava/models/model.rb
CHANGED
data/lib/strava/models/photo.rb
CHANGED
data/lib/strava/models/photos.rb
CHANGED
data/lib/strava/models/route.rb
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Strava
|
|
2
4
|
module Models
|
|
3
5
|
class SegmentEffort < Model
|
|
4
6
|
include Mixins::Distance
|
|
5
7
|
include Mixins::Time
|
|
8
|
+
include Mixins::StartDateLocal
|
|
6
9
|
|
|
7
10
|
property 'id'
|
|
8
11
|
property 'resource_state'
|
|
@@ -10,7 +13,6 @@ module Strava
|
|
|
10
13
|
property 'activity', transform_with: ->(v) { Strava::Models::Activity.new(v) }
|
|
11
14
|
property 'athlete', transform_with: ->(v) { Strava::Models::Athlete.new(v) }
|
|
12
15
|
property 'start_date', transform_with: ->(v) { Time.parse(v) }
|
|
13
|
-
property 'start_date_local', transform_with: ->(v) { Time.parse(v) }
|
|
14
16
|
property 'start_index'
|
|
15
17
|
property 'end_index'
|
|
16
18
|
property 'average_heartrate'
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Strava
|
|
2
4
|
module Models
|
|
3
5
|
class SegmentLeaderboardEntry < Model
|
|
4
6
|
include Mixins::Time
|
|
7
|
+
include Mixins::StartDateLocal
|
|
5
8
|
|
|
6
9
|
property 'athlete_name'
|
|
7
10
|
property 'start_date', transform_with: ->(v) { Time.parse(v) }
|
|
8
|
-
property 'start_date_local', transform_with: ->(v) { Time.parse(v) }
|
|
9
11
|
property 'rank'
|
|
10
12
|
end
|
|
11
13
|
end
|
data/lib/strava/models/split.rb
CHANGED
data/lib/strava/models/stream.rb
CHANGED
data/lib/strava/models/token.rb
CHANGED
data/lib/strava/models/trend.rb
CHANGED
data/lib/strava/models/upload.rb
CHANGED
data/lib/strava/models/zones.rb
CHANGED
data/lib/strava/oauth/client.rb
CHANGED
data/lib/strava/oauth/config.rb
CHANGED
data/lib/strava/version.rb
CHANGED
data/lib/strava/web/client.rb
CHANGED
data/lib/strava/web/config.rb
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Strava
|
|
2
4
|
module Web
|
|
3
5
|
module Response
|
|
4
6
|
class RaiseError < ::Faraday::Response::Middleware
|
|
5
|
-
|
|
7
|
+
CLIENT_ERROR_STATUSES = (400...600).freeze
|
|
6
8
|
|
|
7
9
|
def on_complete(env)
|
|
8
10
|
case env[:status]
|
|
@@ -11,7 +13,7 @@ module Strava
|
|
|
11
13
|
when 407
|
|
12
14
|
# mimic the behavior that we get with proxy requests with HTTPS
|
|
13
15
|
raise Faraday::ConnectionFailed, %(407 "Proxy Authentication Required ")
|
|
14
|
-
when
|
|
16
|
+
when CLIENT_ERROR_STATUSES
|
|
15
17
|
raise Strava::Errors::Fault, response_values(env)
|
|
16
18
|
end
|
|
17
19
|
end
|
data/lib/strava/web/request.rb
CHANGED
data/lib/strava-ruby-client.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'faraday'
|
|
2
4
|
require 'faraday_middleware'
|
|
3
5
|
require 'json'
|
|
@@ -5,6 +7,7 @@ require 'logger'
|
|
|
5
7
|
require 'hashie'
|
|
6
8
|
require 'time'
|
|
7
9
|
|
|
10
|
+
require 'active_support'
|
|
8
11
|
require 'active_support/core_ext/object/to_query'
|
|
9
12
|
require 'active_support/core_ext/hash'
|
|
10
13
|
require 'active_support/concern'
|
|
@@ -17,6 +20,7 @@ require_relative 'strava/errors/fault'
|
|
|
17
20
|
require_relative 'strava/models/mixins/distance'
|
|
18
21
|
require_relative 'strava/models/mixins/elevation'
|
|
19
22
|
require_relative 'strava/models/mixins/time'
|
|
23
|
+
require_relative 'strava/models/mixins/start_date_local'
|
|
20
24
|
|
|
21
25
|
require_relative 'strava/models/model'
|
|
22
26
|
require_relative 'strava/models/token'
|
|
@@ -25,6 +29,7 @@ require_relative 'strava/models/map'
|
|
|
25
29
|
require_relative 'strava/models/activity'
|
|
26
30
|
require_relative 'strava/models/club'
|
|
27
31
|
require_relative 'strava/models/club_admin'
|
|
32
|
+
require_relative 'strava/models/club_event'
|
|
28
33
|
require_relative 'strava/models/club_member'
|
|
29
34
|
require_relative 'strava/models/segment_effort'
|
|
30
35
|
require_relative 'strava/models/photos'
|
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.
|
|
4
|
+
version: 0.4.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel Doubrovkine
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-03-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -66,7 +66,7 @@ dependencies:
|
|
|
66
66
|
- - ">="
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '0'
|
|
69
|
-
description:
|
|
69
|
+
description:
|
|
70
70
|
email: dblock@dblock.org
|
|
71
71
|
executables:
|
|
72
72
|
- strava-oauth-token
|
|
@@ -105,6 +105,7 @@ files:
|
|
|
105
105
|
- lib/strava/models/authorization.rb
|
|
106
106
|
- lib/strava/models/club.rb
|
|
107
107
|
- lib/strava/models/club_admin.rb
|
|
108
|
+
- lib/strava/models/club_event.rb
|
|
108
109
|
- lib/strava/models/club_member.rb
|
|
109
110
|
- lib/strava/models/comment.rb
|
|
110
111
|
- lib/strava/models/explorer_segment.rb
|
|
@@ -115,6 +116,7 @@ files:
|
|
|
115
116
|
- lib/strava/models/map.rb
|
|
116
117
|
- lib/strava/models/mixins/distance.rb
|
|
117
118
|
- lib/strava/models/mixins/elevation.rb
|
|
119
|
+
- lib/strava/models/mixins/start_date_local.rb
|
|
118
120
|
- lib/strava/models/mixins/time.rb
|
|
119
121
|
- lib/strava/models/model.rb
|
|
120
122
|
- lib/strava/models/photo.rb
|
|
@@ -153,8 +155,9 @@ files:
|
|
|
153
155
|
homepage: http://github.com/dblock/strava-ruby-client
|
|
154
156
|
licenses:
|
|
155
157
|
- MIT
|
|
156
|
-
metadata:
|
|
157
|
-
|
|
158
|
+
metadata:
|
|
159
|
+
rubygems_mfa_required: 'true'
|
|
160
|
+
post_install_message:
|
|
158
161
|
rdoc_options: []
|
|
159
162
|
require_paths:
|
|
160
163
|
- lib
|
|
@@ -162,15 +165,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
162
165
|
requirements:
|
|
163
166
|
- - ">="
|
|
164
167
|
- !ruby/object:Gem::Version
|
|
165
|
-
version: '
|
|
168
|
+
version: '2.5'
|
|
166
169
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
170
|
requirements:
|
|
168
171
|
- - ">="
|
|
169
172
|
- !ruby/object:Gem::Version
|
|
170
173
|
version: 1.3.6
|
|
171
174
|
requirements: []
|
|
172
|
-
rubygems_version: 3.
|
|
173
|
-
signing_key:
|
|
175
|
+
rubygems_version: 3.1.3
|
|
176
|
+
signing_key:
|
|
174
177
|
specification_version: 4
|
|
175
178
|
summary: Strava API Ruby client.
|
|
176
179
|
test_files: []
|