fitbyte 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4fc521fa00248d4a2349cbf48840ca97bc567e5d
4
- data.tar.gz: e7d534a59e218901e7c81b36e4ad8cf4a2a7712c
3
+ metadata.gz: 224202239ccc8345b4cced0077f4f6deb3aac0e6
4
+ data.tar.gz: 172d0d9768c89d91514612791138db1a16471ef6
5
5
  SHA512:
6
- metadata.gz: 3af70dae21133cf999be7567e23859fa5d16edf7179f7cb86c55a3be0287737edb3ee1789261df5d6c472a57731d5ad10a08c9bdef46272e2eabfd3bdbdb89a9
7
- data.tar.gz: 172a7eff592f180bcf973d949d67aa934b026df2ab300adfbf4b855f00fc9afe4c617f61cd37f583cd43918eb096666bd97315a059d358f86d5612fcd1e4c169
6
+ metadata.gz: 1a31ebbfaec0c459045ab8c7d7a358ec8e2abc52e980f9f3d31162ff7177ac044aef48d2cc99efe816e52b70265490a1a617f2e537d6865c03e045d6c3b2cd72
7
+ data.tar.gz: 3d301be5aa02e6800c2715212187654e208aa5e8f4644f88e3d784f7a497108a75a49be57d0675876a4a1915288801403d803d3f38f0255c7e3b2a3dbab63236
@@ -1,3 +1,8 @@
1
+ 0.5.0
2
+ -----
3
+ - Add Heart Rate endpoint support. Add support for Time Series endpoints.
4
+ - Minor improvements to some helper functions
5
+
1
6
  0.4.1
2
7
  -----
3
8
  - Users can now provide either snake_cased or camelCased param attribute keys when POSTing data to Fitbit. Keys are automatically converted to camelCase before a request is sent to Fitbit's API.
data/README.md CHANGED
@@ -51,9 +51,10 @@ client.food_logs Date.today
51
51
  # => { "foods" => [{ "isFavorite" => true, "logDate" => "2015-06-26", "logId" => 1820, "loggedFood" => { "accessLevel" => "PUBLIC", "amount" => 132.57, "brand" => "", "calories" => 752, ...}] }
52
52
  ```
53
53
 
54
- To make the response more easily suited for attribute-assignment, it can be parsed to return a hash whose keys are in snake_case format. This can be done by setting the `snake_case` option to `true`, like so:
54
+ To make the response more easily suited for attribute-assignment, it can be parsed to return a hash whose keys are in snake_case format. This can be done by setting the client's `snake_case` option to `true`, like so:
55
55
 
56
56
  ```ruby
57
+ client.snake_case = true
57
58
  client.food_logs Date.today, snake_case: true
58
59
  # => { "foods" => [{ "is_favorite" => true, "log_date" => "2015-06-26", "log_id" => 1820, "logged_food" => { "access_level" => "PUBLIC", "amount" => 132.57, "brand" => "", "calories" => 752, ...}] }
