ruby-fitbit 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  This is a Ruby API for the fitbit and the data at fitbit.com
4
4
 
5
- Currently the gem uses screen scraping to get the data, but it will switch over to use the official API once available. The current set of data it retrieves is pretty limited, but it should grow over time. Originally built just to display a dashboard of my current fitbit stats on my blog.
5
+ Currently the gem uses screen scraping to get the data, but it will switch over to use the official API once available. The current set of data it retrieves is pretty limited, but it should grow over time. Originally built just to display a dashboard of my current fitbit stats on my blog. I started adding additonal data scrapped from the graphs. Which allows me to export the data or do my own charting.
6
6
 
7
7
  == Usage
8
8
 
@@ -17,13 +17,8 @@ Currently the gem uses screen scraping to get the data, but it will switch over
17
17
  fitbit = RubyFitbit.new(EMAIL,PASSWORD)
18
18
 
19
19
  puts "Calories Burned #{fitbit.calories}"
20
- puts "Steps Taken #{fitbit.steps}"
21
- puts "Milkes Walked #{fitbit.miles_walked}"
22
- puts "Activity Levels Durations:"
23
- puts "Sedentary #{fitbit.sedentary_active}"
24
- puts "Lightly #{fitbit.lightly_active}"
25
- puts "Fairly #{fitbit.fairly_active}"
26
- puts "Very #{fitbit.very_active}"
20
+ ...
21
+ look at bin.ruby-fitbit for example usage of coding to the client.
27
22
 
28
23
  output
29
24
  ~/projects/ruby-fitbit(master) > ruby bin/ruby-fitbit my@email.com MYPASS
@@ -38,11 +33,32 @@ Currently the gem uses screen scraping to get the data, but it will switch over
38
33
 
39
34
  done
40
35
 
36
+ advanced usage: Print activity, steps, or calorie data broken down in 5 minute chunks for a given date.
37
+ ~/projects/ruby-fitbit(master) > ruby bin/ruby-fitbit my@email.com MYPASS activity 06/22/2010
38
+ Calories Burned 803
39
+ Steps Taken 552
40
+ Milkes Walked .23
41
+ Activity Levels Durations:
42
+ Sedentary 11hrs 1min
43
+ Lightly 18min
44
+ Fairly 16min
45
+ Very 0min
46
+
47
+ +--------------------------------+------+
48
+ | 0 | 1 |
49
+ +--------------------------------+------+
50
+ | Tue Jun 22 21:50:00 -0400 2010 | 10.0 |
51
+ | Tue Jun 22 05:05:00 -0400 2010 | 0.0 |
52
+ | Tue Jun 22 16:15:00 -0400 2010 | 0.0 |
53
+ | Tue Jun 22 10:40:00 -0400 2010 | 0.0 |
54
+ ...
55
+
56
+ done
57
+
58
+
41
59
 
42
60
  == TODOs
43
61
 
44
- * Get data from any date not just current data
45
- * get the minute by minute calorie chart breakdowns
46
62
  * get food intake tracked etc
47
63
  * add ability for gem to write data to fitbit, such as log and food entries
48
64
  * build everything needed for a nice fitbit IPhone app to use this API.
data/Rakefile CHANGED
@@ -10,7 +10,9 @@ begin
10
10
  gem.email = "Danmayer@gmail.com"
11
11
  gem.homepage = "http://github.com/danmayer/ruby-fitbit"
12
12
  gem.authors = ["Dan Mayer"]
13
- gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
13
+ gem.add_development_dependency "shoulda", ">= 0"
14
+ gem.add_dependency "nokogiri", ">= 1.3.0"
15
+ gem.add_dependency "hirb", ">= 0.2.10"
14
16
  gem.add_dependency "mechanize", ">= 0.9.3"
15
17
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
18
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.1.0
data/bin/ruby-fitbit CHANGED
@@ -1,16 +1,40 @@
1
1
  #! /usr/bin/env ruby
2
- require File.join(File.dirname(__FILE__), '..', 'lib', 'ruby-fitbit')
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'ruby-fitbit')
3
+ require 'hirb'
3
4
 
4
- fitbit = RubyFitbit.new(ARGV[0],ARGV[1])
5
+ if(ARGV[0]!=nil && ARGV[1]!=nil)
6
+ fitbit = RubyFitbit.new(ARGV[0],ARGV[1])
7
+
8
+ puts "Calories Burned #{fitbit.calories}"
9
+ puts "Steps Taken #{fitbit.steps}"
10
+ puts "Milkes Walked #{fitbit.miles_walked}"
11
+ puts "Activity Levels Durations:"
12
+ puts "Sedentary #{fitbit.sedentary_active}"
13
+ puts "Lightly #{fitbit.lightly_active}"
14
+ puts "Fairly # => {fitbit.fairly_active}"
15
+ puts "Very #{fitbit.very_active}"
16
+ end
5
17
 
