strava-ruby-client 3.0.0 → 3.1.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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -0
  3. data/README.md +41 -57
  4. data/lib/strava/api/client.rb +69 -0
  5. data/lib/strava/api/config.rb +40 -0
  6. data/lib/strava/api/cursor.rb +32 -1
  7. data/lib/strava/api/endpoints/activities.rb +197 -57
  8. data/lib/strava/api/endpoints/athletes.rb +64 -8
  9. data/lib/strava/api/endpoints/clubs.rb +24 -59
  10. data/lib/strava/api/endpoints/gears.rb +11 -2
  11. data/lib/strava/api/endpoints/oauth.rb +45 -0
  12. data/lib/strava/api/endpoints/routes.rb +20 -13
  13. data/lib/strava/api/endpoints/segment_efforts.rb +15 -8
  14. data/lib/strava/api/endpoints/segments.rb +74 -21
  15. data/lib/strava/api/endpoints/streams.rb +22 -18
  16. data/lib/strava/api/endpoints/uploads.rb +12 -2
  17. data/lib/strava/api/pagination.rb +25 -0
  18. data/lib/strava/api/ratelimit.rb +34 -0
  19. data/lib/strava/deep_copyable.rb +20 -1
  20. data/lib/strava/errors/fault.rb +32 -0
  21. data/lib/strava/errors/ratelimit_error.rb +35 -0
  22. data/lib/strava/errors/upload_error.rb +55 -0
  23. data/lib/strava/logger.rb +27 -0
  24. data/lib/strava/models/achievement.rb +28 -1
  25. data/lib/strava/models/activity_stats.rb +47 -1
  26. data/lib/strava/models/activity_total.rb +25 -1
  27. data/lib/strava/models/activity_zone.rb +39 -2
  28. data/lib/strava/models/authorization.rb +13 -0
  29. data/lib/strava/models/base_stream.rb +22 -1
  30. data/lib/strava/models/club_event.rb +64 -1
  31. data/lib/strava/models/comment.rb +39 -1
  32. data/lib/strava/models/destination.rb +28 -1
  33. data/lib/strava/models/detailed_activity.rb +203 -2
  34. data/lib/strava/models/detailed_athlete.rb +104 -2
  35. data/lib/strava/models/detailed_club.rb +76 -2
  36. data/lib/strava/models/detailed_gear.rb +45 -2
  37. data/lib/strava/models/detailed_photo.rb +61 -1
  38. data/lib/strava/models/detailed_photos.rb +29 -1
  39. data/lib/strava/models/detailed_segment.rb +89 -2
  40. data/lib/strava/models/detailed_segment_effort.rb +92 -3
  41. data/lib/strava/models/explorer_segment.rb +55 -2
  42. data/lib/strava/models/heart_rate_zone_ranges.rb +29 -1
  43. data/lib/strava/models/kudoser.rb +29 -1
  44. data/lib/strava/models/lap.rb +62 -2
  45. data/lib/strava/models/lat_lng.rb +42 -4
  46. data/lib/strava/models/local_legend.rb +41 -1
  47. data/lib/strava/models/map.rb +31 -0
  48. data/lib/strava/models/meta_activity.rb +15 -2
  49. data/lib/strava/models/meta_athlete.rb +17 -2
  50. data/lib/strava/models/meta_club.rb +15 -1
  51. data/lib/strava/models/mixins/average_speed.rb +81 -3
  52. data/lib/strava/models/mixins/distance.rb +25 -0
  53. data/lib/strava/models/mixins/elapsed_time.rb +18 -0
  54. data/lib/strava/models/mixins/elevation_difference.rb +42 -0
  55. data/lib/strava/models/mixins/elevation_gain.rb +39 -0
  56. data/lib/strava/models/mixins/estimated_moving_time.rb +18 -0
  57. data/lib/strava/models/mixins/http_response.rb +36 -0
  58. data/lib/strava/models/mixins/moving_time.rb +18 -0
  59. data/lib/strava/models/mixins/sport_type.rb +39 -1
  60. data/lib/strava/models/mixins/start_date_local.rb +40 -24
  61. data/lib/strava/models/mixins/time_in_hours.rb +23 -0
  62. data/lib/strava/models/mixins/total_elevation_gain.rb +42 -0
  63. data/lib/strava/models/model.rb +14 -0
  64. data/lib/strava/models/photos_summary.rb +26 -2
  65. data/lib/strava/models/photos_summary_primary.rb +28 -2
  66. data/lib/strava/models/power_zone_ranges.rb +23 -1
  67. data/lib/strava/models/response.rb +18 -0
  68. data/lib/strava/models/route.rb +63 -2
  69. data/lib/strava/models/similar_activities.rb +57 -1
  70. data/lib/strava/models/split.rb +27 -2
  71. data/lib/strava/models/stats_visibility.rb +24 -1
  72. data/lib/strava/models/stream.rb +107 -0
  73. data/lib/strava/models/stream_set.rb +52 -1
  74. data/lib/strava/models/summary_activity.rb +145 -2
  75. data/lib/strava/models/summary_athlete.rb +54 -1
  76. data/lib/strava/models/summary_club.rb +61 -2
  77. data/lib/strava/models/summary_gear.rb +31 -2
  78. data/lib/strava/models/summary_pr_segment_effort.rb +32 -2
  79. data/lib/strava/models/summary_segment.rb +80 -2
  80. data/lib/strava/models/summary_segment_effort.rb +32 -1
  81. data/lib/strava/models/timed_zone_range.rb +24 -1
  82. data/lib/strava/models/token.rb +31 -0
  83. data/lib/strava/models/trend.rb +38 -1
  84. data/lib/strava/models/updatable_activity.rb +36 -1
  85. data/lib/strava/models/upload.rb +50 -1
  86. data/lib/strava/models/waypoint.rb +31 -1
  87. data/lib/strava/models/xoms.rb +35 -1
  88. data/lib/strava/models/zone_range.rb +20 -1
  89. data/lib/strava/models/zones.rb +32 -1
  90. data/lib/strava/oauth/client.rb +107 -19
  91. data/lib/strava/oauth/config.rb +41 -0
  92. data/lib/strava/version.rb +1 -1
  93. data/lib/strava/web/api_response.rb +28 -2
  94. data/lib/strava/web/client.rb +72 -2
  95. data/lib/strava/web/config.rb +40 -0
  96. data/lib/strava/web/connection.rb +39 -0
  97. data/lib/strava/web/raise_response_error.rb +47 -0
  98. data/lib/strava/web/request.rb +56 -0
  99. data/lib/strava/web/response.rb +18 -0
  100. data/lib/strava/webhooks/client.rb +108 -7
  101. data/lib/strava/webhooks/config.rb +44 -0
  102. data/lib/strava/webhooks/models/challenge.rb +40 -0
  103. data/lib/strava/webhooks/models/event.rb +50 -0
  104. data/lib/strava/webhooks/models/subscription.rb +27 -0
  105. data/lib/strava-ruby-client.rb +0 -2
  106. metadata +2 -4
  107. data/lib/strava/models/club_activity.rb +0 -22
  108. data/lib/strava/models/club_athlete.rb +0 -21
