strava-api-v2 0.1

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 (41) hide show
  1. data/.gitignore +18 -0
  2. data/.rvmrc +60 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +100 -0
  6. data/Rakefile +9 -0
  7. data/lib/strava/base_connection.rb +29 -0
  8. data/lib/strava/exceptions.rb +7 -0
  9. data/lib/strava/strava_response.rb +5 -0
  10. data/lib/strava/v1/clubs_request.rb +20 -0
  11. data/lib/strava/v1/connection.rb +22 -0
  12. data/lib/strava/v1/models/athlete.rb +15 -0
  13. data/lib/strava/v1/models/club.rb +14 -0
  14. data/lib/strava/v1/models/effort.rb +17 -0
  15. data/lib/strava/v1/models/ride.rb +23 -0
  16. data/lib/strava/v1/models/segment.rb +19 -0
  17. data/lib/strava/v1/models/stream.rb +17 -0
  18. data/lib/strava/v1/rides_request.rb +60 -0
  19. data/lib/strava/v1/segments_request.rb +31 -0
  20. data/lib/strava/v1/streams_request.rb +15 -0
  21. data/lib/strava/v2/auth_request.rb +17 -0
  22. data/lib/strava/v2/connection.rb +27 -0
  23. data/lib/strava/v2/efforts_request.rb +21 -0
  24. data/lib/strava/v2/models/athlete.rb +15 -0
  25. data/lib/strava/v2/models/auth.rb +15 -0
  26. data/lib/strava/v2/models/effort.rb +19 -0
  27. data/lib/strava/v2/models/segment.rb +26 -0
  28. data/lib/strava/v2/segments_request.rb +21 -0
  29. data/lib/strava/version.rb +3 -0
  30. data/strava-api-v2.gemspec +26 -0
  31. data/test/auth_test.rb +32 -0
  32. data/test/clubs_test.rb +31 -0
  33. data/test/efforts_v2_test.rb +34 -0
  34. data/test/rides_v1_test.rb +62 -0
  35. data/test/segments_v1_request_test.rb +39 -0
  36. data/test/segments_v2_request_test.rb +47 -0
  37. data/test/stream_test.rb +30 -0
  38. data/test/test_data.rb +52 -0
  39. data/test/v1_connection_test.rb +37 -0
  40. data/test/v2_connection_test.rb +37 -0
  41. metadata +190 -0
