ruby-fitbit 0.4.1 → 0.5.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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.5.0
@@ -7,7 +7,8 @@ if(ARGV[0]!=nil && ARGV[1]!=nil)
7
7
  fitbit = RubyFitbit.new(ARGV[0],ARGV[1])
8
8
 
9
9
  #testing some in progress API methods
10
- fitbit.submit_food_log({:food => 'wrap', :unit => '1 serving'})
10
+ #fitbit.submit_food_log({:food => 'wrap', :unit => '1 serving'})
11
+ #puts fitbit.submit_weight_log({:unit => 'lbs', :weight => '131'})
11
12
  #fitbit.get_food_items
12
13
  #puts fitbit.get_eaten_calories[:calories_xml]
13
14
  #exit 1
@@ -45,6 +46,8 @@ if ARGV[2]!=nil
45
46
  when 'activity'
46
47
  puts "calorie data for data #{date}"
47
48
  data = fitbit.get_activity_score_data(date)
49
+ when 'weight'
50
+ puts "logging weight"
48
51
  when 'summary'
49
52
  #do nothing just print the summary above
50
53
  else
@@ -72,7 +72,30 @@ class RubyFitbit
72
72
  form.mealTypeId = meal_type
73
73
  result = @agent.submit(form, form.buttons.first)
74
74
  end
75
-
75
+
76
+ def submit_weight_log(options = {})
77
+ login
78
+
79
+ weight_units = {:lbs => "US", :stone => "UK", :kg => "METRIC"}
80
+
81
+ date = options.fetch(:date) {Time.now}
82
+ date = get_fitbit_date_format(date)
83
+
84
+ unit = options[:unit]
85
+ unit_id = weight_units[unit.to_sym]
86
+ raise "#{unit} isn't one of Fitbit's units. Try #{weight_units.keys.join(", ")} instead." unless unit_id
87
+
88
+ page = @agent.get 'http://www.fitbit.com/weight'
89
+
90
+ form = page.forms[1]
91
+ form.action="/measure/measurements?apiFormat=json&log=on&date=#{date}"
92
+ form.send(options[:unit].to_sym, options[:weight])
93
+ form.weightState = unit_id
94
+ form.bodyFat = options[:percentage_fat]
95
+
96
+ result = @agent.submit(form, form.buttons.first)
97
+ end
98
+
76
99
  def get_unit_id_for_unit(unit)
77
100
  unit_id = nil
78
101
  unit_type = unit.match(/\d+ (.*)/)[1]
@@ -127,22 +150,33 @@ class RubyFitbit
127
150
  return @cached_data[date] if @cached_data[date]
128
151
 
129
152
  page = @agent.get "https://www.fitbit.com/#{date}"
130
-
131
- calories = page.search("//div[@class='data']").search("span").children[0].text
132
- steps = page.search("//div[@class='data']").search("span").children[2].text.strip
133
- miles_walked = page.search("//div[@class='data']").search("span").children[3].text.strip
134
- sedentary_active = page.search("//div[@class='sedentary caption']/div[@class='number']").text.strip
135
- lightly_active = page.search("//div[@class='lightly caption']/div[@class='number']").text.strip
136
- fairly_active = page.search("//div[@class='caption fairly']/div[@class='number']").text.strip
137
- very_active = page.search("//div[@class='caption very']/div[@class='number']").text.strip
153
+
138
154
  data = {}
139
- data['calories'] = calories.to_i
140
- data['steps'] = steps.to_i
141
- data['miles_walked'] = miles_walked.to_f
142
- data['sedentary_active'] = sedentary_active
143
- data['lightly_active'] = lightly_active
144
- data['fairly_active'] = fairly_active
145
- data['very_active'] = very_active
155
+ data['calories'] = 0
156
+ data['steps'] = 0
157
+ data['miles_walked'] = 0.0
158
+
159
+ page.search("//div[@class='data']").each do |datadiv|
160
+ if datadiv.text.match(/calories burned$/)
161
+ data['calories'] = datadiv.search("span").first.text.to_i
162
+ elsif datadiv.text.match(/calories eaten/)
163
+ data['calories_eaten'] = datadiv.search("span").first.text.to_i
164
+ elsif datadiv.text.match(/steps taken/)
165
+ data['steps'] = datadiv.search("span").first.text.to_i
166
+ elsif datadiv.text.match(/miles traveled/)
167
+ data['miles_walked'] = datadiv.search("span").first.text.to_f
168
+ end
169
+ end
170
+
171
+ data['sedentary_active'] = page.search("//div[@class='sedentary caption']/div[@class='number']").text.strip
172
+ data['lightly_active'] = page.search("//div[@class='lightly caption']/div[@class='number']").text.strip
173
+ data['fairly_active'] = page.search("//div[@class='caption fairly']/div[@class='number']").text.strip
174
+ data['very_active'] = page.search("//div[@class='caption very']/div[@class='number']").text.strip
175
+ data['sedentary_active_in_minutes'] = get_minutes_from_time(data['sedentary_active'])
176
+ data['lightly_active_in_minutes'] = get_minutes_from_time(data['lightly_active'])
177
+ data['fairly_active_in_minutes'] = get_minutes_from_time(data['fairly_active'])
178
+ data['very_active_in_minutes'] = get_minutes_from_time(data['very_active'])
179
+
146
180
  @cached_data[date] = data