@@ -2,30 +2,89 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
- # https://developers.strava.com/docs/reference/#api-models-SummaryClub
5
+ #
6
+ # Represents summary information about a Strava club.
7
+ #
8
+ # Contains basic club information without detailed membership data.
9
+ # This is typically returned when listing athlete's clubs or as a
10
+ # reference within other models.
11
+ #
12
+ # @example List athlete's clubs
13
+ # clubs = client.athlete_clubs
14
+ # clubs.each do |club|
15
+ # puts "#{club.name} - #{club.member_count} members"
16
+ # puts club.strava_url
17
+ # end
18
+ #
19
+ # @see DetailedClub
20
+ # @see https://developers.strava.com/docs/reference/#api-models-SummaryClub
21
+ #
6
22
  class SummaryClub < Strava::Models::Response
23
+ # @return [Integer] Club identifier
7
24
  property 'id'
25
+
26
+ # @return [Integer] Resource state indicator (1=meta, 2=summary, 3=detailed)
8
27
  property 'resource_state'
28
+
29
+ # @return [String] Club name
9
30
  property 'name'
31
+
32
+ # @return [String] URL to medium-sized profile picture
10
33
  property 'profile_medium'
34
+
35
+ # @return [String] URL to club cover photo
11
36
  property 'cover_photo'