59
60
  ```
@@ -78,7 +79,7 @@ When initializing a `Fitbyte::Client` instance, you're given access to a handful
78
79
 
79
80
  - `:locale` - The locale to use for response values (default: "en_US" | available: "en_US", "fr_FR", "de_DE", "es_ES", "en_GB", "en_AU", "en_NZ" and "ja_JP")
80
81
 
81
- - `:scope` - A space-delimited list of the permissions you are requesting (default: "activity nutrition profile settings sleep social weight" | available: "activity", "heartrate", "location", "nutrition", "profile", "settings" "sleep", "social" and "weight")
82
+ - `:scope` - A space-delimited list of the permissions you are requesting (default: "activity nutrition profile settings sleep social weight heartrate" | available: "activity", "heartrate", "location", "nutrition", "profile", "settings" "sleep", "social" and "weight")
82
83
 
83
84
  - `:snake_case` - Transform returned object's keys to snake case format (default: false)
84
85
 
@@ -1,5 +1,14 @@
1
1
  module Fitbyte
2
2
  class Client
3
+
4
+ ACTIVITY_RESOURCES = %w(calories caloriesBMR steps distance floors elevation
5
+ minutesSedentary minutesLightlyActive minutesFairlyActive
6
+ minutesVeryActive activityCalories tracker/calories
7
+ tracker/steps tracker/distance tracker/floors
8
+ tracker/elevation tracker/minutesSedentary
9
+ tracker/minutesLightlyActive tracker/minutesFairlyActive
10
+ tracker/minutesVeryActive tracker/activityCalories)
11
+
3
12
  # GET Activities
4
13
  # ==============
5
14
 
@@ -64,6 +73,38 @@ module Fitbyte
64
73
  get("user/#{@user_id}/activities.json", opts)
65
74
  end
66
75
 
76
+ def activity_time_series(resource, opts={})
77
+ start_date = opts[:start_date]
78
+ end_date = opts[:end_date] || Date.today
79
+ period = opts[:period]
80
+
81
+ unless ACTIVITY_RESOURCES.include?(resource)
82
+ raise Fitbyte::InvalidArgumentError, "Invalid resource: \"#{resource}\". Please provide one of the following: #{ACTIVITY_RESOURCES}."
83
+ end
84
+
85
+ if [period, start_date].none?
86
+ raise Fitbyte::InvalidArgumentError, "A start_date or period is required."
87
+ end
88
+
89
+ if period && !PERIODS.include?(period)
90
+ raise Fitbyte::InvalidArgumentError, "Invalid period: \"#{period}\". Please provide one of the following: #{PERIODS}."
91
+ end
92
+
93
+ if period
94
+ result = get("user/#{@user_id}/activities/#{resource}/date/#{format_date(end_date)}/#{period}.json", opts)
95
+ else
96
+ result = get("user/#{@user_id}/activities/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json", opts)
97
+ end
98
+ # remove root key from response
99
+ result.values[0]
100
+ end
101
+
102
+ # ACTIVITY_RESOURCES.each do |resource_path|
103
+ # define_method("activity_#{to_snake_case(resource_path).gsub('/', '_')}_series") do |opts={}|
104
+ # activity_time_series(resource_path, opts={})
105
+ # end
106
+ # end
107
+
67
108
  # POST Activities
68
109
  # ===============
69
110
 
@@ -1,5 +1,7 @@
1
1
  module Fitbyte
2
2
  class Client
3
+ BODY_RESOURCES = %w(bmi fat weight)
4
+
3
5
  def weight_logs(date=Date.today, opts={})
4
6
  get("user/-/body/log/weight/date/#{format_date(date)}.json", opts)
5
7
  end
@@ -15,5 +17,31 @@ module Fitbyte
15
17
  def body_fat_goals(opts={})
16
18
  get("user/-/body/log/fat/goal.json", opts)
17
19
  end
20
+
21
+ def body_time_series(resource, opts={})
22
+ start_date = opts[:start_date]
23
+ end_date = opts[:end_date] || Date.today
24
+ period = opts[:period]
25
+
26
+ unless BODY_RESOURCES.include?(resource)
27
+ raise Fitbyte::InvalidArgumentError, "Invalid resource: \"#{resource}\". Please provide one of the following: #{BODY_RESOURCES}."
28
+ end
29
+
30
+ if [period, start_date].none?
31
+ raise Fitbyte::InvalidArgumentError, "A start_date or period is required."
32
+ end
33
+
34
+ if period && !PERIODS.include?(period)
35
+ raise Fitbyte::InvalidArgumentError, "Invalid period: \"#{period}\". Please provide one of the following: #{PERIODS}."
36
+ end
37
+
38
+ if period
39
+ result = get("user/#{@user_id}/body/#{resource}/date/#{format_date(end_date)}/#{period}.json", opts)
40
+ else
41
+ result = get("user/#{@user_id}/body/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json", opts)
42
+ end
43
+ # remove root key from response
44
+ result.values[0]
45
+ end
18
46
  end
19
47
  end
@@ -1,5 +1,7 @@
1
1
  require "fitbyte/helpers"
2
+ require "fitbyte/exceptions"
2
3
  require "fitbyte/activities"
4
+ require "fitbyte/heart_rate"
3
5
  require "fitbyte/goals"
4
6
  require "fitbyte/alarms"
5
7
  require "fitbyte/body"
@@ -16,7 +18,7 @@ module Fitbyte
16
18
 
17
19
  def initialize(opts)
18
20
  missing_args = [:client_id, :client_secret, :redirect_uri] - opts.keys
19
- raise ArgumentError, "Required arguments: #{missing_args.join(', ')}" if missing_args.size > 0
21
+ raise Fitbyte::InvalidArgumentError, "Required arguments: #{missing_args.join(', ')}" if missing_args.size > 0
20
22
 
21
23
  opts = defaults.merge(opts)
22
24
 
@@ -99,7 +101,7 @@ module Fitbyte
99
101
  site_url: "https://api.fitbit.com",
100
102
  authorize_url: "https://www.fitbit.com/oauth2/authorize",
101
103
  token_url: "https://api.fitbit.com/oauth2/token",
102
- scope: "activity nutrition profile settings sleep social weight",
104
+ scope: "activity nutrition profile settings sleep social weight heartrate",
103
105
  unit_system: "en_US",
104
106
  locale: "en_US",
105
107
  api_version: "1",
@@ -0,0 +1,4 @@
1
+ module Fitbyte
2
+ class InvalidArgumentError < ArgumentError
3
+ end
4
+ end
@@ -1,5 +1,7 @@
1
1
  module Fitbyte
2
2
  class Client
3
+ FOOD_RESOURCES = %w(caloriesIn water)
4
+
3
5
  def food_logs(date=Date.today, opts={})
4
6
  get("user/#{@user_id}/foods/log/date/#{format_date(date)}.json", opts)
5
7
  end
@@ -19,5 +21,31 @@ module Fitbyte
19
21
  def food_goals(opts={})
20
22
  get("user/#{@user_id}/foods/log/goal.json", opts)
21
23
  end
24
+
25
+ def food_time_series(resource, opts={})
26
+ start_date = opts[:start_date]
27
+ end_date = opts[:end_date] || Date.today
28
+ period = opts[:period]
29
+
30
+ unless FOOD_RESOURCES.include?(resource)
31
+ raise Fitbyte::InvalidArgumentError, "Invalid resource: \"#{resource}\". Please provide one of the following: #{FOOD_RESOURCES}."
32
+ end
33
+
34
+ if [period, start_date].none?
35
+ raise Fitbyte::InvalidArgumentError, "A start_date or period is required."
36
+ end
37
+
38
+ if period && !PERIODS.include?(period)
39
+ raise Fitbyte::InvalidArgumentError, "Invalid period: \"#{period}\". Please provide one of the following: #{PERIODS}."
40
+ end
41
+
42
+ if period
43
+ result = get("user/#{@user_id}/foods/log/#{resource}/date/#{format_date(end_date)}/#{period}.json", opts)
44
+ else
45
+ result = get("user/#{@user_id}/foods/log/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json", opts)
46
+ end
47
+ # remove root key from response
48
+ result.values[0]
49
+ end
22
50
  end
23
51
  end
@@ -0,0 +1,25 @@
1
+ module Fitbyte
2
+ class Client
3
+ def heart_rate_time_series(opts={})
4
+ start_date = opts[:start_date]
5
+ end_date = opts[:end_date] || Date.today
6
+ period = opts[:period]
7
+
8
+ if [period, start_date].none?
9
+ raise Fitbyte::InvalidArgumentError, "A start_date or period is required."
10
+ end
11
+
12
+ if period && !PERIODS.include?(period)
13
+ raise Fitbyte::InvalidArgumentError, "Invalid period: \"#{period}\". Please provide one of the following: #{PERIODS}."
14
+ end
15
+
16
+ if period
17
+ result = get("user/#{@user_id}/activities/heart/date/#{format_date(end_date)}/#{period}.json", opts)
18
+ else
19
+ result = get("user/#{@user_id}/activities/heart/date/#{format_date(start_date)}/#{format_date(end_date)}.json", opts)
20
+ end
21
+ # remove root key from response
22
+ result.values[0]
23
+ end
24
+ end
25
+ end
@@ -1,6 +1,8 @@
1
1
  module Fitbyte
2
2
  class Client
3
3
 
4
+ PERIODS = %w(1d 7d 30d 1w 1m 3m 6m 1y max)
5
+
4
6
  def format_date(date)
5
7
  if [Date, Time, DateTime].include?(date.class)
6
8
  date.strftime("%Y-%m-%d")
@@ -8,10 +10,10 @@ module Fitbyte
8
10
  if date =~ /\d{4}\-\d{2}\-\d{2}/
9
11
  date
10
12
  else
11
- raise ArgumentError, "Invalid argument [\"#{date}\"] - string must follow yyyy-MM-dd format."
13
+ raise Fitbyte::InvalidArgumentError, "Invalid argument [\"#{date}\"] - string must follow yyyy-MM-dd format."
12
14
  end
13
15
  else
14
- raise ArgumentError, "Invalid type [#{date.class}] - provide a Date/Time/DateTime or a String(yyyy-MM-dd format)."
16
+ raise Fitbyte::InvalidArgumentError, "Invalid type [#{date.class}] - provide a Date/Time/DateTime or a String(yyyy-MM-dd format)."
15
17
  end
16
18
  end
17
19
 
@@ -20,7 +22,7 @@ module Fitbyte
20
22
  end
21
23
 
22
24
  def deep_keys_to_snake_case!(object)
23
- deep_transform_keys!(object) { |key| to_snake_case(key) }
25
+ deep_transform_keys!(object) { |key| to_snake_case(key, replace_dashes: true) }
24
26
  end
25
27
 
26
28
  def deep_keys_to_camel_case!(object)
@@ -47,11 +49,12 @@ module Fitbyte
47
49
  end
48
50
  end
49
51
 
50
- def to_snake_case(word)
52
+ def to_snake_case(word, opts={})
51
53
  string = word.to_s.dup
52
54
  return string.downcase if string.match(/\A[A-Z]+\z/)
53
55
  string.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
54
56
  string.gsub!(/([a-z])([A-Z])/, '\1_\2')
57
+ string.gsub!("-", "_") if opts[:replace_dashes]
55
58
  string.downcase
56
59
  end
57
60
 
@@ -1,7 +1,36 @@
1
1
  module Fitbyte
2
2
  class Client
3
+ SLEEP_RESOURCES = %w(startTime timeInBed minutesAsleep awakeningsCount
4
+ minutesAwake minutesToFallAsleep minutesAfterWakeup efficiency)
5
+
3
6
  def sleep_logs(date=Date.today, opts={})
4
7
  get("user/#{@user_id}/sleep/date/#{format_date(date)}.json", opts)
5
8
  end
9
+
10
+ def sleep_time_series(resource, opts={})
11
+ start_date = opts[:start_date]
12
+ end_date = opts[:end_date] || Date.today
13
+ period = opts[:period]
14
+
15
+ unless SLEEP_RESOURCES.include?(resource)
16
+ raise Fitbyte::InvalidArgumentError, "Invalid resource: \"#{resource}\". Please provide one of the following: #{SLEEP_RESOURCES}."
17
+ end
18
+
19
+ if [period, start_date].none?
20
+ raise Fitbyte::InvalidArgumentError, "A start_date or period is required."
21
+ end
22
+
23
+ if period && !PERIODS.include?(period)
24
+ raise Fitbyte::InvalidArgumentError, "Invalid period: \"#{period}\". Please provide one of the following: #{PERIODS}."
25
+ end
26
+
27
+ if period
28
+ result = get("user/#{@user_id}/activities/#{resource}/date/#{format_date(end_date)}/#{period}.json", opts)
29
+ else
30
+ result = get("user/#{@user_id}/activities/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json", opts)
31
+ end
32
+ # remove root key from response
33
+ result.values[0]
34
+ end
6
35
  end
7
36
  end
@@ -1,4 +1,4 @@
1
1
  module Fitbyte
2
- VERSION = "0.4.1"
2
+ VERSION = "0.5.0"
3
3
  REPO_URL = "https://github.com/zokioki/fitbyte"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fitbyte
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zoran Pesic
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-04-05 00:00:00.000000000 Z
11
+ date: 2016-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oauth2
@@ -90,9 +90,11 @@ files:
90
90
  - lib/fitbyte/body.rb
91
91
  - lib/fitbyte/client.rb
92
92
  - lib/fitbyte/devices.rb
93
+ - lib/fitbyte/exceptions.rb
93
94
  - lib/fitbyte/food.rb
94
95
  - lib/fitbyte/friends.rb
95
96
  - lib/fitbyte/goals.rb
97
+ - lib/fitbyte/heart_rate.rb
96
98
  - lib/fitbyte/helpers.rb
97
99
  - lib/fitbyte/sleep.rb
98
100
  - lib/fitbyte/user.rb