6
- puts "Calories Burned #{fitbit.calories}"
7
- puts "Steps Taken #{fitbit.steps}"
8
- puts "Milkes Walked #{fitbit.miles_walked}"
9
- puts "Activity Levels Durations:"
10
- puts "Sedentary #{fitbit.sedentary_active}"
11
- puts "Lightly #{fitbit.lightly_active}"
12
- puts "Fairly #{fitbit.fairly_active}"
13
- puts "Very #{fitbit.very_active}"
18
+ if ARGV[2]!=nil
14
19
 
15
- puts ''
16
- puts "done"
20
+ begin
21
+ date = Time.parse(ARGV[3])
22
+ rescue
23
+ date = Time.now
24
+ end
25
+
26
+ case ARGV[2]
27
+ when 'calorie'
28
+ puts "calorie data for data #{date}"
29
+ data = fitbit.get_calorie_data(date)
30
+ when 'activity'
31
+ puts "calorie data for data #{date}"
32
+ data = fitbit.get_activity_score_data(date)
33
+ else
34
+ puts "steps data for data #{date}"
35
+ data = fitbit.get_steps_data(date)
36
+ end
37
+ puts Hirb::Helpers::AutoTable.render(data)
38
+ end
39
+
40
+ puts "done"
data/lib/ruby-fitbit.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'mechanize'
3
+ require 'nokogiri'
3
4
 
4
5
  class RubyFitbit
5
6
 
@@ -8,18 +9,35 @@ class RubyFitbit
8
9
  def initialize(email, pass)
9
10
  @email = email
10
11
  @pass = pass
12
+ @agent = WWW::Mechanize.new #{|a| a.log = Logger.new(STDERR) } #turn on if debugging
13
+ @logged_in = false
11
14
  get_data
12
15
  end
13
16
 
14
- def get_data
15
- agent = WWW::Mechanize.new #{|a| a.log = Logger.new(STDERR) } #turn on if debugging
16
- page = agent.get 'https://www.fitbit.com/login'
17
-
18
- form = page.forms.first
19
- form.email = @email
20
- form.password = @pass
17
+ #todo only login once
18
+ def login
19
+ unless @logged_in
20
+ page = @agent.get 'https://www.fitbit.com/login'
21
+
22
+ form = page.forms.first
23
+ form.email = @email
24
+ form.password = @pass
25
+
26
+ page = @agent.submit(form, form.buttons.first)
27
+
28
+ @userId = page.search("//div[@class='accountLinks']").search("a")[0]['href'].gsub('/user/','')
29
+ # @agent.cookie_jar.jar["www.fitbit.com"]['/']['uid'].value
30
+ # @agent.cookie_jar.jar["www.fitbit.com"]['/']['sid'].value
21
31
 
22
- page = agent.submit(form, form.buttons.first)
32
+ @logged_in = true
33
+ end
34
+ end
35
+
36
+ def get_data(date = Time.now)
37
+ login
38
+
39
+ date = get_fitbit_date_format(date).gsub('-','/')
40
+ page = @agent.get "https://www.fitbit.com/#{date}"
23
41
 
24
42
  @calories = page.search("//div[@class='data']").search("span").children[0].text
25
43
  @steps = page.search("//div[@class='data']").search("span").children[2].text.strip
@@ -30,4 +48,50 @@ class RubyFitbit
30
48
  @very_active = page.search("//div[@class='caption very']/div[@class='number']").text.strip
31
49
  end
32
50
 
51
+ def get_steps_data(date = Time.now)
52
+ get_graph_data('intradaySteps',date)
53
+ end
54
+
55
+ def get_calorie_data(date = Time.now)
56
+ get_graph_data('intradayCaloriesBurned',date)
57
+ end
58
+
59
+ def get_activity_score_data(date = Time.now)
60
+ get_graph_data('intradayActiveScore',date)
61
+ end
62
+
63
+ def get_graph_data(graph_type = 'intradaySteps', date = Time.now, data_version = '2108')
64
+ login
65
+
66
+ date = get_fitbit_date_format(date)
67
+
68
+ params = {:userId => @userId,
69
+ :type => graph_type,
70
+ :version => "amchart",
71
+ :dataVersion => data_version,
72
+ :chart_Type => "column2d",
73
+ :period => "1d",
74
+ :dateTo => date}
75
+
76
+ params = WWW::Mechanize::Util.build_query_string(params)
77
+ uri = "http://www.fitbit.com/graph/getGraphData?#{params}"
78
+
79
+ page = @agent.get uri
80
+ doc = Nokogiri::HTML(page.content)
81
+ minutes_segment = 0
82
+ chart_data = {}
83
+ doc.xpath('//data/chart/graphs/graph/value').each do |ele|
84
+ moment = Time.parse(date)+(5*60*minutes_segment)
85
+ minutes_segment += 1
86
+ chart_data[moment] = ele.child.text
87
+ end
88
+
89
+ chart_data
90
+ end
91
+
92
+ def get_fitbit_date_format(date)
93
+ #fitbit date format expects like so: 2010-06-24
94
+ date = date.strftime("%Y-%m-%d")
95
+ end
96
+
33
97
  end