37
+
38
+ # @return [String] URL to smaller club cover photo
12
39
  property 'cover_photo_small'
40
+
41
+ # @return [String] Primary sport type (e.g., "cycling", "running", "other")
13
42
  property 'sport_type'
43
+
44
+ # @return [Array<String>] List of activity types the club supports
14
45
  property 'activity_types'
46
+
47
+ # @return [String] City where club is located
15
48
  property 'city'
49
+
50
+ # @return [String] State/province where club is located
16
51
  property 'state'
52
+
53
+ # @return [String] Country where club is located
17
54
  property 'country'
55
+
56
+ # @return [Boolean] Whether club is private
18
57
  property 'private'
58
+
59
+ # @return [Integer] Number of club members
19
60
  property 'member_count'
61
+
62
+ # @return [Boolean] Whether club is featured by Strava
20
63
  property 'featured'
64
+
65
+ # @return [Boolean] Whether club is verified by Strava
21
66
  property 'verified'
67
+
68
+ # @return [String] Club URL slug
22
69
  property 'url'
23
- # undocumented
70
+
71
+ # @return [String] URL to full-sized profile picture
24
72
  property 'profile'
73
+
74
+ # @return [String] Icon representing the activity types
25
75
  property 'activity_types_icon'
76
+
77
+ # @return [Array<Integer>] Dimensions of cover photo [width, height]
26
78
  property 'dimensions'
79
+
80
+ # @return [String] Localized sport type string
27
81
  property 'localized_sport_type'
28
82
 
83
+ #
84
+ # Returns the Strava web URL for this club.
85
+ #
86
+ # @return [String] Full URL to view the club on Strava.com
87
+ #
29
88
  def strava_url
30
89
  "https://www.strava.com/clubs/#{url || id}"
31
90
  end
@@ -2,16 +2,45 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
- # https://developers.strava.com/docs/reference/#api-models-SummaryGear
5
+ #
6
+ # Represents summary information about athlete's equipment/gear.
7
+ #
8
+ # Contains basic gear information without detailed specifications.
9
+ # Typically returned as part of athlete profile or activity data.
10
+ #
11
+ # Includes the Distance mixin for formatting accumulated distance.
12
+ #
13
+ # @example Access gear from athlete profile
14
+ # athlete = client.athlete
15
+ # athlete.bikes.each do |bike|
16
+ # puts "#{bike.name}: #{bike.distance_s}"
17
+ # end
18
+ #
19
+ # @see DetailedGear
20
+ # @see https://developers.strava.com/docs/reference/#api-models-SummaryGear
21
+ #
6
22
  class SummaryGear < Strava::Models::Response
23
+ # @return [String] Gear identifier (e.g., "b12345" for bike, "g12345" for shoes)
7
24
  property 'id'
25
+
26
+ # @return [Integer] Resource state indicator
8
27
  property 'resource_state'
28
+
29
+ # @return [Boolean] Whether this is the athlete's primary gear for this type
9
30
  property 'primary'
31
+
32
+ # @return [String] Gear name/title
10
33
  property 'name'
34
+
11
35
  include Mixins::Distance
12
- # undocumented
36
+
37
+ # @return [String] Nickname for the gear
13
38
  property 'nickname'
39
+
40
+ # @return [Boolean] Whether gear has been retired/is no longer in use
14
41
  property 'retired'
42
+
43
+ # @return [Float] Distance in meters after conversion (likely for imperial users)
15
44
  property 'converted_distance'
16
45
  end
17
46
  end