147
181
  data
148
182
  end
@@ -167,11 +201,10 @@ class RubyFitbit
167
201
  data['calories'] = 0
168
202
  data['steps'] = 0
169
203
  data['miles_walked'] = 0
170
- # TODO these aren't numbers but times need to convert all to minutes and then back
171
- #data['sedentary_active'] = 0
172
- #data['lightly_active'] = 0
173
- #data['fairly_active'] = 0
174
- #data['very_active'] = 0
204
+ data['sedentary_active_in_minutes'] = 0
205
+ data['lightly_active_in_minutes'] = 0
206
+ data['fairly_active_in_minutes'] = 0
207
+ data['very_active_in_minutes'] = 0
175
208
  days = 0
176
209
 
177
210
  days_data = get_aggregated_data(start_date, end_date)
@@ -236,4 +269,14 @@ class RubyFitbit
236
269
  date = date.strftime("%Y-%m-%d")
237
270
  end
238
271
 
272
+ def get_minutes_from_time(str)
273
+ if m = str.to_s.strip.match(/^((\d+)hrs?)? ?((\d+)min)?$/)
274
+ hrs = m[1].to_i * 60
275
+ mins = m[3].to_i
276
+ return (hrs + mins)
277
+ end
278
+
279
+ return 0
280
+ end
281
+
239
282
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ruby-fitbit}
8
- s.version = "0.4.1"
8
+ s.version = "0.5.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Dan Mayer"]
12
- s.date = %q{2011-01-02}
12
+ s.date = %q{2011-02-13}
13
13
  s.default_executable = %q{ruby-fitbit}
14
14
  s.description = %q{This is a Ruby API for Fitbit.com, currently scraping, but soon will use the officail API (when released)}
15
15
  s.email = %q{Danmayer@gmail.com}
@@ -77,10 +77,16 @@ END
77
77
  assert_equal 1928, data['calories'], "wrong calories"
78
78
  assert_equal 7821, data['steps'], "wrong steps"
79
79
  assert_equal 3.38, data['miles_walked'], "wrong miles"
80
- assert_equal "16hrs 58min", data['sedentary_active'], "wrong sedentary"
81
- assert_equal "1hr 42min", data['lightly_active'], "wrong lightly"
82
- assert_equal "1hr 51min", data['fairly_active'], "wrong fairly"
80
+
81
+
82
+ assert_equal "16hrs 58min", data['sedentary_active'], "wrong sedentary"
83
+ assert_equal "1hr 42min", data['lightly_active'], "wrong lightly"
84
+ assert_equal "1hr 51min", data['fairly_active'], "wrong fairly"
83
85
  assert_equal "17min", data['very_active'], "wrong very"
86
+ assert_equal 1018, data['sedentary_active_in_minutes'], "wrong sedentary"
87
+ assert_equal 102, data['lightly_active_in_minutes'], "wrong lightly"
88
+ assert_equal 111, data['fairly_active_in_minutes'], "wrong fairly"
89
+ assert_equal 17, data['very_active_in_minutes'], "wrong very"
84
90
  end
85
91
 
86
92
  should "use VCR successfully" do
@@ -96,8 +102,25 @@ END
96
102
  assert_equal 4.61, data['miles_walked'], "wrong miles"
97
103
  assert_equal "18hrs 26min", data['sedentary_active'], "wrong sedentary"
98
104
  assert_equal "1hr 17min", data['lightly_active'], "wrong lightly"
99
- assert_equal "1hr 29min", data['fairly_active'], "wrong fairly"
105
+ assert_equal "1hr 29min", data['fairly_active'], "wrong fairly"
100
106
  assert_equal "42min", data['very_active'], "wrong very"
107
+ assert_equal 1106, data['sedentary_active_in_minutes'], "wrong sedentary"
108
+ assert_equal 77, data['lightly_active_in_minutes'], "wrong lightly"
109
+ assert_equal 89, data['fairly_active_in_minutes'], "wrong fairly"
110
+ assert_equal 42, data['very_active_in_minutes'], "wrong very"
111
+ end
112
+
113
+ should "convert times properly" do
114
+ {
115
+ "18hrs 26min" => 1106,
116
+ "1hr 17min" => 77,
117
+ "42min" => 42,
118
+ "3hrs " => 180,
119
+ }.each do |t,m|
120
+ fitbit = RubyFitbit.new("fake@fake.com","pass")
121
+ mins = fitbit.get_minutes_from_time(t)
122
+ assert_equal m, mins, "wrong minutes for #{t}"
123
+ end
101
124
  end
102
125
 
103
126
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 4
8
- - 1
9
- version: 0.4.1
7
+ - 5
8
+ - 0
9
+ version: 0.5.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Dan Mayer
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-01-02 00:00:00 -05:00
17
+ date: 2011-02-13 00:00:00 -05:00
18
18
  default_executable: ruby-fitbit
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency