garmin_connectr 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  GarminConnectr is a simple Ruby library for accessing data from Garmin Connect. As of 12/2009, Garmin's own Connect API has yet to be released. Until then, this screen scraping lib does the job.
4
4
 
5
+ CHANGELOG:
6
+ 0.6: The Garmin Connect interface has been updated. I have rewritten most of garmin_connectr and added several cucumber tests. The API has changed. Please see the example usage below.
7
+
5
8
  Install:
6
9
 
7
10
  gem install garmin_connectr
@@ -12,23 +15,28 @@ Usage:
12
15
  gc = GarminConnectr.new
13
16
 
14
17
  # Load a specific activity
15
- activity = gc.load( ACTIVITY_ID )
18
+ activity = gc.load_activity( :id => ACTIVITY_ID )
16
19
  puts "#{ g.activity } / #{ g.name } / #{ g.time } / #{ g.distance }"
17
20
 
21
+ puts "Available fields for this activity: #{ g.fields.join(',') }"
22
+
23
+ puts "Splits for this activity:"
24
+ g.activity.splits.each do |split|
25
+ puts "#{ split.split } / #{ split.distance } / #{ split.time }"
26
+ end
27
+
28
+ puts "Split summary:"
29
+ puts "#{ activity.split_summary.time }"
30
+
18
31
  # Load a list of my activities
19
- list = gc.activities( garmin_connect_username, garmin_connect_password )
32
+ list = gc.load_activities( :username => garmin_connect_username,
33
+ :password => garmin_connect_password )
20
34
  list.each do |activity|
21
- activity.load!
22
35
  puts "#{ activity.name } / #{ activity.start_time }"
23
36
  end
24
37
 
25
- # Review activity split/lap data
26
- activity.splits.each do |split|
27
- puts "#{ split['split'] }: Distance: #{ split['distance'] }"
28
- end
29
-
30
38
  See examples/*
31
39
 
32
40
  == Copyright
33
41
 
34
- Copyright (c) 2009 Adam Roth. See LICENSE for details.
42
+ Copyright (c) 2010 Adam Roth. See LICENSE for details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.5
1
+ 0.0.6
data/examples/activity.rb CHANGED
@@ -3,15 +3,14 @@ require '../lib/garmin_connectr.rb'
3
3
  activity_id = 21450277
4
4
 
5
5
  gc = GarminConnectr.new
6
- activity = gc.load( activity_id )
6
+ activity = gc.load_activity( :id => activity_id )
7
7
 
8
8
  puts activity.name
9
- puts " Activity : #{ activity.activity }"
9
+ puts " Activity : #{ activity.activity_type }"
10
10
  puts " Distance : #{ activity.distance }"
11
- puts " Start : #{ activity.start_time }"
12
- puts " Avg HR : #{ activity.avg_hr }"
13
- puts " Splits : #{ activity.splits.count }"
11
+ puts " Start : #{ activity.timestamp }"
12
+ puts " Splits : #{ activity.split_count }"
14
13
 
15
14
  activity.splits.each do |split|
16
- puts "\t#{ split['split'] } : Distance = #{ split['distance'] }"
15
+ puts "\t#{ split.split } : Distance = #{ split.distance }"
17
16
  end
@@ -3,18 +3,16 @@ require '../lib/garmin_connectr.rb'
3
3
  username = 'garmin_connect_username'
4
4
  password = 'garmin_connect_password'
5
5
 
6
- opts = {
7
- :preload => false, ## Automatically fetch additional activity data
8
- :limit => 10 ## Limit to last 10 activites
9
- }
6
+ username = 'adamjroth'
7
+ password = 'xcxcxc98'
10
8
 
11
9
  gc = GarminConnectr.new
12
- activities = gc.activities( username, password, opts )
10
+ activities = gc.load_activity_list( :username => username, :password => password )
13
11
 
14
12
  activities.each do |activity|
15
- puts "#{ activity.name } (#{ activity.activity_id })"
13
+ puts "#{ activity.name }"
16
14
  activity.load!
17
- puts " Activity : #{ activity.activity }"
15
+ puts " Activity : #{ activity.activity_type }"
18
16
  puts " Distance : #{ activity.distance }"
19
- puts " Start : #{ activity.start_time }\n\n"
17
+ puts " Start : #{ activity.timestamp }\n\n"
20
18
  end
@@ -0,0 +1,109 @@
1
+ Scenario: Load Activity
2
+ Given I have loaded activity 30051790
3
+ Then the name should be "MTB - Mesh RDL "
4
+ And the activity_type should be "Mountain Biking"
5
+ And the event_type should be "Training"
6
+ And the timestamp should be "Wed, Apr 14, 2010 1:46 PM"
7
+ And the time should be "00:55:15"
8
+ And the distance should be "5.26 mi"
9
+ And the elevation_gain should be "610 ft"
10
+ And the calories should be "433 C"
11
+ And the avg_temperature should be "74.4 °F"
12
+ And the moving_time should be "00:35:39"
13
+ And the elapsed_time should be "00:55:15"
14
+ And the avg_speed should be "5.7 mph"
15
+ And the avg_moving_speed should be "8.9 mph"
16
+ And the max_speed should be "27.1 mph"
17
+ And the avg_pace should be "10:30 min/mi"
18
+ And the avg_moving_pace should be "06:46 min/mi"
19
+ And the best_pace should be "02:12 min/mi"
20
+ And the elevation_loss should be "615 ft"
21
+ And the min_elevation should be "334 ft"
22
+ And the max_elevation should be "886 ft"
23
+ And the avg_hr_bpm should be "132 bpm"
24
+ And the max_hr_bpm should be "172 bpm"
25
+ And the avg_hr_pom should be "67 % of Max"
26
+ And the max_hr_pom should be "87 % of Max"
27
+ And the avg_hr_hrzones should be "1.0 z"
28
+ And the max_hr_hrzones should be "3.9 z"
29
+ And the avg_bike_cadence should be "84 rpm"
30
+ And the max_bike_cadence should be "166 rpm"
31
+ And the avg_temperature should be "74.4 °F"
32
+ And the min_temperature should be "73.4 °F"
33
+ And the max_temperature should be "78.8 °F"
34
+ And the split_count should be "3"
35
+
36
+ Scenario: Load Activity with Splits
37
+ Given I have loaded activity 30051790
38
+ Then the split_count should be "3"
39
+
40
+ And the time for split 1 should be "00:08:51"
41
+ And the time for split 2 should be "00:26:16"
42
+ And the time for split 3 should be "00:20:07"
43
+
44
+ And the moving_time for split 1 should be "00:05:42"
45
+ And the moving_time for split 2 should be "00:16:18"
46
+ And the moving_time for split 3 should be "00:13:39"
47
+
48
+ And the distance for split 1 should be "1.55"
49
+ And the distance for split 2 should be "1.85"
50
+ And the distance for split 3 should be "1.87"
51
+
52
+ And the elevation_gain for split 1 should be "44"
53
+ And the elevation_gain for split 2 should be "483"
54
+ And the elevation_gain for split 3 should be "82"
55
+
56
+ And the elevation_loss for split 1 should be "368"
57
+ And the elevation_loss for split 2 should be "0"
58
+ And the elevation_loss for split 3 should be "247"
59
+
60
+ And the avg_speed for split 1 should be "10.5"
61
+ And the avg_speed for split 2 should be "4.2"
62
+ And the avg_speed for split 3 should be "5.6"
63
+
64
+ And the avg_moving_speed for split 1 should be "16.3"
65
+ And the avg_moving_speed for split 2 should be "6.8"
66
+ And the avg_moving_speed for split 3 should be "8.2"
67
+
68
+ And the max_speed for split 1 should be "27.1"
69
+ And the max_speed for split 2 should be "13.2"
70
+ And the max_speed for split 3 should be "25.8"
71
+
72
+ And the avg_hr for split 1 should be "111"
73
+ And the avg_hr for split 2 should be "141"
74
+ And the avg_hr for split 3 should be "131"
75
+
76
+ And the max_hr for split 1 should be "135"
77
+ And the max_hr for split 2 should be "172"
78
+ And the max_hr for split 3 should be "166"
79
+
80
+ And the avg_bike_cadence for split 1 should be "92"
81
+ And the avg_bike_cadence for split 2 should be "82"
82
+ And the avg_bike_cadence for split 3 should be "84"
83
+
84
+ And the max_bike_cadence for split 1 should be "146"
85
+ And the max_bike_cadence for split 2 should be "146"
86
+ And the max_bike_cadence for split 3 should be "166"
87
+
88
+ And the calories for split 1 should be "15"
89
+ And the calories for split 2 should be "266"
90
+ And the calories for split 3 should be "152"
91
+
92
+ And the avg_temp for split 1 should be "75.6"
93
+ And the avg_temp for split 2 should be "74.7"
94
+ And the avg_temp for split 3 should be "73.4"
95
+
96
+ And the time for split summary should be "00:55:15"
97
+ And the moving_time for split summary should be "00:35:39"
98
+ And the distance for split summary should be "5.26"
99
+ And the elevation_gain for split summary should be "610"
100
+ And the elevation_loss for split summary should be "615"
101
+ And the avg_speed for split summary should be "5.7"
102
+ And the avg_moving_speed for split summary should be "8.9"
103
+ And the max_speed for split summary should be "27.1"
104
+ And the avg_hr for split summary should be "132"
105
+ And the max_hr for split summary should be "172"
106
+ And the avg_bike_cadence for split summary should be "84"
107
+ And the max_bike_cadence for split summary should be "166"
108
+ And the calories for split summary should be "433"
109
+ And the avg_temp for split summary should be "74.4"
@@ -0,0 +1,6 @@
1
+ Scenario: Load Activity List
2
+ Given I have loaded the activity list for username USERNAME with password PASSWORD
3
+ Then the activity list should contain some activities
4
+ And the first activity should have a name
5
+ And the first activity should have a distance
6
+ And the first activity should have a activity_type
@@ -0,0 +1,12 @@
1
+ Given /^I have loaded the activity list for username ([\w]+) with password ([\w]+)$/ do |username, password|
2
+ @gc = GarminConnectr.new
3
+ @activities = @gc.load_activity_list( :username => username, :password => password )
4
+ end
5
+
6
+ Then /^the activity list should contain some activities$/ do
7
+ @activities.size.should_not == 0
8
+ end
9
+
10
+ Then /^the first activity should have a ([\w]+)$/ do |field|
11
+ @activities.first.send( field.to_sym ).should_not == nil
12
+ end
@@ -0,0 +1,17 @@
1
+ Given /^I have loaded activity 30051790$/ do
2
+ @gc = GarminConnectr.new
3
+ @activity = @gc.load_activity( :id => 30051790 )
4
+ end
5
+
6
+ Then /^the ([\w_]+) should be "([^"]*)"$/ do |field, value|
7
+ value = value.to_i if field.to_s.match(/count/i)
8
+ @activity.send( field ).should == value
9
+ end
10
+
11
+ Then /^the ([\w_]+) for split ([\d\w]+) should be "([^\"]*)"$/ do |field, split, value|
12
+ if split == 'summary'
13
+ @activity.split_summary.send( field ).should == value
14
+ else
15
+ @activity.splits[ split.to_i - 1 ].send( field ).should == value
16
+ end
17
+ end
@@ -0,0 +1 @@
1
+ require 'lib/garmin_connectr.rb'
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{garmin_connectr}
8
- s.version = "0.0.5"
8
+ s.version = "0.0.6"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["aroth"]
12
- s.date = %q{2010-01-01}
12
+ s.date = %q{2010-04-17}
13
13
  s.description = %q{GarminConnectr is a simple Ruby library for accessing data from Garmin Connect.}
14
14
  s.email = %q{adamjroth@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -25,6 +25,11 @@ Gem::Specification.new do |s|
25
25
  "VERSION",
26
26
  "examples/activity.rb",
27
27
  "examples/activity_list.rb",
28
+ "features/activity.feature",
29
+ "features/activity_list.feature",
30
+ "features/step_definitions/activity_list_steps.rb",
31
+ "features/step_definitions/activity_steps.rb",
32
+ "features/support/env.rb",
28
33
  "garmin_connectr.gemspec",
29
34
  "lib/garmin_connectr.rb",
30
35
  "test/garmin_connectr_test.rb"
@@ -32,7 +37,7 @@ Gem::Specification.new do |s|
32
37
  s.homepage = %q{http://github.com/aroth/garmin_connectr}
33
38
  s.rdoc_options = ["--charset=UTF-8"]
34
39
  s.require_paths = ["lib"]
35
- s.rubygems_version = %q{1.3.5}
40
+ s.rubygems_version = %q{1.3.6}
36
41
  s.summary = %q{GarminConnectr is a simple Ruby library for accessing data from Garmin Connect.}
37
42
  s.test_files = [
38
43
  "test/garmin_connectr_test.rb",
@@ -1,32 +1,28 @@
1
1
  require 'rubygems'
2
2
  require 'nokogiri'
3
3
  require 'open-uri'
4
- require 'mechanize'
5
4
  require 'fastercsv'
5
+ require 'simple-rss'
6
+ require 'mechanize'
6
7
 
7
8
  class GarminConnectr
8
9
 
9
- attr_reader :activity_list
10
-
11
10
  def initialize
12
- @activity_list = []
13
11
  end
14
12
 
15
- ## Load a specific Garmin Connect activity. See GarminConnectActivity rdoc for more information.
16
- def load( activity_id )
17
- activity = GarminConnectActivity.new( activity_id )
13
+ def load_activity( opts )
14
+ id = opts[:id]
15
+ activity = GarminConnectrActivity.new( :id => id )
18
16
  activity.load!
19
17
  end
20
18
 
21
- ## Returns an array of GarminActivity objects.
22
- ##
23
- ## Options:
24
- ## :preload [true/false] - Automatically fetch additional activity data for each activity returned (slower)
25
- ## :limit - Limit the number of activites returned (default: 50)
26
- def activities( username, password, opts={} )
27
- @activity_list = []
19
+ def load_activity_list( opts )
20
+ username = opts[:username]
21
+ password = opts[:password]
28
22
  limit = opts[:limit] || 50
29
23
 
24
+ activity_list = []
25
+
30
26
  agent = WWW::Mechanize.new { |agent| agent.user_agent_alias = 'Mac Safari' }
31
27
  page = agent.get('http://connect.garmin.com/signin')
32
28
  form = page.form('login')
@@ -42,112 +38,130 @@ class GarminConnectr
42
38
  name = act.search('span').inner_html
43
39
  act[:href].match(/\/([\d]+)$/)
44
40
  aid = $1
45
-
46
- activity = GarminConnectActivity.new( aid, name )
47
- activity.load! if opts[:preload]
48
- @activity_list << activity
41
+ activity = GarminConnectrActivity.new( :id => aid, :name => name )
42
+ activity_list << activity
49
43
  end
50
- @activity_list
44
+ activity_list
51
45
  end
52
46
 
53
47
  end
54
48
 
55
- class GarminConnectActivity
49
+ class GarminConnectrActivity
50
+ attr_accessor :id, :data, :splits, :split_summary, :loaded
56
51
 
57
- attr_reader :activity_id, :loaded, :name, :url, :device, :start_time, :activity, :event, :time, :distance, :calories
58
- attr_reader :avg_speed, :max_speed, :avg_power, :max_power, :elevation_gain, :elevation_loss, :min_elevation, :max_elevation, :avg_hr, :max_hr, :avg_bike_cadence, :max_bike_cadence, :avg_temperature, :min_temperature, :max_temperature, :avg_pace, :best_pace
59
-
60
- FIELDS = ['Avg Speed', 'Max Speed', 'Avg Power', 'Max Power', 'Elevation Gain', 'Elevation Loss', 'Min Elevation', 'Max Elevation', 'Avg HR', 'Max HR', 'Avg Bike Cadence', 'Max Bike Cadence', 'Avg Temperature', 'Min Temperature', 'Max Temperature', 'Avg Pace', 'Best Pace']
61
-
62
- def initialize( activity_id, name=nil )
63
- @activity_id = activity_id
64
- @name = name unless name.nil?
65
- @loaded = false
66
- @fields = ['name', 'url', 'device', 'start_time']
52
+ def initialize( opts )
53
+ @id = opts[:id]
67
54
  @splits = []
68
- @split_summary = {}
55
+ @data = {}
56
+ @data[:name] = opts[:name]
57
+ @loaded = false
69
58
  end
70
-
71
- ## Fetch activity details. This will happen automatically if using GarminConnect#load. You will have
72
- ## call load! explicity on the activities returned by GarminConnect#activities unless the :preload option is set to true.
59
+
73
60
  def load!
74
- @doc = Nokogiri::HTML(open("http://connect.garmin.com/activity/#{ @activity_id }"))
75
- @name = @doc.search('#activityName').inner_html
76
- @url = "http://connect.garmin.com/activity/#{ @activity_id }"
77
- @device = @doc.search('.additionalInfoContent span').inner_html.gsub('Device: ','')
78
- @start_time = @doc.search('#activityStartDate').children[0].to_s.gsub(/[\n]+/,'')
79
- @loaded = true
80
-
81
- # Summary Fields (TODO: clean up)
82
- @activity = @doc.search('#activityTypeValue').inner_html.gsub(/[\n]+/,'').strip rescue nil
83
- @event = @doc.search('#eventTypeValue').inner_html.gsub(/[\n]+/,'').strip rescue nil
84
- @time = @doc.css('#summaryTotalTime')[0].parent.children.search('.summaryField').inner_html.strip rescue nil
85
- @distance = @doc.css('#summaryDistance')[0].parent.children.search('.summaryField').inner_html.strip rescue nil
86
- @calories = @doc.css('#summaryCalories')[0].parent.children.search('.summaryField').inner_html.strip rescue nil
87
-
88
- # Tabbed Fields
89
- FIELDS.each do |field|
90
- name = field.downcase.gsub(' ','_')
91
- self.instance_variable_set("@#{ name }", self.send( :tab_data, field ) )
92
- end
93
-
94
- # Splits - parse CSV
95
- @doc = open("http://connect.garmin.com/csvExporter/#{ @activity_id }.csv")
96
- @splits = []
97
- @split_summary = {}
61
+ url = "http://connect.garmin.com/activity/#{ @id }"
62
+ doc = Nokogiri::HTML(open(url))
98
63
 
99
- @keys = []
100
- @csv = FasterCSV.parse( @doc.read )
101
- @csv[0].each do |key|
102
- @keys.push key.downcase.gsub(' ','_') if key.is_a?(String)
64
+ # HR cell name manipulation
65
+ ['bpm', 'pom', 'hrZones'].each do |hr|
66
+ doc.css("##{ hr }Summary td").each do |e|
67
+ e.inner_html = "Max HR #{ hr.upcase }:" if e.inner_html =~ /Max HR/i
68
+ e.inner_html = "Avg HR #{ hr.upcase }:" if e.inner_html =~ /Avg HR/i
69
+ end
103
70
  end
104
- ## Data Rows
105
- @csv[1, @csv.length - 2].each_with_index do |row, index|
106
- split = {}
107
- @keys.each_with_index do |key, key_index|
108
- split[ key ] = row[ key_index ]
71
+
72
+ @scrape = {
73
+ :details => {
74
+ :name => doc.css('#activityName').inner_html,
75
+ :activity_type => doc.css('#activityTypeValue').inner_html.gsub(/[\n\t]+/,''),
76
+ :event_type => doc.css('#eventTypeValue').inner_html.gsub(/[\n\t]+/,''),
77
+ :timestamp => doc.css('#timestamp').inner_html.gsub(/[\n\t]+/,''),
78
+ :embed => doc.css('.detailsEmbedCode').attr('value').value
79
+ },
80
+ :summaries => {
81
+ :overall => { :css => '#detailsOverallBox' },
82
+ :timing => { :css => '#detailsTimingBox' },
83
+ :elevation => { :css => '#detailsElevationBox' },
84
+ :heart_rate => { :css => '#detailsHeartRateBox' },
85
+ :cadence => { :css => '#detailsCadenceBox' },
86
+ :temperature => { :css => '#detailsTemperatureBox' },
87
+ :power => { :css => '#detailsPowerBox' }
88
+ }
89
+ }
90
+
91
+ @scrape[:details][:split_count] = doc.css('.detailsLapsNumber')[0].inner_html.to_i rescue 0
92
+
93
+ @scrape[:details].each { |k,v| @data[k] = v }
94
+ @scrape[:summaries].each do |k,v|
95
+ doc.css("#{ v[:css] } td").each do |e|
96
+ if e.inner_html =~ /:[ ]?$/
97
+ key = e.inner_html.downcase.gsub(/ $/,'').gsub(/:/,'').gsub(' ','_').to_sym
98
+ @data[key] = e.next.next.inner_html.strip
99
+ end
109
100
  end
110
- @splits << split
111
101
  end
112
- ## Summary Row
113
- @keys.each_with_index do |key, key_index|
114
- @split_summary[ key ] = @csv.last[ key_index ]
102
+
103
+ ## Splits
104
+ if self.split_count > 0
105
+ load_splits!
115
106
  end
116
-
107
+
108
+ @loaded = true
117
109
  self
118
110
  end
119
111
 
120
- ## Returns an array of hashes detailing activity splits (laps). Attributes may include:
121
- ##
122
- ## split
123
- ## time
124
- ## distance
125
- ## elevation_gain
126
- ## elevation_loss
127
- ## avg_speed
128
- ## max_speed
129
- ## avg_hr
130
- ## max_hr
131
- ## avg_bike_cadence
132
- ## max_bike_cadence
133
- ## calories
134
- ## avg_temp
135
- ## max_power
136
- ## avg_power
112
+ def fields
113
+ @data.keys
114
+ end
115
+
137
116
  def splits
117
+ self.load! unless @loaded
138
118
  @splits
139
119
  end
120
+
121
+ private
122
+
123
+ def load_splits!
124
+ doc = open("http://connect.garmin.com/csvExporter/#{ @id }.csv")
125
+
126
+ keys = []
127
+ csv = FasterCSV.parse( doc.read )
128
+ csv[0].each do |key|
129
+ keys.push key.downcase.gsub(' ','_') if key.is_a?(String)
130
+ end
131
+
132
+ csv[1, csv.length-1].each_with_index do |row, index|
133
+ split = GarminConnectrActivitySplit.new
134
+ keys.each_with_index do |key, key_index|
135
+ split.data[ key.to_sym ] = row[ key_index ].strip
136
+ end
137
+ index < csv.length - 2 ? @splits << split : @split_summary = split
138
+ end
139
+ end
140
140
 
141
- ## Returns a hash of activity splits/laps summary. See splits rdoc for possible attributes.
142
- def split_summary
143
- @split_summary
141
+ def method_missing(name)
142
+ self.load! if !@data[name.to_sym] and !@loaded # lazy loading
143
+ @data[name.to_sym]
144
144
  end
145
145
 
146
+ end
147
+
148
+ class GarminConnectrActivitySplit
149
+
150
+ attr_reader :index, :data
151
+
152
+ def initialize( opts={} )
153
+ @index = opts[:index]
154
+ @data = {}
155
+ end
156
+
157
+ def fields
158
+ @data.keys
159
+ end
160
+
146
161
  private
147
162
 
148
- def tab_data( label )
149
- label += ":" unless label.match(/:$/)
150
- @doc.css('.label').to_a.delete_if { |e| e.inner_html != label }.first.parent.children.search('.field').inner_html.strip rescue nil
163
+ def method_missing(name)
164
+ @data[name.to_sym]
151
165
  end
152
-
166
+
153
167
  end
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: garmin_connectr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 6
9
+ version: 0.0.6
5
10
  platform: ruby
6
11
  authors:
7
12
  - aroth
@@ -9,7 +14,7 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-01-01 00:00:00 -05:00
17
+ date: 2010-04-17 00:00:00 -04:00
13
18
  default_executable:
14
19
  dependencies: []
15
20
 
@@ -31,6 +36,11 @@ files:
31
36
  - VERSION
32
37
  - examples/activity.rb
33
38
  - examples/activity_list.rb
39
+ - features/activity.feature
40
+ - features/activity_list.feature
41
+ - features/step_definitions/activity_list_steps.rb
42
+ - features/step_definitions/activity_steps.rb
43
+ - features/support/env.rb
34
44
  - garmin_connectr.gemspec
35
45
  - lib/garmin_connectr.rb
36
46
  - test/garmin_connectr_test.rb
@@ -47,18 +57,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
47
57
  requirements:
48
58
  - - ">="
49
59
  - !ruby/object:Gem::Version
60
+ segments:
61
+ - 0
50
62
  version: "0"
51
- version:
52
63
  required_rubygems_version: !ruby/object:Gem::Requirement
53
64
  requirements:
54
65
  - - ">="
55
66
  - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
56
69
  version: "0"
57
- version:
58
70
  requirements: []
59
71
 
60
72
  rubyforge_project:
61
- rubygems_version: 1.3.5
73
+ rubygems_version: 1.3.6
62
74
  signing_key:
63
75
  specification_version: 3
64
76
  summary: GarminConnectr is a simple Ruby library for accessing data from Garmin Connect.