@@ -2,14 +2,44 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
- # https://developers.strava.com/docs/reference/#api-models-SummaryPRSegmentEffort
5
+ #
6
+ # Represents an athlete's personal record (PR) on a segment.
7
+ #
8
+ # Contains information about the athlete's best effort on a particular segment,
9
+ # including when it was achieved and how many times they've attempted the segment.
10
+ #
11
+ # @see https://developers.strava.com/docs/reference/#api-models-SummaryPRSegmentEffort Strava API SummaryPRSegmentEffort reference
12
+ # @see Strava::Models::SummarySegment
13
+ # @see Strava::Models::DetailedSegmentEffort
14
+ #
15
+ # @example Accessing PR information from a segment
16
+ # segment = client.segment(1234567)
17
+ # if segment.athlete_pr_effort
18
+ # pr = segment.athlete_pr_effort
19
+ # puts "Your PR: #{pr.pr_elapsed_time} seconds"
20
+ # puts "Set on: #{pr.pr_date}"
21
+ # puts "Total attempts: #{pr.effort_count}"
22
+ # end
23
+ #
6
24
  class SummaryPRSegmentEffort < Strava::Models::Response
25
+ # @return [Integer, nil] Activity ID where the PR was achieved
7
26
  property 'pr_activity_id'
27
+
28
+ # @return [Integer, nil] Elapsed time for the PR effort in seconds
8
29
  property 'pr_elapsed_time'
30
+
31
+ # @return [Date, nil] Date when the PR was set
9
32
  property 'pr_date', transform_with: ->(v) { Date.parse(v) }
33
+
34
+ # @return [Integer] Total number of times the athlete has attempted this segment
10
35
  property 'effort_count'
11
- # undocumented
36
+
37
+ # @return [String, nil] Visibility setting for the PR effort
38
+ # @note Not documented by Strava API
12
39
  property 'pr_visibility'
40
+
41
+ # @return [String, nil] Visibility setting for the activity containing the PR
42
+ # @note Not documented by Strava API
13
43
  property 'pr_activity_visibility'
14
44
  end
15
45
  end
@@ -2,32 +2,110 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
- # https://developers.strava.com/docs/reference/#api-models-SummarySegment
5
+ #
6
+ # Represents summary information about a segment.
7
+ #
8
+ # A segment is a specific section of road or trail that athletes can compete on.
9
+ # This summary version contains key information about the segment including
10
+ # location, elevation, and the athlete's personal stats on it.
11
+ #
12
+ # @see https://developers.strava.com/docs/reference/#api-models-SummarySegment Strava API SummarySegment reference
13
+ # @see Strava::Models::DetailedSegment
14
+ # @see Strava::Models::ExplorerSegment
15
+ # @see Strava::Models::SummaryPRSegmentEffort
16
+ #
17
+ # @example Accessing segment information from an effort
18
+ # activity = client.activity(1234567890)
19
+ # activity.segment_efforts.each do |effort|
20
+ # segment = effort.segment
21
+ # puts "#{segment.name} (#{segment.distance_s})"
22
+ # puts " Location: #{segment.city}, #{segment.state}, #{segment.country}"
23
+ # puts " Grade: #{segment.average_grade}% (max: #{segment.maximum_grade}%)"
24
+ # puts " Elevation: #{segment.elevation_low}m - #{segment.elevation_high}m"
25
+ #
26
+ # if segment.athlete_pr_effort
27
+ # puts " Your PR: #{segment.athlete_pr_effort.pr_elapsed_time}s"
28
+ # end
29
+ # end
30
+ #
6
31
  class SummarySegment < Strava::Models::Response
32
+ # @return [Integer] Unique identifier for this segment
7
33
  property 'id'
34
+
35
+ # @return [String] Name of the segment
8
36
  property 'name'
37
+
38
+ # @return [String] Activity type this segment is for ("Ride" or "Run")
9
39
  property 'activity_type'
40
+
41
+ # Includes distance in meters and conversion helper methods
10
42
  include Mixins::Distance
43
+
44
+ # @return [Float] Average grade/incline as a percentage
11
45
  property 'average_grade'
46
+
47
+ # @return [Float] Maximum grade/incline as a percentage
12
48
  property 'maximum_grade'
49
+
50
+ # @return [Float] Highest elevation point on the segment in meters
13
51
  property 'elevation_high'
52
+
53
+ # @return [Float] Lowest elevation point on the segment in meters
14
54
  property 'elevation_low'