@@ -0,0 +1,31 @@
1
+ require 'strava/v1/models/segment'
2
+
3
+ module Strava
4
+ module V1
5
+ module SegmentRequest
6
+ SEGMENT_PARAMS_MAP = {
7
+ :club_id => :clubId,
8
+ :athlete_id => :athleteId,
9
+ :athlete_name => :athleteName,
10
+ :start_date => :startDate,
11
+ :end_date => :endDate,
12
+ :start_id => :startId,
13
+ :best => :best
14
+ }
15
+
16
+ def efforts_for_segment_path(id)
17
+ "segments/#{id}/efforts"
18
+ end
19
+
20
+ def segment_with_efforts(id, params = {})
21
+ final_params = {}
22
+ params.each_pair do |key, value|
23
+ raise RequestError.new if SEGMENT_PARAMS_MAP[key].nil?
24
+ final_params[SEGMENT_PARAMS_MAP[key]] = value
25
+ end
26
+ all_json = self.fetch(efforts_for_segment_path(id), final_params)
27
+ Segment.new(all_json["segment"], all_json["efforts"])
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,15 @@
1
+ require 'strava/v1/models/stream'
2
+
3
+ module Strava
4
+ module V1
5
+ module StreamRequest
6
+ def streams_path(id)
7
+ "streams/#{id}"
8
+ end
9
+
10
+ def stream(id)
11
+ Stream.new(self.fetch(streams_path(id), nil))
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ require 'strava/v2/models/auth'
2
+
3
+ module Strava
4
+ module V2
5
+ module AuthRequest
6
+ def login_path
7
+ 'authentication/login'
8
+ end
9
+
10
+ def login(email, password)
11
+ auth = Auth.new(self.fetch(login_path(), {:email => email, :password => password}))
12
+ self.set_authorized_user(auth.athlete.id, auth.token)
13
+ return auth
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ require 'httparty'
2
+ require 'strava/base_connection'
3
+ require 'strava/exceptions'
4
+ require 'strava/v2/auth_request'
5
+ require 'strava/v2/efforts_request'
6
+ require 'strava/v2/segments_request'
7
+
8
+ module Strava
9
+ module V2
10
+ class Connection
11
+ include HTTParty
12
+ include Strava::BaseConnection
13
+ include Strava::V2::AuthRequest
14
+ include Strava::V2::EffortsRequest
15
+ include Strava::V2::SegmentsRequest
16
+
17
+ attr_reader :user_id, :token
18
+ base_uri 'http://www.strava.com/api/v2'
19
+ format :json
20
+
21
+ def set_authorized_user(user_id, token)
22
+ @user_id = user_id
23
+ @token = token
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ require 'strava/v2/models/effort'
2
+
3
+ module Strava
4
+ module V2
5
+ module EffortsRequest
6
+ def efforts_path(id)
7
+ "rides/#{id}/efforts"
8
+ end
9
+
10
+ def segments_for_ride(ride_id)
11
+ all_json = self.fetch(efforts_path(ride_id), {})
12
+
13
+ all_segments = []
14
+ all_json["efforts"].each { |effort_json|
15
+ all_segments.push(Segment.new(effort_json["segment"], [effort_json["effort"]]))
16
+ }
17
+ all_segments
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ require 'strava/strava_response'
2
+
3
+ module Strava
4
+ module V2
5
+ class Athlete < StravaResponse
6
+ attr_reader :id, :name, :agreed_to_terms
7
+
8
+ def initialize(json_blob)
9
+ @id = json_blob["id"]
10
+ @name = json_blob["name"]
11
+ @agreed_to_terms = json_blob["agreed_to_terms"]
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'strava/strava_response'
2
+ require 'strava/v2/models/athlete'
3
+
4
+ module Strava
5
+ module V2
6
+ class Auth < StravaResponse
7
+ attr_reader :token, :athlete
8
+
9
+ def initialize(json_blob)
10
+ @token = json_blob["token"]
11
+ @athlete = Athlete.new(json_blob["athlete"])
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ require 'strava/strava_response'
2
+ require 'strava/v2/models/segment'
3
+
4
+ module Strava
5
+ module V2
6
+ class Effort < StravaResponse
7
+ attr_reader :id, :elapsed_time, :moving_time, :distance
8
+
9
+ # Initialize the Effort
10
+ # ejs - the effort JSON
11
+ def initialize(ejs)
12
+ @id = ejs["id"]
13
+ @elapsed_time = ejs["elapsed_time"]
14
+ @moving_time = ejs["moving_time"]
15
+ @distance = ejs["distance"]
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ require 'strava/strava_response'
2
+ require 'strava/v2/models/effort'
3
+
4
+ module Strava
5
+ module V2
6
+ class Segment < StravaResponse
7
+ attr_reader :id, :efforts, :name, :climb_category, :start_latlng, :end_latlng, :average_grade
8
+
9
+ # include the efforts in the segment, if applicable
10
+ # jb - the json for the segment
11
+ # ejb - the json for the efforts, in a list
12
+ def initialize(jb, ejb)
13
+ @id = jb["id"]
14
+ @name = jb["name"]
15
+ @climb_category = jb["climb_category"]
16
+ @start_latlng = jb["start_latlng"]
17
+ @end_latlng = jb["end_latlng"]
18
+ @average_grade = jb["avg_grade"]
19
+ @efforts = []
20
+ ejb.each { |effort_json|
21
+ @efforts.push(Effort.new(effort_json))
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,21 @@
1
+ require 'strava/v2/models/segment'
2
+
3
+ module Strava
4
+ module V2
5
+ module SegmentsRequest
6
+ def segments_and_efforts_for_ride_path(ride_id)
7
+ "rides/#{ride_id}/efforts"
8
+ end
9
+
10
+ def segments_and_efforts_for_ride(ride_id)
11
+ all_json = self.fetch(segments_and_efforts_for_ride_path(ride_id), {})
12
+ all_segments = []
13
+ all_json["efforts"].each { |effort_json|
14
+ all_segments.push(Segment.new(effort_json["segment"], [effort_json["effort"]]))
15
+ }
16
+ all_segments
17
+ end
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,3 @@
1
+ module Strava
2
+ VERSION = "0.1"
3
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'strava/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "strava-api-v2"
8
+ spec.version = Strava::VERSION
9
+ spec.authors = ["Luke StClair"]
10
+ spec.email = ["secureboot@gmail.com"]
11
+ spec.description = %q{API to access strava API, v2}
12
+ spec.summary = %q{Provides access to the strava v1 and v2 apis, which are soon to be deprecated}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "test-unit"
24
+ spec.add_development_dependency "httparty"
25
+ spec.add_development_dependency "mocha"
26
+ end
data/test/auth_test.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'test/unit'
2
+ require 'mocha/setup'
3
+ require 'strava/v2/connection'
4
+ require 'strava/exceptions'
5
+ require 'strava/v2/models/athlete'
6
+ require 'json'
7
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'test'))
8
+ require 'test_data'
9
+
10
+ class AuthTest < Test::Unit::TestCase
11
+
12
+ def setup
13
+ @s = Strava::V2::Connection.new
14
+ end
15
+
16
+ def test_successful_auth
17
+ email = 'secureboot@gmail.com'
18
+ password = 'notatallreal'
19
+
20
+ Strava::V2::Connection.stubs(:get)
21
+ .with("/#{@s.login_path}", {:query => {:email => email, :password => password}})
22
+ .returns(stub(:code => 200, :parsed_response => (JSON.parse TestData.test_login)))
23
+ result = @s.login(email, password)
24
+ assert_equal("thetoken", result.token)
25
+ # make sure the athlete parses out okay.
26
+ assert result.athlete.is_a?(Strava::V2::Athlete)
27
+
28
+ # be sure the auth for the connection gets set
29
+ assert_equal(7976, @s.user_id)
30
+ assert_equal("thetoken", @s.token)
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ require 'test/unit'
2
+ require 'mocha/setup'
3
+ require 'strava/v1/connection'
4
+ require 'strava/exceptions'
5
+ require 'strava/v1/models/club'
6
+ require 'json'
7
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'test'))
8
+ require 'test_data'
9
+
10
+ class ClubsTest < Test::Unit::TestCase
11
+
12
+ def setup
13
+ @s = Strava::V1::Connection.new
14
+ end
15
+
16
+ def test_clubs
17
+ club_name = "mission"
18
+
19
+ Strava::V1::Connection.stubs(:get)
20
+ .with("/clubs", {:query => {:name => club_name}})
21
+ .returns(stub(:code => 200, :parsed_response => (JSON.parse TestData.test_clubs)))
22
+
23
+ clubs = @s.clubs(club_name)
24
+
25
+ assert clubs[0].is_a?(Strava::V1::Club)
26
+ assert_equal(11, clubs.length)
27
+ first = clubs[0]
28
+ assert_equal("Mission Cycling", first.name)
29
+ assert_equal(15, first.id)
30
+ end
31
+ end
@@ -0,0 +1,34 @@
1
+ require 'test/unit'
2
+ require 'mocha/setup'
3
+ require 'strava/v2/connection'
4
+ require 'strava/exceptions'
5
+ require 'strava/v2/models/athlete'
6
+ require 'json'
7
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'test'))
8
+ require 'test_data'
9
+
10
+ class EffortsV2Test < Test::Unit::TestCase
11
+
12
+ def setup
13
+ @s = Strava::V2::Connection.new
14
+ end
15
+
16
+ def test_get_efforts_for_ride
17
+ ride_id = 448459
18
+ Strava::V2::Connection.stubs(:get)
19
+ .with("/rides/#{ride_id}/efforts", {:query => {}})
20
+ .returns(stub(:code => 200, :parsed_response => (JSON.parse TestData.test_v2_efforts)))
21
+ segments = @s.segments_for_ride(ride_id)
22
+ effort = segments[0].efforts[0]
23
+ assert effort.is_a?(Strava::V2::Effort)
24
+ assert_equal(45665444, effort.id)
25
+ assert_equal(12, segments.length)
26
+ assert_equal(634, effort.elapsed_time)
27
+ assert_equal(634, effort.moving_time)
28
+ assert_equal(5342.8, effort.distance)
29
+ assert_equal(852034, segments[0].id)
30
+ assert_equal(1, segments[0].climb_category)
31
+ assert_equal([37.771132132038474,-122.45532101020217], segments[0].start_latlng)
32
+ assert_equal(-0.997671, segments[0].average_grade)
33
+ end
34
+ end
@@ -0,0 +1,62 @@
1
+ require 'test/unit'
2
+ require 'mocha/setup'
3
+ require 'strava/v1/connection'
4
+ require 'strava/exceptions'
5
+ require 'strava/v1/models/athlete'
6
+ require 'json'
7
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'test'))
8
+ require 'test_data'
9
+
10
+ class RidesV1Test < Test::Unit::TestCase
11
+
12
+ def setup
13
+ @s = Strava::V1::Connection.new
14
+ end
15
+
16
+ def test_rides_with_no_params
17
+ Strava::V1::Connection.stubs(:get)
18
+ .with("/#{@s.rides_path}", {:query => {}})
19
+ .returns(stub(:code => 200, :parsed_response => (JSON.parse TestData.test_rides_no_params)))
20
+ result = @s.rides()
21
+ assert_equal(50, result.length)
22
+ end
23
+
24
+ def test_rides_with_invalid_param
25
+ assert_raise Strava::RequestError do
26
+ @s.rides({:made_up => "whatever"})
27
+ end
28
+ end
29
+
30
+ def test_rides_with_two_valid_params
31
+ Strava::V1::Connection.stubs(:get)
32
+ .with("/#{@s.rides_path}", {:query => {:startId => 77563, :offset => 50}})
33
+ .returns(stub(:code => 200, :parsed_response => (JSON.parse TestData.test_ride_start_id_and_offset)))
34
+ rides = @s.rides({:start_id => 77563, :offset => 50})
35
+
36
+ assert_equal(52127040, rides[0].id)
37
+ end
38
+
39
+ def test_getting_efforts_for_a_ride
40
+ ride_id = 77563
41
+ Strava::V1::Connection.stubs(:get)
42
+ .with("/rides/#{ride_id}/efforts", {:query => {}})
43
+ .returns(stub(:code => 200, :parsed_response => (JSON.parse TestData.test_efforts)))
44
+ ride = @s.ride_with_efforts(ride_id)
45
+ assert_equal(ride_id, ride.id)
46
+ assert_equal(5819602, ride.segments[0].efforts[0].id)
47
+ assert_equal(640366, ride.segments[0].id)
48
+ end
49
+
50
+ def test_show_ride_details
51
+ ride_id = 77563
52
+ Strava::V1::Connection.stubs(:get)
53
+ .with("/rides/#{ride_id}", {:query => {}})
54
+ .returns(stub(:code => 200, :parsed_response => (JSON.parse TestData.test_show_ride_deets)))
55
+ ride = @s.ride(ride_id)
56
+ assert_equal(82369.1, ride.distance)
57
+ assert_equal(1441.02, ride.elevation_gain)
58
+ assert_equal("02/28/10 San Francisco, CA", ride.name)
59
+ assert_equal("julianbill", ride.athlete.username)
60
+ assert_equal(1139, ride.athlete.id)
61
+ end
62
+ end
@@ -0,0 +1,39 @@
1
+ require 'test/unit'
2
+ require 'mocha/setup'
3
+ require 'strava/v1/connection'
4
+ require 'strava/v1/segments_request'
5
+ require 'strava/exceptions'
6
+ require 'json'
7
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'test'))
8
+ require 'test_data'
9
+
10
+ class SegmentsV1RequestTest < Test::Unit::TestCase
11
+
12
+ def setup
13
+ @s = Strava::V1::Connection.new
14
+ end
15
+
16
+ def test_get_efforts_for_segment
17
+ segment_id = 229781
18
+
19
+ Strava::V1::Connection.stubs(:get)
20
+ .with("/segments/#{segment_id}/efforts", {:query => {:best => true}})
21
+ .returns(stub(:code => 200, :parsed_response => (JSON.parse TestData.test_v1_segment_efforts)))
22
+ segment = @s.segment_with_efforts(segment_id, {:best => true})
23
+ assert segment.is_a?(Strava::V1::Segment)
24
+ assert segment.efforts[0].is_a?(Strava::V1::Effort)
25
+ assert_equal(segment_id, segment.id)
26
+ assert_equal(50, segment.efforts.length)
27
+ first = segment.efforts[0]
28
+ assert_equal(801006623, first.id)
29
+ assert_equal(123529, first.athlete.id)
30
+ assert_equal("jimwhimpey", first.athlete.username)
31
+ assert_equal("Jim Whimpey", first.athlete.name)
32
+ end
33
+
34
+ def test_segment_with_bad_param
35
+ assert_raise Strava::RequestError do
36
+ @s.segment_with_efforts(12345, {:made_up => "whatever"})
37
+ end
38
+ end
39
+ end