strava-ruby-client 0.2.0 → 0.3.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 +14 -0
- data/README.md +710 -88
- data/bin/strava-webhooks.rb +56 -0
- data/lib/strava-ruby-client.rb +37 -0
- data/lib/strava/api/client.rb +11 -141
- data/lib/strava/api/endpoints/activities.rb +120 -0
- data/lib/strava/api/endpoints/athletes.rb +42 -0
- data/lib/strava/api/endpoints/clubs.rb +75 -0
- data/lib/strava/api/endpoints/gears.rb +18 -0
- data/lib/strava/api/endpoints/routes.rb +55 -0
- data/lib/strava/api/endpoints/running_races.rb +30 -0
- data/lib/strava/api/endpoints/segment_efforts.rb +33 -0
- data/lib/strava/api/endpoints/segments.rb +111 -0
- data/lib/strava/api/endpoints/streams.rb +61 -0
- data/lib/strava/api/endpoints/uploads.rb +40 -0
- data/lib/strava/logger.rb +1 -1
- data/lib/strava/models/achievement.rb +9 -0
- data/lib/strava/models/activity.rb +11 -5
- data/lib/strava/models/activity_stats.rb +17 -0
- data/lib/strava/models/activity_total.rb +17 -0
- data/lib/strava/models/athlete.rb +10 -0
- data/lib/strava/models/club.rb +6 -0
- data/lib/strava/models/club_admin.rb +13 -0
- data/lib/strava/models/club_member.rb +16 -0
- data/lib/strava/models/explorer_segment.rb +19 -0
- data/lib/strava/models/gear.rb +5 -0
- data/lib/strava/models/heart_rate_zone_ranges.rb +8 -0
- data/lib/strava/models/kudoser.rb +10 -0
- data/lib/strava/models/lap.rb +3 -0
- data/lib/strava/models/mixins/distance.rb +18 -0
- data/lib/strava/models/power_zone_ranges.rb +7 -0
- data/lib/strava/models/route.rb +27 -0
- data/lib/strava/models/running_race.rb +33 -0
- data/lib/strava/models/segment.rb +15 -3
- data/lib/strava/models/segment_effort.rb +7 -2
- data/lib/strava/models/segment_leaderboard.rb +10 -0
- data/lib/strava/models/segment_leaderboard_entry.rb +12 -0
- data/lib/strava/models/segment_stats.rb +15 -0
- data/lib/strava/models/stream.rb +10 -0
- data/lib/strava/models/stream_set.rb +17 -0
- data/lib/strava/models/upload.rb +11 -0
- data/lib/strava/models/zone_range.rb +8 -0
- data/lib/strava/models/zones.rb +8 -0
- data/lib/strava/version.rb +1 -1
- data/lib/strava/web/client.rb +11 -1
- data/lib/strava/web/connection.rb +1 -1
- data/lib/strava/webhooks/client.rb +58 -0
- data/lib/strava/webhooks/config.rb +33 -0
- data/lib/strava/webhooks/models/challenge.rb +15 -0
- data/lib/strava/webhooks/models/event.rb +15 -0
- data/lib/strava/webhooks/models/subscription.rb +14 -0
- metadata +37 -2
data/lib/strava/models/club.rb
CHANGED
@@ -17,6 +17,12 @@ module Strava
|
|
17
17
|
property 'featured'
|
18
18
|
property 'verified'
|
19
19
|
property 'url'
|
20
|
+
property 'membership'
|
21
|
+
property 'admin'
|
22
|
+
property 'owner'
|
23
|
+
property 'description'
|
24
|
+
property 'club_type'
|
25
|
+
property 'following_count'
|
20
26
|
|
21
27
|
def strava_url
|
22
28
|
"https://www.strava.com/clubs/#{url || id}"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Strava
|
2
|
+
module Models
|
3
|
+
class ClubMember < Model
|
4
|
+
property 'resource_state'
|
5
|
+
property 'firstname'
|
6
|
+
property 'lastname'
|
7
|
+
property 'owner'
|
8
|
+
property 'admin'
|
9
|
+
property 'membership'
|
10
|
+
|
11
|
+
def name
|
12
|
+
[firstname, lastname].compact.join(' ') if firstname || lastname
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Strava
|
2
|
+
module Models
|
3
|
+
class ExplorerSegment < Model
|
4
|
+
include Mixins::MetricDistance
|
5
|
+
|
6
|
+
property 'id'
|
7
|
+
property 'resource_state'
|
8
|
+
property 'name'
|
9
|
+
property 'climb_category'
|
10
|
+
property 'climb_category_desc'
|
11
|
+
property 'avg_grade'
|
12
|
+
property 'start_latlng'
|
13
|
+
property 'end_latlng'
|
14
|
+
property 'elev_difference'
|
15
|
+
property 'points'
|
16
|
+
property 'starred'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/strava/models/gear.rb
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
module Strava
|
2
2
|
module Models
|
3
3
|
class Gear < Model
|
4
|
+
include Mixins::MetricDistance
|
5
|
+
|
4
6
|
property 'id'
|
5
7
|
property 'resource_state'
|
6
8
|
property 'distance'
|
7
9
|
property 'name'
|
8
10
|
property 'primary'
|
11
|
+
property 'brand_name'
|
12
|
+
property 'model_name'
|
13
|
+
property 'description'
|
9
14
|
end
|
10
15
|
end
|
11
16
|
end
|
data/lib/strava/models/lap.rb
CHANGED
@@ -68,6 +68,24 @@ module Strava
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
end
|
71
|
+
|
72
|
+
module MetricDistance
|
73
|
+
extend ActiveSupport::Concern
|
74
|
+
include Strava::Models::Mixins::Distance
|
75
|
+
|
76
|
+
def units
|
77
|
+
:metric
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
module ImperialDistance
|
82
|
+
extend ActiveSupport::Concern
|
83
|
+
include Strava::Models::Mixins::Distance
|
84
|
+
|
85
|
+
def units
|
86
|
+
:imperial
|
87
|
+
end
|
88
|
+
end
|
71
89
|
end
|
72
90
|
end
|
73
91
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Strava
|
2
|
+
module Models
|
3
|
+
class Route < Model
|
4
|
+
include Mixins::MetricDistance
|
5
|
+
include Mixins::Elevation
|
6
|
+
include Mixins::Time
|
7
|
+
|
8
|
+
property 'id'
|
9
|
+
property 'athlete', transform_with: ->(v) { Strava::Models::Athlete.new(v) }
|
10
|
+
property 'name'
|
11
|
+
property 'description'
|
12
|
+
property 'total_elevation_gain', from: 'elevation_gain'
|
13
|
+
property 'map', transform_with: ->(v) { Strava::Models::Map.new(v) }
|
14
|
+
property 'private'
|
15
|
+
property 'resource_state'
|
16
|
+
property 'starred'
|
17
|
+
property 'sub_type'
|
18
|
+
property 'timestamp', transform_with: ->(v) { Time.at(v) }
|
19
|
+
property 'created_at', transform_with: ->(v) { Time.parse(v) }
|
20
|
+
property 'updated_at', transform_with: ->(v) { Time.parse(v) }
|
21
|
+
property 'type'
|
22
|
+
property 'estimated_moving_time'
|
23
|
+
property 'moving_time', from: 'estimated_moving_time'
|
24
|
+
property 'segments', transform_with: ->(v) { v.map { |r| Strava::Models::Segment.new(r) } }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Strava
|
2
|
+
module Models
|
3
|
+
class RunningRace < Model
|
4
|
+
include Mixins::MetricDistance
|
5
|
+
|
6
|
+
property 'id'
|
7
|
+
property 'resource_state'
|
8
|
+
property 'name'
|
9
|
+
property 'running_race_type'
|
10
|
+
property 'distance'
|
11
|
+
property 'start_date_local', transform_with: ->(v) { Time.parse(v) }
|
12
|
+
property 'city'
|
13
|
+
property 'state'
|
14
|
+
property 'country'
|
15
|
+
property 'route_ids'
|
16
|
+
property 'measurement_preference'
|
17
|
+
property 'url'
|
18
|
+
property 'website_url'
|
19
|
+
property 'status'
|
20
|
+
|
21
|
+
def strava_url
|
22
|
+
"https://www.strava.com/running-races/#{url}" if url
|
23
|
+
end
|
24
|
+
|
25
|
+
def distance_s
|
26
|
+
case measurement_preference
|
27
|
+
when 'meters' then distance_in_kilometers_s
|
28
|
+
when 'feet' then distance_in_miles_s
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
module Strava
|
2
2
|
module Models
|
3
3
|
class Segment < Model
|
4
|
-
include Mixins::
|
4
|
+
include Mixins::MetricDistance
|
5
|
+
include Mixins::Elevation
|
6
|
+
include Mixins::Time
|
5
7
|
|
6
8
|
property 'id'
|
7
9
|
property 'resource_state'
|
@@ -24,9 +26,19 @@ module Strava
|
|
24
26
|
property 'private'
|
25
27
|
property 'hazardous'
|
26
28
|
property 'starred'
|
29
|
+
property 'created_at', transform_with: ->(v) { Time.parse(v) }
|
30
|
+
property 'updated_at', transform_with: ->(v) { Time.parse(v) }
|
31
|
+
property 'map', transform_with: ->(v) { Strava::Models::Map.new(v) }
|
32
|
+
property 'effort_count'
|
33
|
+
property 'athlete_count'
|
34
|
+
property 'star_count'
|
35
|
+
property 'athlete_segment_stats', transform_with: ->(v) { Strava::Models::SegmentStats.new(v) }
|
36
|
+
property 'pr_time'
|
37
|
+
property 'athlete_pr_effort', transform_with: ->(v) { Strava::Models::SegmentEffort.new(v) }
|
38
|
+
property 'starred_date', transform_with: ->(v) { Time.parse(v) }
|
27
39
|
|
28
|
-
def
|
29
|
-
|
40
|
+
def elapsed_time
|
41
|
+
pr_time
|
30
42
|
end
|
31
43
|
end
|
32
44
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Strava
|
2
2
|
module Models
|
3
3
|
class SegmentEffort < Model
|
4
|
+
include Mixins::MetricDistance
|
4
5
|
include Mixins::Time
|
5
6
|
|
6
7
|
property 'id'
|
@@ -10,15 +11,19 @@ module Strava
|
|
10
11
|
property 'athlete', transform_with: ->(v) { Strava::Models::Athlete.new(v) }
|
11
12
|
property 'start_date', transform_with: ->(v) { Time.parse(v) }
|
12
13
|
property 'start_date_local', transform_with: ->(v) { Time.parse(v) }
|
13
|
-
property 'distance'
|
14
14
|
property 'start_index'
|
15
15
|
property 'end_index'
|
16
16
|
property 'average_heartrate'
|
17
17
|
property 'max_heartrate'
|
18
18
|
property 'segment', transform_with: ->(v) { Strava::Models::Segment.new(v) }
|
19
|
-
property 'achievements'
|
19
|
+
property 'achievements', transform_with: ->(v) { v.map { |r| Strava::Models::Achievement.new(r) } }
|
20
20
|
property 'hidden'
|
21
21
|
property 'pr_rank'
|
22
|
+
property 'average_cadence'
|
23
|
+
property 'device_watts'
|
24
|
+
property 'average_watts'
|
25
|
+
property 'athlete_segment_stats', transform_with: ->(v) { Strava::Models::SegmentStats.new(v) }
|
26
|
+
property 'is_kom'
|
22
27
|
end
|
23
28
|
end
|
24
29
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Strava
|
2
|
+
module Models
|
3
|
+
class SegmentLeaderboardEntry < Model
|
4
|
+
include Mixins::Time
|
5
|
+
|
6
|
+
property 'athlete_name'
|
7
|
+
property 'start_date', transform_with: ->(v) { Time.parse(v) }
|
8
|
+
property 'start_date_local', transform_with: ->(v) { Time.parse(v) }
|
9
|
+
property 'rank'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Strava
|
2
|
+
module Models
|
3
|
+
class SegmentStats < Model
|
4
|
+
include Mixins::Time
|
5
|
+
|
6
|
+
property 'pr_elapsed_time'
|
7
|
+
property 'pr_date', transform_with: ->(v) { Date.parse(v) }
|
8
|
+
property 'effort_count'
|
9
|
+
|
10
|
+
def elapsed_time
|
11
|
+
pr_elapsed_time
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Strava
|
2
|
+
module Models
|
3
|
+
class StreamSet < Model
|
4
|
+
property 'distance', transform_with: ->(v) { Strava::Models::Stream.new(v) }
|
5
|
+
property 'time', transform_with: ->(v) { Strava::Models::Stream.new(v) }
|
6
|
+
property 'latlng', transform_with: ->(v) { Strava::Models::Stream.new(v) }
|
7
|
+
property 'altitude', transform_with: ->(v) { Strava::Models::Stream.new(v) }
|
8
|
+
property 'velocity_smooth', transform_with: ->(v) { Strava::Models::Stream.new(v) }
|
9
|
+
property 'heartrate', transform_with: ->(v) { Strava::Models::Stream.new(v) }
|
10
|
+
property 'cadence', transform_with: ->(v) { Strava::Models::Stream.new(v) }
|
11
|
+
property 'watts', transform_with: ->(v) { Strava::Models::Stream.new(v) }
|
12
|
+
property 'temp', transform_with: ->(v) { Strava::Models::Stream.new(v) }
|
13
|
+
property 'moving', transform_with: ->(v) { Strava::Models::Stream.new(v) }
|
14
|
+
property 'grade_smooth', transform_with: ->(v) { Strava::Models::Stream.new(v) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/strava/version.rb
CHANGED
data/lib/strava/web/client.rb
CHANGED
@@ -10,7 +10,7 @@ module Strava
|
|
10
10
|
Strava::Web::Config::ATTRIBUTES.each do |key|
|
11
11
|
send("#{key}=", options[key] || Strava::Web.config.send(key))
|
12
12
|
end
|
13
|
-
@logger ||= Strava::Logger.
|
13
|
+
@logger ||= Strava::Logger.logger
|
14
14
|
end
|
15
15
|
|
16
16
|
def endpoint
|
@@ -26,6 +26,16 @@ module Strava
|
|
26
26
|
Config
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
def parse_args(id_or_options, options = {})
|
31
|
+
if id_or_options.is_a?(Hash)
|
32
|
+
throw ArgumentError.new('Required argument :id missing') if id_or_options[:id].nil?
|
33
|
+
[id_or_options[:id], id_or_options.except(:id)]
|
34
|
+
else
|
35
|
+
throw ArgumentError.new('Required argument :id missing') if id_or_options.nil?
|
36
|
+
[id_or_options, options]
|
37
|
+
end
|
38
|
+
end
|
29
39
|
end
|
30
40
|
end
|
31
41
|
end
|
@@ -25,7 +25,7 @@ module Strava
|
|
25
25
|
connection.use ::Faraday::Request::Multipart
|
26
26
|
connection.use ::Faraday::Request::UrlEncoded
|
27
27
|
connection.use ::Strava::Web::Response::RaiseError
|
28
|
-
connection.use ::FaradayMiddleware::ParseJson
|
28
|
+
connection.use ::FaradayMiddleware::ParseJson, content_type: /\bjson$/
|
29
29
|
connection.response :logger, logger if logger
|
30
30
|
connection.adapter ::Faraday.default_adapter
|
31
31
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Strava
|
2
|
+
module Webhooks
|
3
|
+
class Client < Strava::Web::Client
|
4
|
+
attr_accessor(*Config::ATTRIBUTES)
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
Strava::Webhooks::Config::ATTRIBUTES.each do |key|
|
8
|
+
send("#{key}=", options[key] || Strava::Webhooks.config.send(key))
|
9
|
+
end
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
def request(method, path, options)
|
14
|
+
super method, path, { client_id: client_id, client_secret: client_secret }.merge(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# Get existing push subscriptions.
|
19
|
+
#
|
20
|
+
def push_subscriptions(options = {})
|
21
|
+
get('push_subscriptions', options).map do |row|
|
22
|
+
Strava::Webhooks::Models::Subscription.new(row)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Delete an existing push subscription.
|
28
|
+
#
|
29
|
+
def delete_push_subscription(id_or_options, options = {})
|
30
|
+
id, options = parse_args(id_or_options, options)
|
31
|
+
delete("push_subscriptions/#{id}", options)
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# Create a subscription.
|
37
|
+
#
|
38
|
+
# @option options [String] :callback_url
|
39
|
+
# Address where webhook events will be sent.
|
40
|
+
# @option options [String] :verify_token
|
41
|
+
# String chosen by the application owner for client security. An identical string should be returned by Strava's subscription service.
|
42
|
+
#
|
43
|
+
def create_push_subscription(options = {})
|
44
|
+
Strava::Webhooks::Models::Subscription.new(post('push_subscriptions', options))
|
45
|
+
end
|
46
|
+
|
47
|
+
class << self
|
48
|
+
def configure
|
49
|
+
block_given? ? yield(Config) : Config
|
50
|
+
end
|
51
|
+
|
52
|
+
def config
|
53
|
+
Config
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|