55
+
56
+ # @return [LatLng] GPS coordinates of segment start point
15
57
  property 'start_latlng', transform_with: ->(v) { Strava::Models::LatLng.new(v) }
58
+
59
+ # @return [LatLng] GPS coordinates of segment end point
16
60
  property 'end_latlng', transform_with: ->(v) { Strava::Models::LatLng.new(v) }
61
+
62
+ # @return [Integer] Climb category (0=uncategorized, 5=easiest, 1=hardest, HC=hors catégorie)
17
63
  property 'climb_category'
64
+
65
+ # @return [String, nil] City where the segment is located
18
66
  property 'city'
67
+
68
+ # @return [String, nil] State/province where the segment is located
19
69
  property 'state'
70
+
71
+ # @return [String, nil] Country where the segment is located
20
72
  property 'country'
73
+
74
+ # @return [Boolean] Whether this is a private segment
21
75
  property 'private'
76
+
77
+ # @return [SummaryPRSegmentEffort, nil] Athlete's personal record on this segment
22
78
  property 'athlete_pr_effort', transform_with: ->(v) { Strava::Models::SummaryPRSegmentEffort.new(v) }
79
+
80
+ # @return [SummarySegmentEffort, nil] Athlete's statistics for this segment
23
81
  property 'athlete_segment_stats', transform_with: ->(v) { Strava::Models::SummarySegmentEffort.new(v) }
24
- # undocumented
82
+
83
+ # @return [Integer] Resource state indicator
84
+ # @note Not documented by Strava API
25
85
  property 'resource_state'
86
+
87
+ # @return [String, nil] URL or path to elevation profile visualization
88
+ # @note Not documented by Strava API
26
89
  property 'elevation_profile'
90
+
91
+ # @return [Array, nil] Array of elevation profile data
92
+ # @note Not documented by Strava API
27
93
  property 'elevation_profiles'
94
+
95
+ # @return [Boolean, nil] Whether this segment has been flagged as hazardous
96
+ # @note Not documented by Strava API
28
97
  property 'hazardous'
98
+
99
+ # @return [Boolean, nil] Whether the current athlete has starred this segment
100
+ # @note Not documented by Strava API
29
101
  property 'starred'
102
+
103
+ # @return [Time, nil] Date when the athlete starred this segment
104
+ # @note Not documented by Strava API
30
105
  property 'starred_date', transform_with: ->(v) { Time.parse(v) }
106
+
107
+ # @return [Integer, nil] Athlete's PR time on this segment in seconds
108
+ # @note Not documented by Strava API
31
109
  property 'pr_time'
32
110
  end
33
111
  end
@@ -2,14 +2,45 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
- # https://developers.strava.com/docs/reference/#api-models-SummarySegmentEffort
5
+ #
6
+ # Represents a summary of a segment effort within an activity.
7
+ #
8
+ # A segment effort is an attempt at a defined segment (a portion of road or trail).
9
+ # This summary version contains basic information about the effort without
10
+ # detailed statistics.
11
+ #
12
+ # @see https://developers.strava.com/docs/reference/#api-models-SummarySegmentEffort Strava API SummarySegmentEffort reference
13
+ # @see Strava::Models::DetailedSegmentEffort
14
+ # @see Strava::Models::DetailedActivity#segment_efforts
15
+ #
16
+ # @example Accessing segment efforts from an activity
17
+ # activity = client.activity(1234567890)
18
+ # activity.segment_efforts.each do |effort|
19
+ # puts "#{effort.name}: #{effort.elapsed_time_in_hours_s}"
20
+ # puts " KOM: #{effort.is_kom}"
21
+ # puts " Distance: #{effort.distance_s}"
22
+ # end
23
+ #
6
24
  class SummarySegmentEffort < Strava::Models::Response
25
+ # @return [Integer] Unique identifier for this segment effort
7
26
  property 'id'
27
+
28
+ # @return [Integer] ID of the activity containing this segment effort
8
29
  property 'activity_id'
30
+
31
+ # Includes elapsed_time (total time including stops) and helper methods
9
32
  include Mixins::ElapsedTime
33
+
34
+ # @return [Time] Start time of the segment effort in UTC
10
35
  property 'start_date', transform_with: ->(v) { Time.parse(v) }
36
+
37
+ # Includes start_date_local with timezone handling
11
38
  include Mixins::StartDateLocal
39
+
40
+ # Includes distance in meters and conversion helper methods
12
41
  include Mixins::Distance
42
+
43
+ # @return [Boolean] Whether this effort achieved KOM (King/Queen of the Mountain)
13
44
  property 'is_kom'
14
45
  end
15
46
  end
@@ -2,10 +2,33 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
- # https://developers.strava.com/docs/reference/#api-models-TimedZoneRange
5
+ #
6
+ # Represents a training zone range with time spent in that zone.
7
+ #
8
+ # Used in activity zone distributions to show how much time was spent
9
+ # at different intensity levels during an activity.
10
+ #
11
+ # @see https://developers.strava.com/docs/reference/#api-models-TimedZoneRange Strava API TimedZoneRange reference
12
+ # @see Strava::Models::ZoneRange
13
+ # @see Strava::Models::ActivityZone
14
+ #
15
+ # @example Viewing time distribution across zones
16
+ # zones = client.activity_zones(1234567890)
17
+ # hr_zone = zones.find { |z| z.type == 'heartrate' }
18
+ #
19
+ # hr_zone.distribution_buckets.each_with_index do |bucket, i|
20
+ # minutes = bucket.time / 60
21
+ # puts "Zone #{i + 1} (#{bucket.min}-#{bucket.max} bpm): #{minutes} minutes"
22
+ # end
23
+ #
6
24
  class TimedZoneRange < Strava::Models::Response
25
+ # @return [Integer] Maximum value for this zone (e.g., maximum heart rate or power)
7
26
  property 'max'
27
+
28
+ # @return [Integer] Minimum value for this zone (e.g., minimum heart rate or power)
8
29
  property 'min'
30
+
31
+ # @return [Integer] Time spent in this zone in seconds
9
32
  property 'time'
10
33
  end
11
34
  end
@@ -2,12 +2,43 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
+ #
6
+ # Represents an OAuth token response from Strava.
7
+ #
8
+ # This model is returned when exchanging an authorization code for an access token
9
+ # or when refreshing an expired token. It contains the access token, refresh token,
10
+ # expiration time, and basic athlete information.
11
+ #
12
+ # Tokens expire after a period of time (typically 6 hours). When a token expires,
13
+ # use the refresh_token to obtain a new access_token via the OAuth flow.
14
+ #
15
+ # @example Inspecting token information
16
+ # token = client.oauth_token(code: 'auth_code')
17
+ # puts "Access Token: #{token.access_token}"
18
+ # puts "Refresh Token: #{token.refresh_token}"
19
+ # puts "Expires at: #{token.expires_at}"
20
+ # puts "Athlete: #{token.athlete.firstname} #{token.athlete.lastname}"
21
+ #
22
+ # @see Strava::OAuth::Client#oauth_token
23
+ # @see https://developers.strava.com/docs/authentication/
24
+ #
5
25
  class Token < Strava::Models::Response
26
+ # @return [String] Type of token, typically "Bearer"
6
27
  property 'token_type'
28
+
29
+ # @return [String] OAuth access token for API authentication
7
30
  property 'access_token'
31
+
32
+ # @return [String] Refresh token for obtaining new access tokens
8
33
  property 'refresh_token'
34
+
35
+ # @return [Integer] Number of seconds until token expires
9
36
  property 'expires_in'
37
+
38
+ # @return [Time] Expiration time of the access token
10
39
  property 'expires_at', transform_with: ->(v) { Time.at(v) }
40
+
41
+ # @return [Strava::Models::SummaryAthlete] Summary of the authenticated athlete
11
42
  property 'athlete', transform_with: ->(v) { Strava::Models::SummaryAthlete.new(v) }
12
43
  end
13
44
  end
@@ -2,13 +2,50 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
- # Undocumented
5
+ #
6
+ # Represents performance trend data.
7
+ #
8
+ # Contains trend information about speed and performance over time,
9
+ # showing whether performance is improving, declining, or staying consistent.
10
+ # This model is not documented in the official Strava API reference.
11
+ #
12
+ # @note This model is not documented by Strava API documentation. Properties
13
+ # are inferred from API responses.
14
+ #
15
+ # @see Strava::Models::SimilarActivities
16
+ #
17
+ # @example Accessing trend data
18
+ # activity = client.activity(1234567890)
19
+ # if activity.similar_activities&.trend
20
+ # trend = activity.similar_activities.trend
21
+ # puts "Trend direction: #{trend.direction}"
22
+ # puts "Speed range: #{trend.min_speed} - #{trend.max_speed} m/s"
23
+ # puts "Current activity index: #{trend.current_activity_index}"
24
+ # end
25
+ #
6
26
  class Trend < Strava::Models::Response
27
+ # @return [Array, nil] Array of speed values showing the trend
28
+ # @note Not documented by Strava API
7
29
  property 'speeds'
30
+
31
+ # @return [Integer, nil] Index of current activity in the trend series
32
+ # @note Not documented by Strava API
8
33
  property 'current_activity_index'
34
+
35
+ # @return [Float, nil] Minimum speed in the trend in meters per second
36
+ # @note Not documented by Strava API
9
37
  property 'min_speed'
38
+
39
+ # @return [Float, nil] Median speed in the trend in meters per second
40
+ # @note Not documented by Strava API
10
41
  property 'mid_speed'
42
+
43
+ # @return [Float, nil] Maximum speed in the trend in meters per second
44
+ # @note Not documented by Strava API
11
45
  property 'max_speed'
46
+
47
+ # @return [Integer, nil] Trend direction indicator (e.g., -1=declining, 0=stable, 1=improving)
48
+ # @note Not documented by Strava API
12
49
  property 'direction'
13
50
  end
14
51
  end
@@ -2,14 +2,49 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
- # https://developers.strava.com/docs/reference/#api-models-UpdatableActivity
5
+ #
6
+ # Represents the response from updating an activity.
7
+ #
8
+ # When you update an activity using the update_activity endpoint, Strava returns
9
+ # this model containing the fields that were successfully updated. This is a subset
10
+ # of the full activity data.
11
+ #
12
+ # @see https://developers.strava.com/docs/reference/#api-models-UpdatableActivity Strava API UpdatableActivity reference
13
+ # @see Strava::Api::Client#update_activity
14
+ # @see Strava::Models::DetailedActivity
15
+ #
16
+ # @example Updating activity properties
17
+ # updated = client.update_activity(1234567890,
18
+ # name: "Morning Run",
19
+ # description: "Great weather today!",
20
+ # commute: false,
21
+ # trainer: false,
22
+ # gear_id: "g12345"
23
+ # )
24
+ #
25
+ # puts "Activity renamed to: #{updated.name}"
26
+ # puts "Gear ID: #{updated.gear_id}"
27
+ #
6
28
  class UpdatableActivity < Strava::Models::Response
29
+ # @return [Boolean, nil] Whether this activity is a commute
7
30
  property 'commute'
31
+
32
+ # @return [Boolean, nil] Whether this activity was done on a trainer/treadmill
8
33
  property 'trainer'
34
+
35
+ # @return [Boolean, nil] Whether to hide this activity from the home feed
9
36
  property 'hide_from_home'
37
+
38
+ # @return [String, nil] Description of the activity
10
39
  property 'description'
40
+
41
+ # @return [String, nil] Name/title of the activity
11
42
  property 'name'
43
+
44
+ # @return [String, nil] Sport type (e.g., "Run", "Ride", "Swim")
12
45
  property 'sport_type'
46
+
47
+ # @return [String, nil] ID of the gear (shoes/bike) used for this activity
13
48
  property 'gear_id'
14
49
  end
15
50
  end