@@ -0,0 +1,66 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{ruby-fitbit}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Dan Mayer"]
12
+ s.date = %q{2010-07-03}
13
+ s.default_executable = %q{ruby-fitbit}
14
+ s.description = %q{This is a Ruby API for Fitbit.com, currently scraping, but soon will use the officail API (when released)}
15
+ s.email = %q{Danmayer@gmail.com}
16
+ s.executables = ["ruby-fitbit"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.rdoc"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".gitignore",
24
+ "LICENSE",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "bin/ruby-fitbit",
29
+ "lib/ruby-fitbit.rb",
30
+ "ruby-fitbit.gemspec",
31
+ "test/helper.rb",
32
+ "test/test_ruby-fitbit.rb"
33
+ ]
34
+ s.homepage = %q{http://github.com/danmayer/ruby-fitbit}
35
+ s.rdoc_options = ["--charset=UTF-8"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = %q{1.3.6}
38
+ s.summary = %q{This is a Ruby API for Fitbit.com}
39
+ s.test_files = [
40
+ "test/helper.rb",
41
+ "test/test_ruby-fitbit.rb"
42
+ ]
43
+
44
+ if s.respond_to? :specification_version then
45
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
46
+ s.specification_version = 3
47
+
48
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
49
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
50
+ s.add_runtime_dependency(%q<nokogiri>, [">= 1.3.0"])
51
+ s.add_runtime_dependency(%q<hirb>, [">= 0.2.10"])
52
+ s.add_runtime_dependency(%q<mechanize>, [">= 0.9.3"])
53
+ else
54
+ s.add_dependency(%q<shoulda>, [">= 0"])
55
+ s.add_dependency(%q<nokogiri>, [">= 1.3.0"])
56
+ s.add_dependency(%q<hirb>, [">= 0.2.10"])
57
+ s.add_dependency(%q<mechanize>, [">= 0.9.3"])
58
+ end
59
+ else
60
+ s.add_dependency(%q<shoulda>, [">= 0"])
61
+ s.add_dependency(%q<nokogiri>, [">= 1.3.0"])
62
+ s.add_dependency(%q<hirb>, [">= 0.2.10"])
63
+ s.add_dependency(%q<mechanize>, [">= 0.9.3"])
64
+ end
65
+ end
66
+
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 0
8
7
  - 1
9
- version: 0.0.1
8
+ - 0
9
+ version: 0.1.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Dan Mayer
@@ -14,11 +14,11 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-26 00:00:00 -04:00
17
+ date: 2010-07-03 00:00:00 -04:00
18
18
  default_executable: ruby-fitbit
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: thoughtbot-shoulda
21
+ name: shoulda
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
24
  requirements:
@@ -30,9 +30,37 @@ dependencies:
30
30
  type: :development
31
31
  version_requirements: *id001
32
32
  - !ruby/object:Gem::Dependency
33
- name: mechanize
33
+ name: nokogiri
34
34
  prerelease: false
35
35
  requirement: &id002 !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ segments:
40
+ - 1
41
+ - 3
42
+ - 0
43
+ version: 1.3.0
44
+ type: :runtime
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: hirb
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ segments:
54
+ - 0
55
+ - 2
56
+ - 10
57
+ version: 0.2.10
58
+ type: :runtime
59
+ version_requirements: *id003
60
+ - !ruby/object:Gem::Dependency
61
+ name: mechanize
62
+ prerelease: false
63
+ requirement: &id004 !ruby/object:Gem::Requirement
36
64
  requirements:
37
65
  - - ">="
38
66
  - !ruby/object:Gem::Version
@@ -42,7 +70,7 @@ dependencies:
42
70
  - 3
43
71
  version: 0.9.3
44
72
  type: :runtime
45
- version_requirements: *id002
73
+ version_requirements: *id004
46
74
  description: This is a Ruby API for Fitbit.com, currently scraping, but soon will use the officail API (when released)
47
75
  email: Danmayer@gmail.com
48
76
  executables:
@@ -61,6 +89,7 @@ files:
61
89
  - VERSION
62
90
  - bin/ruby-fitbit
63
91
  - lib/ruby-fitbit.rb
92
+ - ruby-fitbit.gemspec
64
93
  - test/helper.rb
65
94
  - test/test_ruby-fitbit.rb
66
95
  has_rdoc: true