basis-band 0.0.4 → 0.1.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/README.md CHANGED
@@ -1,23 +1,31 @@
1
1
  # Basis API Access Gem
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/basis-band.png)](http://badge.fury.io/rb/basis-band)
4
+
3
5
  Includes a command line tool that can be used to either capture the raw JSON
4
6
  responses from app.mybasis.com, or to convert the metrics from the API
5
7
  responses into CSV.
6
8
 
7
- First off you need to find your userid. The command line tool now provides an
8
- option to output your userid given a username and password on the command line.
9
- Just pass the username and password joined with a colon (:) using the -l
10
- option and you'll get your userid back as output. Assuming your username is
9
+ ## Usage
10
+
11
+ There are two different versions of the API available at app.mybasis.com. The
12
+ V1 API (which holds most of the detailed data about heartrate and steps) uses a
13
+ user id, while the V2 API (which holds information about activities like
14
+ walking, running or biking state) uses an access token. You can use the -l
15
+ option to the command line tool to dump out both values.
16
+ Just pass the username and password joined with a colon (:).
17
+ Assuming your username is
11
18
  'mikerowehl@gmail.com' and your password is 'pppppp' the command would look
12
19
  like this:
13
20
 
14
21
  ```
15
22
  > miker $ basis-band -l mikerowehl@gmail.com:pppppp
16
- 1234567890abcdef12345678
23
+ ID for V1 api: 1234567890abcdef12345678
24
+ token for V2 api: abcdef1234567890abcdef1234567890
17
25
  ```
18
26
 
19
- In this example the userid returned is '1234567890abcdef12345678'. In the rest
20
- of the examples the userid is abbreviated to 'xxxxx'.
27
+ In this example the userid returned is '1234567890abcdef12345678' and the
28
+ token is 'abcdef1234567890abcdef1234567890'.
21
29
 
22
30
  If you pass -u and -d options the raw text will be fetched from the API and
23
31
  output on standard output:
@@ -50,7 +58,29 @@ t,state,skin_temp,heartrate,air_temp,calories,gsr,steps
50
58
  ...
51
59
  ```
52
60
 
53
- For additional information see the PHP example at
54
- [https://github.com/btroia/basis-data-export](https://github.com/btroia/basis-data-export).
55
- That example includes instructions for finding your userid.
61
+ If you want the activity info for a given day pass in the access token using
62
+ -t and the date you want with -d:
56
63
 
64
+ ```
65
+ > miker $ basis-band -t abcdef1234567890abcdef1234567890 -d 2013-11-05 | python -mjson.tool
66
+ {
67
+ "content": {
68
+ "activities": [
69
+ {
70
+ "actual_seconds": 1323,
71
+ "calories": 118.8,
72
+ "end_time": {
73
+ "iso": "2013-11-05T22:38:25Z",
74
+ "time_zone": {
75
+ "name": "America/Los_Angeles",
76
+ "offset": -480
77
+ },
78
+ "timestamp": 1383691105
79
+ },
80
+ "heart_rate": {
81
+ "avg": null,
82
+ "max": null,
83
+ "min": null
84
+ },
85
+ ...
86
+ ```
data/bin/basis-band CHANGED
@@ -26,21 +26,47 @@ OptionParser.new do |opts|
26
26
  opts.on("-c", "--[no-]csv", "Output CSV format") do |c|
27
27
  options[:csv] = c
28
28
  end
29
+ opts.on("-C", "--cachedir DIR", "Directory to use to cache results") do |c|
30
+ options[:cachedir] = c
31
+ end
29
32
  opts.on("-l", "--login username:password", "Login and print user id") do |l|
30
33
  options[:login] = l
31
34
  end
35
+ opts.on("-s", "--summary", "Summarize all the data from the cache") do |s|
36
+ options[:summary] = s
37
+ end
38
+ opts.on("-t", "--token TOKEN", "Token for v2 API access") do |t|
39
+ options[:token] = t
40
+ end
32
41
  end.parse!
33
42
 
34
43
  if options[:login]
35
44
  (u,p) = options[:login].split(":", 2)
36
- a = ApiAuth.new
37
- puts a.login(u, p)
45
+ token, id = ApiAuth.new.login(u, p)
46
+ puts "ID for V1 api: #{id}"
47
+ puts "token for V2 api: #{token}"
48
+ exit
49
+ end
50
+
51
+ b = BasisBand.new(options[:userid])
52
+ if options[:cachedir]
53
+ b.set_cache_dir(options[:cachedir])
54
+ end
55
+
56
+ if options[:summary]
57
+ all = b.data_for_all
58
+ all.each do |k,v|
59
+ puts "Data for day #{k}"
60
+ t = ApiResponseModel.new(v).summary
61
+ puts " average air_temp = #{t["air_temp"]["avg"]}"
62
+ end
38
63
  exit
39
64
  end
40
65
 
41
66
  if options[:userid] and options[:date]
42
- b = BasisBand.new(options[:userid])
43
67
  raw = b.data_for_day(options[:date])
68
+ elsif options[:token] and options[:date]
69
+ raw = b.fetch_activities_for_day(options[:date], options[:token])
44
70
  else
45
71
  raw = $stdin.read
46
72
  end
data/lib/basis-band.rb CHANGED
@@ -4,12 +4,66 @@ require 'basis-band/api-auth'
4
4
  require 'basis-band/api-response-model'
5
5
 
6
6
  class BasisBand
7
+ @cache_dir = nil
8
+
7
9
  def initialize(userid)
8
10
  @userid = userid
9
11
  end
10
12
 
13
+ def set_cache_dir(dir)
14
+ @cache_dir = dir
15
+ end
16
+
11
17
  def data_for_day(date)
18
+ r = cached_value_for_day(date)
19
+ if !r
20
+ r = fetch_value_for_day(date)
21
+ end
22
+ r
23
+ end
24
+
25
+ def data_for_all
26
+ all = all_cache_files.collect do |f|
27
+ d = File.basename(f, ".json")
28
+ [d, cached_value_for_day(d)]
29
+ end
30
+ Hash[all]
31
+ end
32
+
33
+ def cache_filename(date)
34
+ File.join(@cache_dir, date + ".json")
35
+ end
36
+
37
+ def all_cache_files()
38
+ Dir[File.join(@cache_dir, "*.json")]
39
+ end
40
+
41
+ def cached_value_for_day(date)
42
+ raw = nil
43
+ begin
44
+ File.open(cache_filename(date), "r") { |f|
45
+ raw = f.read
46
+ }
47
+ rescue
48
+ # ignore exception
49
+ end
50
+ raw
51
+ end
52
+
53
+ def fetch_value_for_day(date)
54
+ f = ApiFetch.new()
55
+ raw = f.get_day(@userid, date)
56
+ if raw && @cache_dir
57
+ File.open(cache_filename(date), "w") { |f|
58
+ f.write(raw)
59
+ }
60
+ end
61
+ raw
62
+ end
63
+
64
+ def fetch_activities_for_day(date, token)
12
65
  f = ApiFetch.new()
13
- f.get_day(@userid, date)
66
+ raw = f.get_activities(token, date)
67
+ raw
14
68
  end
15
69
  end
@@ -7,7 +7,7 @@ class ApiAuth
7
7
 
8
8
  def login(username, password)
9
9
  token = auth_request(username, password)
10
- get_user_id(token)
10
+ [token, get_user_id(token)]
11
11
  end
12
12
 
13
13
  def auth_request(username, password)
@@ -31,6 +31,10 @@ class ApiFetch
31
31
  "https://app.mybasis.com/api/v1/chart/#{userid}.json?#{f}&#{m}"
32
32
  end
33
33
 
34
+ def activities_url(date)
35
+ "https://app.mybasis.com/api/v2/users/me/days/#{date}/activities?expand=activities&type=run,walk,bike"
36
+ end
37
+
34
38
  def https_fetch(url)
35
39
  u = URI.parse(url)
36
40
  http = Net::HTTP.new(u.host, u.port)
@@ -40,8 +44,23 @@ class ApiFetch
40
44
  http.request(request).body
41
45
  end
42
46
 
47
+ def https_fetch_v2(url, token)
48
+ u = URI.parse(url)
49
+ http = Net::HTTP.new(u.host, u.port)
50
+ http.use_ssl = true
51
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
52
+ request = Net::HTTP::Get.new(u.request_uri)
53
+ request.add_field('Cookie', "access_token=#{token}; scope=login")
54
+ http.request(request).body
55
+ end
56
+
43
57
  def get_day(userid, date, summary = true, body_states = true, skip_metrics = [])
44
58
  res = https_fetch(url(userid, date, summary, body_states, skip_metrics))
45
59
  res
46
60
  end
61
+
62
+ def get_activities(token, date)
63
+ res = https_fetch_v2(activities_url(date), token)
64
+ res
65
+ end
47
66
  end
@@ -38,4 +38,16 @@ class ApiResponseModel
38
38
  hash_for_minute(x)
39
39
  }
40
40
  end
41
+
42
+ def metric_summary(metric)
43
+ {"avg" => @json["metrics"][metric]["avg"]}
44
+ end
45
+
46
+ def summary
47
+ res = {}
48
+ for m in @json["metrics"].keys
49
+ res[m] = metric_summary(m)
50
+ end
51
+ res
52
+ end
41
53
  end
@@ -1,3 +1,3 @@
1
1
  module BasisBandMeta
2
- VERSION = '0.0.4'
2
+ VERSION = '0.1.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: basis-band
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-28 00:00:00.000000000 Z
12
+ date: 2013-11-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json