@@ -2,20 +2,69 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
- # https://developers.strava.com/docs/reference/#api-models-Upload
5
+ #
6
+ # Represents an activity file upload status.
7
+ #
8
+ # When uploading activity files (GPX, TCX, FIT) to Strava, the upload is processed
9
+ # asynchronously. This model tracks the upload status and provides helper methods
10
+ # to check if processing is complete.
11
+ #
12
+ # @example Upload and poll for completion
13
+ # upload = client.create_upload(
14
+ # file: Faraday::UploadIO.new('activity.gpx', 'application/gpx+xml'),
15
+ # data_type: 'gpx'
16
+ # )
17
+ #
18
+ # while upload.processing?
19
+ # sleep 2
20
+ # upload = client.upload(upload.id)
21
+ # end
22
+ #
23
+ # if upload.error
24
+ # puts "Upload failed: #{upload.error}"
25
+ # else
26
+ # puts "Activity created: #{upload.activity_id}"
27
+ # end
28
+ #
29
+ # @see Strava::Api::Client#create_upload
30
+ # @see Strava::Api::Client#upload
31
+ # @see https://developers.strava.com/docs/reference/#api-models-Upload
32
+ #
6
33
  class Upload < Strava::Models::Response
34
+ # @return [Integer] Upload ID
7
35
  property 'id'
36
+
37
+ # @return [String] Upload ID as string
8
38
  property 'id_str'
39
+
40
+ # @return [String] External identifier for the upload
9
41
  property 'external_id'
42
+
43
+ # @return [String, nil] Error message if upload failed
10
44
  property 'error'
45
+
46
+ # @return [String] Status message (e.g., "Your activity is ready.", "Your activity is still being processed.")
11
47
  property 'status'
48
+
49
+ # @return [Integer, nil] Activity ID once processing is complete
12
50
  property 'activity_id'
13
51
 
52
+ #
53
+ # Checks if the upload is still processing.
54
+ #
55
+ # @return [Boolean] true if upload is still being processed
56
+ # @raise [Strava::Errors::UploadError] if upload failed with an error
57
+ #
14
58
  def processing?
15
59
  validate!
16
60
  activity_id.nil?
17
61
  end
18
62
 
63
+ #
64
+ # Checks if the upload has completed processing.
65
+ #
66
+ # @return [Boolean] true if upload processing is complete
67
+ #
19
68
  def processed?
20
69
  !processing?
21
70
  end
@@ -2,13 +2,43 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
- # https://developers.strava.com/docs/reference/#api-models-Waypoint
5
+ #
6
+ # Represents a waypoint on a route.
7
+ #
8
+ # Waypoints are markers along a route that can indicate points of interest,
9
+ # turns, or other significant locations. They include GPS coordinates and
10
+ # descriptive information.
11
+ #
12
+ # @see https://developers.strava.com/docs/reference/#api-models-Waypoint Strava API Waypoint reference
13
+ # @see Strava::Models::Route
14
+ # @see Strava::Models::LatLng
15
+ #
16
+ # @example Accessing route waypoints
17
+ # route = client.route(1234567)
18
+ # route.waypoints.each do |waypoint|
19
+ # puts "#{waypoint.title}: #{waypoint.description}"
20
+ # puts " Location: #{waypoint.latlng.lat}, #{waypoint.latlng.lng}"
21
+ # puts " Distance into route: #{waypoint.distance_into_route}m"
22
+ # puts " Categories: #{waypoint.categories.join(', ')}"
23
+ # end
24
+ #
6
25
  class Waypoint < Strava::Models::Response
26
+ # @return [LatLng] GPS coordinates of the waypoint
7
27
  property 'latlng', transform_with: ->(v) { Strava::Models::LatLng.new(v) }
28
+
29
+ # @return [LatLng, nil] Target GPS coordinates (may differ from latlng for snapped waypoints)
8
30
  property 'target_latlng', transform_with: ->(v) { Strava::Models::LatLng.new(v) }
31
+
32
+ # @return [Array<String>] Categories or types for this waypoint (e.g., ["water", "rest"])
9
33
  property 'categories'
34
+
35
+ # @return [String] Title or name of the waypoint
10
36
  property 'title'
37
+
38
+ # @return [String, nil] Detailed description of the waypoint
11
39
  property 'description'
40
+
41
+ # @return [Float] Distance from the start of the route to this waypoint in meters
12
42
  property 'distance_into_route'
13
43
  end
14
44
  end