nike_plus 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +20 -0
- data/README.md +52 -0
- data/README.rdoc +19 -0
- data/lib/nike_plus/activity.rb +132 -0
- data/lib/nike_plus/activity_summary.rb +57 -0
- data/lib/nike_plus/client.rb +94 -0
- data/lib/nike_plus/version.rb +3 -0
- data/lib/nike_plus.rb +8 -0
- metadata +171 -0
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Adam Roth
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# NikePlus
|
2
|
+
|
3
|
+
A Ruby library for accessing Nike+ data.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
gem install nike_plus
|
7
|
+
|
8
|
+
## Documentation
|
9
|
+
[http://rdoc.info/gems/nike_plus][documentation]
|
10
|
+
|
11
|
+
[documentation]: http://rdoc.info/gems/nike_plus
|
12
|
+
|
13
|
+
## Usage Example
|
14
|
+
nike = NikePlus::Client.new( :email => 'test@nikeplus.com', :password => 'mypassword' )
|
15
|
+
|
16
|
+
list = nike.activities
|
17
|
+
|
18
|
+
list.each do |summary|
|
19
|
+
activity = nike.activity( summary.activityId )
|
20
|
+
|
21
|
+
puts "name : #{ activity.name }"
|
22
|
+
puts "distance : #{ activity.miles } miles"
|
23
|
+
puts "pace : #{ activity.mpm } min/mile"
|
24
|
+
puts "waypoints : #{ activity.geo.waypoints.size } points" if activity.geo.waypoints.any?
|
25
|
+
end
|
26
|
+
|
27
|
+
## Contributing
|
28
|
+
In the spirit of [free software][free-sw], **everyone** is encouraged to help
|
29
|
+
improve this project.
|
30
|
+
|
31
|
+
[free-sw]: http://www.fsf.org/licensing/essays/free-sw.html
|
32
|
+
|
33
|
+
Here are some ways *you* can contribute:
|
34
|
+
|
35
|
+
* by using alpha, beta, and prerelease versions
|
36
|
+
* by reporting bugs
|
37
|
+
* by suggesting new features
|
38
|
+
* by writing or editing documentation
|
39
|
+
* by writing specifications
|
40
|
+
* by writing code (**no patch is too small**: fix typos, add comments, clean up
|
41
|
+
inconsistent whitespace)
|
42
|
+
* by refactoring code
|
43
|
+
* by fixing [issues][]
|
44
|
+
* by reviewing patches
|
45
|
+
|
46
|
+
[issues]: https://github.com/aroth/nike_plus/issues
|
47
|
+
|
48
|
+
## Copyright
|
49
|
+
Copyright (c) 2012 Adam Roth
|
50
|
+
See [LICENSE][] for details.
|
51
|
+
|
52
|
+
[license]: https://github.com/aroth/nike_plus/blob/master/LICENSE.txt
|
data/README.rdoc
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= nike_plus
|
2
|
+
|
3
|
+
Ruby library for accessing Nike+ data.
|
4
|
+
|
5
|
+
== Contributing to nike_plus
|
6
|
+
|
7
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
8
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
9
|
+
* Fork the project.
|
10
|
+
* Start a feature/bugfix branch.
|
11
|
+
* Commit and push until you are happy with your contribution.
|
12
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2012 Adam Roth. See LICENSE.txt for
|
18
|
+
further details.
|
19
|
+
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module NikePlus
|
2
|
+
# Nike+ returns a lot of data for an activity. Internally, Hashie is used to convert the parsed JSON data
|
3
|
+
# into a pseduo-hash that behaves like an object. Below is a fairly complete list of the data returned for
|
4
|
+
# an activity logged with Nike+ in June 2012:
|
5
|
+
#
|
6
|
+
# name => "RUN ON: 06/21/12 06:28 PM",
|
7
|
+
# activityId => "2003132748",
|
8
|
+
# activityType => "RUN",
|
9
|
+
# timeZone => "-04:00",
|
10
|
+
# timeZoneId => "GMT-04:00",
|
11
|
+
# dstOffset => "00:00",
|
12
|
+
# startTimeUtc => "2012-06-21T18:28:45-04:00",
|
13
|
+
# status => "complete",
|
14
|
+
# activeTime => 0,
|
15
|
+
# gps => true,
|
16
|
+
# latitude => 41.765266,
|
17
|
+
# longitude => -72.66858,
|
18
|
+
# heartrate => false,
|
19
|
+
# deviceType => "IPHONE",
|
20
|
+
# prevId => "2000841465",
|
21
|
+
# duration => 2140619,
|
22
|
+
# calories => 393,
|
23
|
+
# fuel => 1320,
|
24
|
+
# steps => 0,
|
25
|
+
# distance => 6.240550994873047,
|
26
|
+
# averageHeartRate => 0.0,
|
27
|
+
# minimumHeartRate => 0.0,
|
28
|
+
# maximumHeartRate => 0.0,
|
29
|
+
# isTopRoute => false,
|
30
|
+
# syncDate => 1340320046000,
|
31
|
+
# snapshots => { ... },
|
32
|
+
# geo => {
|
33
|
+
# coordinate => "41.762526, -72.66285",
|
34
|
+
# waypoints => [ ... ]
|
35
|
+
# },
|
36
|
+
# history => [ ... ]
|
37
|
+
#
|
38
|
+
#
|
39
|
+
# Usage:
|
40
|
+
# activity = nike.activity( 1000001 )
|
41
|
+
#
|
42
|
+
# activity.name # => "RUN ON: 06/21/12 06:28 PM"
|
43
|
+
# activity.deviceType # => "IPHONE"
|
44
|
+
#
|
45
|
+
# points = activity.geo.waypoints
|
46
|
+
# points[0].lat # => 41.75566
|
47
|
+
# points[0].lon # => -72.6529
|
48
|
+
# points[0].ele # => 10.86276
|
49
|
+
#
|
50
|
+
# It's a good idea to inspect the Activity object to determine exactly what data you may want.
|
51
|
+
#
|
52
|
+
# Instance methods defined below manipulate this data into more useful forms.
|
53
|
+
|
54
|
+
class Activity < Hashie::Mash
|
55
|
+
|
56
|
+
KM_TO_MILE = 0.621371192
|
57
|
+
|
58
|
+
# Return an array of waypoints in the form: [ [lat, lon], [lat, lon], [lat, lon] ]
|
59
|
+
def waypoint_list
|
60
|
+
return [] unless self.geo and self.geo.waypoints
|
61
|
+
self.geo.waypoints.collect { |waypoint| [waypoint.lat, waypoint.lon] }
|
62
|
+
end
|
63
|
+
|
64
|
+
# Return activity duration in the form HH:MM:SS.
|
65
|
+
def time
|
66
|
+
a=[1, 1000, 60000, 3600000]*2
|
67
|
+
ms = duration
|
68
|
+
"%02d" % (ms / a[3]).to_s << ":" <<
|
69
|
+
"%02d" % (ms % a[3] / a[2]).to_s << ":" <<
|
70
|
+
"%02d" % (ms % a[2] / a[1]).to_s #<< "." <<
|
71
|
+
#"%03d" % (ms % a[1]).to_s
|
72
|
+
end
|
73
|
+
|
74
|
+
## Activity distance in kilometers.
|
75
|
+
def kilometers
|
76
|
+
self.distance
|
77
|
+
end
|
78
|
+
|
79
|
+
## Activity distance in miles.
|
80
|
+
def miles
|
81
|
+
self.distance * KM_TO_MILE
|
82
|
+
end
|
83
|
+
|
84
|
+
## Activity speed in kilometers per hour.
|
85
|
+
def kmh
|
86
|
+
values = self.speed_values
|
87
|
+
return nil unless values and values.any?
|
88
|
+
|
89
|
+
avg = sum = 0.0
|
90
|
+
values.each { |value| sum += value.to_f }
|
91
|
+
avg = sum / values.size
|
92
|
+
end
|
93
|
+
|
94
|
+
## Activity speed in miles per hour.
|
95
|
+
def mph
|
96
|
+
return nil unless self.kmh
|
97
|
+
self.kmh * KM_TO_MILE
|
98
|
+
end
|
99
|
+
|
100
|
+
## Activity pace in minutes per kilometer.
|
101
|
+
def mpk
|
102
|
+
kmh = self.kmh
|
103
|
+
return nil unless kmh and kmh.is_a?(Float)
|
104
|
+
div = 60.0 / kmh
|
105
|
+
min = div.floor
|
106
|
+
sec = ( ( div - min ) * 60.0 ).round
|
107
|
+
"#{ sprintf("%.2d", min ) }:#{ sprintf("%.2d", sec ) }"
|
108
|
+
end
|
109
|
+
|
110
|
+
## Activity pace in minutes per mile.
|
111
|
+
def mpm
|
112
|
+
mph = self.mph
|
113
|
+
return nil unless mph and mph.is_a?(Float)
|
114
|
+
div = 60.0 / mph
|
115
|
+
min = div.floor
|
116
|
+
sec = ( ( div - min ) * 60.0 )
|
117
|
+
"#{ sprintf("%.2d", min ) }:#{ sprintf("%.2d", sec ) }"
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def speed_values
|
123
|
+
return nil unless self.history
|
124
|
+
values = []
|
125
|
+
self.history.each do |data|
|
126
|
+
values = data['values'] if data.type == 'SPEED'
|
127
|
+
end
|
128
|
+
values
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module NikePlus
|
2
|
+
# Calling NikePlus#activites returns an array of ActivitySummary objects. ActivitySummary data does
|
3
|
+
# not include geographic or historical details (waypoints, speed, pacing intervals). Use NikePlus#activity to
|
4
|
+
# retrieve those. Below is a fairly complete list of the summary data returned for an activity logged
|
5
|
+
# with Nike+ in June 2012:
|
6
|
+
#
|
7
|
+
# name => "RUN ON: 06/21/12 06:28 PM",
|
8
|
+
# activityId => "2003132748",
|
9
|
+
# activityType => "RUN",
|
10
|
+
# timeZone => "-04:00",
|
11
|
+
# timeZoneId => "GMT-04:00",
|
12
|
+
# dstOffset => "00:00",
|
13
|
+
# startTimeUtc => "2012-06-21T18:28:45-04:00",
|
14
|
+
# status => "complete",
|
15
|
+
# activeTime => 0,
|
16
|
+
# gps => true,
|
17
|
+
# latitude => 41.765266,
|
18
|
+
# longitude => -72.66858,
|
19
|
+
# heartrate => false,
|
20
|
+
# deviceType => "IPHONE",
|
21
|
+
# isTopRoute => false,
|
22
|
+
# tags => {
|
23
|
+
# location => "outdoors",
|
24
|
+
# emotion => "amped",
|
25
|
+
# weather => "amped",
|
26
|
+
# terrain => "amped"
|
27
|
+
# },
|
28
|
+
# metrics => {
|
29
|
+
# averageHeartRate => 0.0,
|
30
|
+
# minimumHeartRate => 0.0,
|
31
|
+
# maximumHeartRate => 0.0,
|
32
|
+
# averagePace => 343017.62805217603,
|
33
|
+
# duration => 2140619,
|
34
|
+
# calories => 393,
|
35
|
+
# fuel => 1320,
|
36
|
+
# steps => 0,
|
37
|
+
# distance => 6.240550994873047
|
38
|
+
# }
|
39
|
+
#
|
40
|
+
# Usage:
|
41
|
+
# # Summary
|
42
|
+
# summary = nike.activities.first # => NikePlus::ActivitySummary
|
43
|
+
# summary.name # => "RUN ON: 06/21/12 06:28 PM"
|
44
|
+
# summary.metrics.calories # => 393
|
45
|
+
#
|
46
|
+
# # Full details
|
47
|
+
# activity = nike.activity( summary.activityId ) # => NikePlus::Activity
|
48
|
+
# activity.geo.waypoints
|
49
|
+
# activity.geo.mph
|
50
|
+
#
|
51
|
+
# The fields above not gauranteed. For example, activities logged prior to the Nike+GPS app do not
|
52
|
+
# return GPS or tag data. It's a good idea to inspect the ActivitySummary object to determine exactly what data
|
53
|
+
# you may want.
|
54
|
+
|
55
|
+
class ActivitySummary < Hashie::Mash
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'nike_plus/version'
|
2
|
+
require 'nike_plus/activity'
|
3
|
+
require 'nike_plus/activity_summary'
|
4
|
+
|
5
|
+
module NikePlus
|
6
|
+
class Client
|
7
|
+
|
8
|
+
attr_reader :screenname, :user, :authorization_response
|
9
|
+
|
10
|
+
# Initializes a new NikePlus::Client object.
|
11
|
+
#
|
12
|
+
# Configuration options are:
|
13
|
+
# * +email+ - Nike+ account email address.
|
14
|
+
# * +password+ - Nike+ account password.
|
15
|
+
# * +debug+- Debug flag, set to true for debugging output.
|
16
|
+
#
|
17
|
+
# Example:
|
18
|
+
# nike = NikePlus::Client.new( :email => 'test@nikeplus.com', :password => 'mypassword' )
|
19
|
+
def initialize( options={} )
|
20
|
+
@email = options[:email]
|
21
|
+
@password = options[:password]
|
22
|
+
@debug = options[:debug]
|
23
|
+
|
24
|
+
@agent = Mechanize.new
|
25
|
+
|
26
|
+
url = 'https://secure-nikeplus.nike.com/nsl/services/user/login?app=b31990e7-8583-4251-808f-9dc67b40f5d2&format=json&contentType=plaintext'
|
27
|
+
@authorization_response = post(url, { :email => @email, :password => @password })
|
28
|
+
|
29
|
+
if @authorization_response.serviceResponse.header.success == 'true'
|
30
|
+
@user = @authorization_response.serviceResponse.body.User
|
31
|
+
@screenname = @user.screenName
|
32
|
+
else
|
33
|
+
raise @authorization_response.serviceResponse.header.errorCodes.first.message
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Return an array of NikePlus::ActivitySummary objects. To get full details on the activity use the #activity method.
|
38
|
+
#
|
39
|
+
# Example:
|
40
|
+
# activities = nike.activities # => [NikePlus::ActivitySummary, NikePlus::ActivitySummary]
|
41
|
+
# activity = nike.activity( activities[0]activityId ) # => NikePlus::Activity
|
42
|
+
def activities
|
43
|
+
url = "http://nikeplus.nike.com/plus/activity/running/#{ @screenname }/lifetime/activities?indexStart=0&indexEnd=9999"
|
44
|
+
data = get(url)
|
45
|
+
activity_list = data.activities.any? ? data.activities.collect { |a| NikePlus::ActivitySummary.new( a.activity ) } : []
|
46
|
+
end
|
47
|
+
|
48
|
+
# Return full details on a specific activity.
|
49
|
+
#
|
50
|
+
# Params:
|
51
|
+
# * +id+ - Nike+ Activity ID
|
52
|
+
#
|
53
|
+
# Example:
|
54
|
+
# nike.activity( 123456 ) # => NikePlus::Activity
|
55
|
+
def activity( id )
|
56
|
+
url = "http://nikeplus.nike.com/plus/running/ajax/#{ id }"
|
57
|
+
data = get(url)
|
58
|
+
activity = NikePlus::Activity.new( data.activity ) if data.activity
|
59
|
+
end
|
60
|
+
|
61
|
+
# Return an array of activity ids.
|
62
|
+
#
|
63
|
+
# Example:
|
64
|
+
# nike.activity_ids # => [100, 101, 102, 103]
|
65
|
+
def activity_ids
|
66
|
+
self.activities.collect(&:activityId)
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def get( path )
|
72
|
+
response = @agent.get( path )
|
73
|
+
parse( response )
|
74
|
+
end
|
75
|
+
|
76
|
+
def post( path, params )
|
77
|
+
response = @agent.post( path, params )
|
78
|
+
parse( response )
|
79
|
+
end
|
80
|
+
|
81
|
+
def parse( response )
|
82
|
+
hash = Hashie::Mash.new()
|
83
|
+
begin
|
84
|
+
json = JSON.parse( response.body )
|
85
|
+
hash = Hashie::Mash.new( json )
|
86
|
+
rescue
|
87
|
+
warn "[ERROR] #{ $! }" if @debug
|
88
|
+
end
|
89
|
+
hash
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
data/lib/nike_plus.rb
ADDED
metadata
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nike_plus
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Adam Roth
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-06-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: mechanize
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.5.1
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.5.1
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: json
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.7.3
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.7.3
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: hashie
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.2.0
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.2.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: shoulda
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rdoc
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '3.12'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '3.12'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: bundler
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 1.1.3
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.1.3
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: jeweler
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.8.4
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 1.8.4
|
126
|
+
description: Ruby library for accessing Nike+ data
|
127
|
+
email: adamjroth@gmail.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files:
|
131
|
+
- LICENSE.txt
|
132
|
+
- README.md
|
133
|
+
- README.rdoc
|
134
|
+
files:
|
135
|
+
- lib/nike_plus.rb
|
136
|
+
- lib/nike_plus/activity.rb
|
137
|
+
- lib/nike_plus/activity_summary.rb
|
138
|
+
- lib/nike_plus/client.rb
|
139
|
+
- lib/nike_plus/version.rb
|
140
|
+
- LICENSE.txt
|
141
|
+
- README.md
|
142
|
+
- README.rdoc
|
143
|
+
homepage: http://github.com/aroth/nike_plus
|
144
|
+
licenses:
|
145
|
+
- MIT
|
146
|
+
post_install_message:
|
147
|
+
rdoc_options: []
|
148
|
+
require_paths:
|
149
|
+
- lib
|
150
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
151
|
+
none: false
|
152
|
+
requirements:
|
153
|
+
- - ! '>='
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0'
|
156
|
+
segments:
|
157
|
+
- 0
|
158
|
+
hash: 4523249482076616895
|
159
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
|
+
none: false
|
161
|
+
requirements:
|
162
|
+
- - ! '>='
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
requirements: []
|
166
|
+
rubyforge_project:
|
167
|
+
rubygems_version: 1.8.21
|
168
|
+
signing_key:
|
169
|
+
specification_version: 3
|
170
|
+
summary: Ruby library for accessing Nike+ data
|
171
|
+
test_files: []
|