strava-ruby-client 0.2.0 → 0.3.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 +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
@@ -0,0 +1,18 @@
|
|
1
|
+
module Strava
|
2
|
+
module Api
|
3
|
+
module Endpoints
|
4
|
+
module Gears
|
5
|
+
#
|
6
|
+
# Returns an equipment using its identifier.
|
7
|
+
#
|
8
|
+
# @option options [String] :id
|
9
|
+
# Gear id.
|
10
|
+
#
|
11
|
+
def gear(id_or_options, options = {})
|
12
|
+
id, options = parse_args(id_or_options, options)
|
13
|
+
Strava::Models::Gear.new(get("gear/#{id}", options))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Strava
|
2
|
+
module Api
|
3
|
+
module Endpoints
|
4
|
+
module Routes
|
5
|
+
#
|
6
|
+
# Returns a GPX file of the route.
|
7
|
+
#
|
8
|
+
# @option options [String] :id
|
9
|
+
# Route id.
|
10
|
+
#
|
11
|
+
def export_route_gpx(id_or_options, options = {})
|
12
|
+
id, options = parse_args(id_or_options, options)
|
13
|
+
get "routes/#{id}/export_gpx", options
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Returns a TCS file of the route.
|
18
|
+
#
|
19
|
+
# @option options [String] :id
|
20
|
+
# Route id.
|
21
|
+
#
|
22
|
+
def export_route_tcx(id_or_options, options = {})
|
23
|
+
id, options = parse_args(id_or_options, options)
|
24
|
+
get "routes/#{id}/export_tcx", options
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# Returns a route using its identifier.
|
29
|
+
#
|
30
|
+
# @option options [String] :id
|
31
|
+
# Route id.
|
32
|
+
#
|
33
|
+
def route(id_or_options, options = {})
|
34
|
+
id, options = parse_args(id_or_options, options)
|
35
|
+
Strava::Models::Route.new(get("routes/#{id}", options))
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# Returns a list of the routes created by the authenticated athlete using their athlete ID.
|
40
|
+
#
|
41
|
+
# @option options [Integer] :id
|
42
|
+
# The identifier of the athlete.
|
43
|
+
# @option options [Integer] :page
|
44
|
+
# Page number.
|
45
|
+
# @option options [Integer] :per_page
|
46
|
+
# Number of items per page. Defaults to 30.
|
47
|
+
#
|
48
|
+
def athlete_routes(id_or_options, options = {}, &block)
|
49
|
+
id, options = parse_args(id_or_options, options)
|
50
|
+
paginate "athletes/#{id}/routes", options, Strava::Models::Route, &block
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Strava
|
2
|
+
module Api
|
3
|
+
module Endpoints
|
4
|
+
module RunningRaces
|
5
|
+
#
|
6
|
+
# Returns a running race for a given identifier.
|
7
|
+
#
|
8
|
+
# @option options [String] :id
|
9
|
+
# The identifier of the running race.
|
10
|
+
#
|
11
|
+
def running_race(id_or_options, options = {})
|
12
|
+
id, options = parse_args(id_or_options, options)
|
13
|
+
Strava::Models::RunningRace.new(get("running_races/#{id}", options))
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Returns a list running races based on a set of search criteria.
|
18
|
+
#
|
19
|
+
# @option options [Integer] :year
|
20
|
+
# Filters the list by a given year.
|
21
|
+
#
|
22
|
+
def running_races(options = {})
|
23
|
+
get('running_races', options).map do |row|
|
24
|
+
Strava::Models::RunningRace.new(row)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Strava
|
2
|
+
module Api
|
3
|
+
module Endpoints
|
4
|
+
module SegmentEfforts
|
5
|
+
#
|
6
|
+
# Returns a segment effort from an activity that is owned by the authenticated athlete.
|
7
|
+
#
|
8
|
+
# @option options [String] :id
|
9
|
+
# The identifier of the segment effort.
|
10
|
+
#
|
11
|
+
def segment_effort(id_or_options, options = {})
|
12
|
+
id, options = parse_args(id_or_options, options)
|
13
|
+
Strava::Models::SegmentEffort.new(get("segment_efforts/#{id}", options))
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Returns a set of the authenticated athlete's segment efforts for a given segment.
|
18
|
+
#
|
19
|
+
# @option options [Integer] :id
|
20
|
+
# The identifier of the segment.
|
21
|
+
# @option options [Integer] :page
|
22
|
+
# Page number.
|
23
|
+
# @option options [Integer] :per_page
|
24
|
+
# Number of items per page. Defaults to 30.
|
25
|
+
#
|
26
|
+
def segment_efforts(id_or_options, options = {}, &block)
|
27
|
+
id, options = parse_args(id_or_options, options)
|
28
|
+
paginate "segments/#{id}/all_efforts", options, Strava::Models::SegmentEffort, &block
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Strava
|
2
|
+
module Api
|
3
|
+
module Endpoints
|
4
|
+
module Segments
|
5
|
+
#
|
6
|
+
# Returns the top 10 segments matching a specified query.
|
7
|
+
#
|
8
|
+
# @option options [Array[Float]] :bounds
|
9
|
+
# The latitude and longitude for two points describing a rectangular boundary for the search: [southwest corner latitude, southwest corner longitude, northeast corner latitude, northeast corner longitude].
|
10
|
+
# @option options [String] :activity_type
|
11
|
+
# Desired activity type. May take one of the following values: running, riding.
|
12
|
+
# @option options [Integer] :min_cat
|
13
|
+
# The minimum climbing category.
|
14
|
+
# @option options [Integer] :max_cat
|
15
|
+
# The maximum climbing category.
|
16
|
+
#
|
17
|
+
def explore_segments(options = {})
|
18
|
+
throw ArgumentError.new('Required argument :bounds missing') if options[:bounds].nil?
|
19
|
+
bounds = options[:bounds]
|
20
|
+
bounds = bounds.map(&:to_s).join(',') if bounds.is_a?(Array)
|
21
|
+
get('segments/explore', options.merge(bounds: bounds))['segments'].map do |row|
|
22
|
+
Strava::Models::ExplorerSegment.new(row)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Returns the specified segment leaderboard.
|
28
|
+
#
|
29
|
+
# @option options [Integer] :id
|
30
|
+
# The identifier of the segment leaderboard.
|
31
|
+
# @option options [String] :gender
|
32
|
+
# Filter by gender.
|
33
|
+
# @option options [String] :age_group
|
34
|
+
# Filter by age group.
|
35
|
+
# @option options [String] :weight_class
|
36
|
+
# Filter by weight class.
|
37
|
+
# @option options [Boolean] :following
|
38
|
+
# Filter by friends of the authenticated athlete.
|
39
|
+
# @option options [Integer] :club_id
|
40
|
+
# Filter by club.
|
41
|
+
# @option options [String] :date_range
|
42
|
+
# Filter by date range.
|
43
|
+
# @option options [Integer] :context_entries
|
44
|
+
# ?
|
45
|
+
# @option options [Integer] :page
|
46
|
+
# Page number.
|
47
|
+
# @option options [Integer] :per_page
|
48
|
+
# Number of items per page. Defaults to 30.
|
49
|
+
#
|
50
|
+
def segment_leaderboard(id_or_options, options = {})
|
51
|
+
id, options = parse_args(id_or_options, options)
|
52
|
+
|
53
|
+
if block_given?
|
54
|
+
next_page = 1
|
55
|
+
total_count = 0
|
56
|
+
loop do
|
57
|
+
query = options.merge(page: next_page)
|
58
|
+
response = Strava::Models::SegmentLeaderboard.new(get("segments/#{id}/leaderboard", query))
|
59
|
+
total_count += response.entries.count
|
60
|
+
break unless response.entries.any?
|
61
|
+
|
62
|
+
yield response
|
63
|
+
break if total_count >= response.entry_count
|
64
|
+
|
65
|
+
next_page += 1
|
66
|
+
end
|
67
|
+
else
|
68
|
+
Strava::Models::SegmentLeaderboard.new(get("segments/#{id}/leaderboard", options))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# List of the authenticated athlete's starred segments.
|
74
|
+
#
|
75
|
+
# @option options [Integer] :page
|
76
|
+
# Page number.
|
77
|
+
# @option options [Integer] :per_page
|
78
|
+
# Number of items per page. Defaults to 30.
|
79
|
+
#
|
80
|
+
def starred_segments(options = {}, &block)
|
81
|
+
paginate 'segments/starred', options, Strava::Models::Segment, &block
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# Returns the specified segment.
|
86
|
+
#
|
87
|
+
# @option options [String] :id
|
88
|
+
# The identifier of the segment.
|
89
|
+
#
|
90
|
+
def segment(id_or_options, options = {})
|
91
|
+
id, options = parse_args(id_or_options, options)
|
92
|
+
Strava::Models::Segment.new(get("segments/#{id}", options))
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# Stars/Unstars the given segment for the authenticated athlete.
|
97
|
+
#
|
98
|
+
# @option options [String] :id
|
99
|
+
# The identifier of the segment to star.
|
100
|
+
# @option options [Boolean] :starred
|
101
|
+
# If true, star the segment; if false, unstar the segment.
|
102
|
+
#
|
103
|
+
def star_segment(id_or_options, options = {})
|
104
|
+
id, options = parse_args(id_or_options, options)
|
105
|
+
throw ArgumentError.new('Required argument :starred missing') if options[:starred].nil?
|
106
|
+
Strava::Models::Segment.new(put("segments/#{id}/starred", options))
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Strava
|
2
|
+
module Api
|
3
|
+
module Endpoints
|
4
|
+
module Streams
|
5
|
+
#
|
6
|
+
# Returns the given activity's streams.
|
7
|
+
#
|
8
|
+
# @option options [String] :id
|
9
|
+
# The identifier of the activity.
|
10
|
+
# @option options [Array[String]] :keys
|
11
|
+
# Desired stream types.
|
12
|
+
# @option options [Boolean] :key_by_type
|
13
|
+
# Must be true.
|
14
|
+
#
|
15
|
+
def activity_streams(id_or_options, options = {})
|
16
|
+
id, options = parse_args(id_or_options, options)
|
17
|
+
query = options.dup
|
18
|
+
query[:key_by_type] = true unless options.key?(:key_by_type)
|
19
|
+
query[:keys] = options[:keys].join(',') if options[:keys] && options[:keys].is_a?(Array)
|
20
|
+
Strava::Models::StreamSet.new(get("activities/#{id}/streams", query))
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# Returns a set of streams for a segment effort completed by the authenticated athlete.
|
25
|
+
#
|
26
|
+
# @option options [String] :id
|
27
|
+
# The identifier of the segment effort.
|
28
|
+
# @option options [Array[String]] :keys
|
29
|
+
# The types of streams to return.
|
30
|
+
# @option options [Boolean] :key_by_type
|
31
|
+
# Must be true.
|
32
|
+
#
|
33
|
+
def segment_effort_streams(id_or_options, options = {})
|
34
|
+
id, options = parse_args(id_or_options, options)
|
35
|
+
query = options.dup
|
36
|
+
query[:key_by_type] = true unless options.key?(:key_by_type)
|
37
|
+
query[:keys] = options[:keys].join(',') if options[:keys] && options[:keys].is_a?(Array)
|
38
|
+
Strava::Models::StreamSet.new(get("segment_efforts/#{id}/streams", query))
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Returns the given segment's streams.
|
43
|
+
#
|
44
|
+
# @option options [String] :id
|
45
|
+
# The identifier of the segment.
|
46
|
+
# @option options [Array[String]] :keys
|
47
|
+
# The types of streams to return.
|
48
|
+
# @option options [Boolean] :key_by_type
|
49
|
+
# Must be true.
|
50
|
+
#
|
51
|
+
def segment_streams(id_or_options, options = {})
|
52
|
+
id, options = parse_args(id_or_options, options)
|
53
|
+
query = options.dup
|
54
|
+
query[:key_by_type] = true unless options.key?(:key_by_type)
|
55
|
+
query[:keys] = options[:keys].join(',') if options[:keys] && options[:keys].is_a?(Array)
|
56
|
+
Strava::Models::StreamSet.new(get("segments/#{id}/streams", query))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Strava
|
2
|
+
module Api
|
3
|
+
module Endpoints
|
4
|
+
module Uploads
|
5
|
+
#
|
6
|
+
# Uploads a new data file to create an activity from.
|
7
|
+
#
|
8
|
+
# @option options [File] :file
|
9
|
+
# The uploaded file.
|
10
|
+
# @option options [String] :name
|
11
|
+
# The desired name of the resulting activity.
|
12
|
+
# @option options [String] :description
|
13
|
+
# The desired description of the resulting activity.
|
14
|
+
# @option options [Boolean] :trainer
|
15
|
+
# Whether the resulting activity should be marked as having been performed on a trainer.
|
16
|
+
# @option options [Boolean] :commute
|
17
|
+
# Whether the resulting activity should be tagged as a commute.
|
18
|
+
# @option options [String] :data_type
|
19
|
+
# The format of the uploaded file.
|
20
|
+
# @option options [String] :external_id
|
21
|
+
# The desired external identifier of the resulting activity.
|
22
|
+
#
|
23
|
+
def create_upload(options = {})
|
24
|
+
Strava::Models::Upload.new(post('uploads', options))
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# Returns an upload for a given identifier.
|
29
|
+
#
|
30
|
+
# @option options [String] :id
|
31
|
+
# The identifier of the upload.
|
32
|
+
#
|
33
|
+
def upload(id_or_options, options = {})
|
34
|
+
id, options = parse_args(id_or_options, options)
|
35
|
+
Strava::Models::Upload.new(get("uploads/#{id}", options))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/strava/logger.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Strava
|
2
2
|
module Models
|
3
3
|
class Activity < Model
|
4
|
-
include Mixins::
|
4
|
+
include Mixins::MetricDistance
|
5
5
|
include Mixins::Time
|
6
6
|
include Mixins::Elevation
|
7
7
|
|
@@ -65,10 +65,16 @@ module Strava
|
|
65
65
|
property 'laps', transform_with: ->(v) { v.map { |r| Strava::Models::Lap.new(r) } }
|
66
66
|
property 'gear', transform_with: ->(v) { Strava::Models::Gear.new(v) }
|
67
67
|
property 'device_name'
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
property 'average_cadence'
|
69
|
+
property 'average_temp'
|
70
|
+
property 'average_watts'
|
71
|
+
property 'weighted_average_watts'
|
72
|
+
property 'kilojoules'
|
73
|
+
property 'device_watts'
|
74
|
+
property 'max_watts'
|
75
|
+
property 'highlighted_kudosers', transform_with: ->(v) { v.map { |r| Strava::Models::Kudoser.new(r) } }
|
76
|
+
property 'segment_leaderboard_opt_out'
|
77
|
+
property 'leaderboard_opt_out'
|
72
78
|
|
73
79
|
def distance_s
|
74
80
|
if type == 'Swim'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Strava
|
2
|
+
module Models
|
3
|
+
class ActivityStats < Model
|
4
|
+
property 'biggest_ride_distance'
|
5
|
+
property 'biggest_climb_elevation_gain'
|
6
|
+
property 'recent_ride_totals', transform_with: ->(v) { Strava::Models::ActivityTotal.new(v) }
|
7
|
+
property 'recent_run_totals', transform_with: ->(v) { Strava::Models::ActivityTotal.new(v) }
|
8
|
+
property 'recent_swim_totals', transform_with: ->(v) { Strava::Models::ActivityTotal.new(v) }
|
9
|
+
property 'ytd_ride_totals', transform_with: ->(v) { Strava::Models::ActivityTotal.new(v) }
|
10
|
+
property 'ytd_run_totals', transform_with: ->(v) { Strava::Models::ActivityTotal.new(v) }
|
11
|
+
property 'ytd_swim_totals', transform_with: ->(v) { Strava::Models::ActivityTotal.new(v) }
|
12
|
+
property 'all_ride_totals', transform_with: ->(v) { Strava::Models::ActivityTotal.new(v) }
|
13
|
+
property 'all_run_totals', transform_with: ->(v) { Strava::Models::ActivityTotal.new(v) }
|
14
|
+
property 'all_swim_totals', transform_with: ->(v) { Strava::Models::ActivityTotal.new(v) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Strava
|
2
|
+
module Models
|
3
|
+
class ActivityTotal < Model
|
4
|
+
include Mixins::MetricDistance
|
5
|
+
include Mixins::Time
|
6
|
+
include Mixins::Elevation
|
7
|
+
|
8
|
+
property 'count'
|
9
|
+
property 'achievement_count'
|
10
|
+
property 'elevation_gain'
|
11
|
+
|
12
|
+
def total_elevation_gain
|
13
|
+
elevation_gain
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -20,6 +20,16 @@ module Strava
|
|
20
20
|
property 'follower'
|
21
21
|
property 'friend'
|
22
22
|
property 'summit'
|
23
|
+
property 'follower_count'
|
24
|
+
property 'friend_count'
|
25
|
+
property 'mutual_friend_count'
|
26
|
+
property 'athlete_type'
|
27
|
+
property 'date_preference'
|
28
|
+
property 'measurement_preference'
|
29
|
+
property 'clubs', transform_with: ->(v) { v.map { |r| Strava::Models::Club.new(r) } }
|
30
|
+
property 'weight'
|
31
|
+
property 'bikes', transform_with: ->(v) { v.map { |r| Strava::Models::Gear.new(r) } }
|
32
|
+
property 'shoes', transform_with: ->(v) { v.map { |r| Strava::Models::Gear.new(r) } }
|
23
33
|
|
24
34
|
def name
|
25
35
|
[firstname, lastname].compact.join(' ') if firstname || lastname
|