fitbit_api 0.14.2 → 0.15.1
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 +4 -4
- data/.github/workflows/{test.yml → ci.yml} +4 -2
- data/.rubocop.yml +28 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +2 -0
- data/README.md +11 -11
- data/Rakefile +5 -3
- data/fitbit_api.gemspec +15 -4
- data/lib/fitbit_api/activities.rb +30 -28
- data/lib/fitbit_api/alarms.rb +6 -4
- data/lib/fitbit_api/base.rb +5 -1
- data/lib/fitbit_api/body.rb +17 -16
- data/lib/fitbit_api/breathing_rate.rb +20 -28
- data/lib/fitbit_api/cardio_score.rb +11 -14
- data/lib/fitbit_api/client.rb +10 -7
- data/lib/fitbit_api/devices.rb +2 -0
- data/lib/fitbit_api/food.rb +20 -18
- data/lib/fitbit_api/friends.rb +2 -0
- data/lib/fitbit_api/goals.rb +4 -2
- data/lib/fitbit_api/heart_rate.rb +19 -19
- data/lib/fitbit_api/heart_rate_variability.rb +20 -28
- data/lib/fitbit_api/helpers/configuration.rb +7 -13
- data/lib/fitbit_api/helpers/exceptions.rb +2 -0
- data/lib/fitbit_api/helpers/utils.rb +38 -17
- data/lib/fitbit_api/meals.rb +2 -0
- data/lib/fitbit_api/oxygen_saturation.rb +8 -14
- data/lib/fitbit_api/sleep.rb +18 -17
- data/lib/fitbit_api/subscriptions.rb +8 -6
- data/lib/fitbit_api/temperature.rb +20 -28
- data/lib/fitbit_api/user.rb +2 -0
- data/lib/fitbit_api/version.rb +3 -1
- data/lib/fitbit_api/water.rb +3 -1
- data/lib/fitbit_api.rb +2 -0
- metadata +43 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d911585848ded1bbf5c5abfd9090b96971592ce119e6525e7b82808468717880
|
4
|
+
data.tar.gz: 1d4984610d1bba6468662b5f22d986a324642685811c9eede3bf35127b6e9bfe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fbfd618baee4f3c58b957d7f4997befa6bf25ee9778cf45d340ed13ed64188eb663781aa6a6f326d63263e0d1de21328fbbdb5e2e04c399b18aa9f617c29b852
|
7
|
+
data.tar.gz: e4acd060d4d06f1a39ca1c951140db0413b1e6967f252c7abe0dc471d32295c401e67a34e20ea86531b629afcbc319d70265e0c4cbea7cd6afa646b23fe6e1ae
|
@@ -1,4 +1,4 @@
|
|
1
|
-
name:
|
1
|
+
name: CI
|
2
2
|
|
3
3
|
on:
|
4
4
|
- push
|
@@ -8,7 +8,7 @@ permissions:
|
|
8
8
|
contents: read
|
9
9
|
|
10
10
|
jobs:
|
11
|
-
|
11
|
+
build:
|
12
12
|
runs-on: ubuntu-latest
|
13
13
|
strategy:
|
14
14
|
matrix:
|
@@ -25,5 +25,7 @@ jobs:
|
|
25
25
|
with:
|
26
26
|
ruby-version: ${{ matrix.ruby-version }}
|
27
27
|
bundler-cache: true
|
28
|
+
- name: Run Rubocop
|
29
|
+
run: bundle exec rubocop
|
28
30
|
- name: Run tests
|
29
31
|
run: bundle exec rake
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.6
|
3
|
+
NewCops: enable
|
4
|
+
|
5
|
+
Gemspec/RequiredRubyVersion:
|
6
|
+
Enabled: false
|
7
|
+
|
8
|
+
Style/Documentation:
|
9
|
+
Enabled: false
|
10
|
+
|
11
|
+
Metrics/AbcSize:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Metrics/CyclomaticComplexity:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
Metrics/PerceivedComplexity:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
Metrics/ClassLength:
|
21
|
+
Max: 200
|
22
|
+
|
23
|
+
Metrics/MethodLength:
|
24
|
+
Max: 40
|
25
|
+
|
26
|
+
Metrics/BlockLength:
|
27
|
+
Exclude:
|
28
|
+
- '**/*_spec.rb'
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
0.15.1
|
2
|
+
------
|
3
|
+
- Improve gemspec metadata
|
4
|
+
|
5
|
+
0.15.0
|
6
|
+
------
|
7
|
+
- The following methods now take a subscription_id as the first argument:
|
8
|
+
- create_subscription
|
9
|
+
- delete_subscription
|
10
|
+
- Fix scope param handling for `auth_url`
|
11
|
+
- Refactor configuration logic
|
12
|
+
- Improve endpoint request specs
|
13
|
+
- Format code with Rubocop
|
14
|
+
|
1
15
|
0.14.2
|
2
16
|
------
|
3
17
|
- Add documentation for more methods
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# FitbitAPI
|
2
2
|
|
3
3
|
[](https://rubygems.org/gems/fitbit_api)
|
4
|
-
[](https://github.com/zokioki/fitbit_api/actions/workflows/ci.yml)
|
5
5
|
|
6
6
|
FitbitAPI provides a Ruby interface to the [Fitbit Web API](https://dev.fitbit.com/reference/web-api).
|
7
7
|
|
@@ -95,16 +95,16 @@ client.log_activity activity_id: 12345, durationMillis: '683300'
|
|
95
95
|
|
96
96
|
When initializing a `FitbitAPI::Client` instance, you're given access to a handful of options:
|
97
97
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
| api_version | API version to be used when making requests
|
101
|
-
| unit_system | The measurement unit system to use for response values
|
102
|
-
| locale | The locale to use for response values
|
103
|
-
| scope | A
|
104
|
-
| snake_case_keys | Transform response payload's keys to snake case format
|
105
|
-
| symbolize_keys | Transform response payload's keys to symbols
|
106
|
-
| auto_refresh_token | Automatically refreshes the access token once expired
|
107
|
-
| on_token_refresh | A callback to be invoked whenever the access token is refreshed
|
98
|
+
| Option | Description | Default |
|
99
|
+
| -------------------- | ---------------------------- | -------------- |
|
100
|
+
| `api_version` | API version to be used when making requests | `"1"` |
|
101
|
+
| `unit_system` | The measurement unit system to use for response values | `"en_US"` |
|
102
|
+
| `locale` | The locale to use for response values | `"en_US"` |
|
103
|
+
| `scope` | A list of permissions being requested (array or space-delimited string) | `%w[activity nutrition profile settings sleep social weight heartrate respiratory_rate oxygen_saturation cardio_fitness temperature]` |
|
104
|
+
| `snake_case_keys` | Transform response payload's keys to snake case format | `false` |
|
105
|
+
| `symbolize_keys` | Transform response payload's keys to symbols | `false` |
|
106
|
+
| `auto_refresh_token` | Automatically refreshes the access token once expired | `true` |
|
107
|
+
| `on_token_refresh` | A callback to be invoked whenever the access token is refreshed | `nil` |
|
108
108
|
|
109
109
|
If using this library in Rails, you can configure these options globally in an initializer:
|
110
110
|
|
data/Rakefile
CHANGED
data/fitbit_api.gemspec
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
4
6
|
require 'fitbit_api/version'
|
5
7
|
|
6
8
|
Gem::Specification.new do |spec|
|
@@ -8,10 +10,17 @@ Gem::Specification.new do |spec|
|
|
8
10
|
spec.version = FitbitAPI::VERSION
|
9
11
|
spec.authors = ['Zoran']
|
10
12
|
|
11
|
-
spec.summary =
|
13
|
+
spec.summary = 'A Ruby interface to the Fitbit Web API.'
|
12
14
|
spec.homepage = 'https://github.com/zokioki/fitbit_api'
|
13
15
|
spec.license = 'MIT'
|
14
16
|
|
17
|
+
spec.metadata = {
|
18
|
+
'source_code_uri' => spec.homepage,
|
19
|
+
'changelog_uri' => "#{spec.homepage}/blob/v#{FitbitAPI::VERSION}/CHANGELOG.md",
|
20
|
+
'documentation_uri' => "https://www.rubydoc.info/gems/fitbit_api/#{FitbitAPI::VERSION}",
|
21
|
+
'rubygems_mfa_required' => 'true'
|
22
|
+
}
|
23
|
+
|
15
24
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(bin|test|spec|features)/}) }
|
16
25
|
spec.bindir = 'exe'
|
17
26
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
@@ -21,8 +30,10 @@ Gem::Specification.new do |spec|
|
|
21
30
|
|
22
31
|
spec.add_runtime_dependency 'oauth2', '~> 1.0'
|
23
32
|
|
24
|
-
spec.add_development_dependency 'byebug', '~> 11.0'
|
25
33
|
spec.add_development_dependency 'bundler', '~> 2.3'
|
34
|
+
spec.add_development_dependency 'byebug', '~> 11.0'
|
26
35
|
spec.add_development_dependency 'rake', '~> 13.0'
|
27
36
|
spec.add_development_dependency 'rspec', '~> 3.11'
|
37
|
+
spec.add_development_dependency 'rubocop', '~> 1.39'
|
38
|
+
spec.add_development_dependency 'webmock', '~> 3.18'
|
28
39
|
end
|
@@ -1,21 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FitbitAPI
|
2
4
|
class Client
|
3
|
-
|
4
|
-
ACTIVITY_RESOURCES = %w(calories caloriesBMR steps distance floors elevation
|
5
|
+
ACTIVITY_RESOURCES = %w[calories caloriesBMR steps distance floors elevation
|
5
6
|
minutesSedentary minutesLightlyActive minutesFairlyActive
|
6
7
|
minutesVeryActive activityCalories tracker/calories
|
7
8
|
tracker/steps tracker/distance tracker/floors
|
8
9
|
tracker/elevation tracker/minutesSedentary
|
9
10
|
tracker/minutesLightlyActive tracker/minutesFairlyActive
|
10
|
-
tracker/minutesVeryActive tracker/activityCalories
|
11
|
+
tracker/minutesVeryActive tracker/activityCalories].freeze
|
11
12
|
|
12
|
-
ACTIVITY_INTRADAY_RESOURCES = %w
|
13
|
+
ACTIVITY_INTRADAY_RESOURCES = %w[calories steps distance floors elevation].freeze
|
13
14
|
|
14
15
|
# Retrieves a summary and list of a user's activities and activity log entries for a given day.
|
15
16
|
#
|
16
17
|
# @param date [Date] The date for which to retrieve the activity data.
|
17
18
|
|
18
|
-
def daily_activity_summary(date=Date.today)
|
19
|
+
def daily_activity_summary(date = Date.today)
|
19
20
|
get("user/#{user_id}/activities/date/#{format_date(date)}.json")
|
20
21
|
end
|
21
22
|
|
@@ -59,7 +60,7 @@ module FitbitAPI
|
|
59
60
|
# @option params :offset [Integer] The offset number of entries. Must always be 0
|
60
61
|
# @option params :limit [Integer] The max of the number of entries returned (max: 20)
|
61
62
|
|
62
|
-
def activity_logs_list(params={})
|
63
|
+
def activity_logs_list(params = {})
|
63
64
|
default_params = { before_date: Date.today, after_date: nil, sort: 'desc', limit: 20, offset: 0 }
|
64
65
|
get("user/#{user_id}/activities/list.json", default_params.merge(params))
|
65
66
|
end
|
@@ -82,41 +83,42 @@ module FitbitAPI
|
|
82
83
|
get("user/#{user_id}/activities.json")
|
83
84
|
end
|
84
85
|
|
85
|
-
def activity_time_series(resource, opts={})
|
86
|
+
def activity_time_series(resource, opts = {})
|
86
87
|
start_date = opts[:start_date]
|
87
88
|
end_date = opts[:end_date] || Date.today
|
88
89
|
period = opts[:period]
|
89
90
|
|
90
91
|
unless ACTIVITY_RESOURCES.include?(resource)
|
91
|
-
raise FitbitAPI::InvalidArgumentError,
|
92
|
+
raise FitbitAPI::InvalidArgumentError,
|
93
|
+
"Invalid resource: \"#{resource}\". Please provide one of the following: #{ACTIVITY_RESOURCES}."
|
92
94
|
end
|
93
95
|
|
94
|
-
if [start_date, period].none?
|
95
|
-
raise FitbitAPI::InvalidArgumentError, 'A start_date or period is required.'
|
96
|
-
end
|
96
|
+
raise FitbitAPI::InvalidArgumentError, 'A start_date or period is required.' if [start_date, period].none?
|
97
97
|
|
98
98
|
if period && !PERIODS.include?(period)
|
99
|
-
raise FitbitAPI::InvalidArgumentError,
|
99
|
+
raise FitbitAPI::InvalidArgumentError,
|
100
|
+
"Invalid period: \"#{period}\". Please provide one of the following: #{PERIODS}."
|
100
101
|
end
|
101
102
|
|
102
|
-
if period
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
103
|
+
path = if period
|
104
|
+
"user/#{user_id}/activities/#{resource}/date/#{format_date(end_date)}/#{period}.json"
|
105
|
+
else
|
106
|
+
"user/#{user_id}/activities/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json"
|
107
|
+
end
|
108
|
+
result = get(path)
|
107
109
|
|
108
|
-
|
109
|
-
result.values[0]
|
110
|
+
strip_root_key(result)
|
110
111
|
end
|
111
112
|
|
112
|
-
def activity_intraday_time_series(resource, opts={})
|
113
|
+
def activity_intraday_time_series(resource, opts = {})
|
113
114
|
date = opts[:date] || Date.today
|
114
115
|
detail_level = opts[:detail_level]
|
115
116
|
start_time = opts[:start_time]
|
116
117
|
end_time = opts[:end_time]
|
117
118
|
|
118
119
|
unless ACTIVITY_INTRADAY_RESOURCES.include?(resource)
|
119
|
-
raise FitbitAPI::InvalidArgumentError,
|
120
|
+
raise FitbitAPI::InvalidArgumentError,
|
121
|
+
"Invalid resource: \"#{resource}\". Please provide one of the following: #{ACTIVITY_RESOURCES}."
|
120
122
|
end
|
121
123
|
|
122
124
|
if [date, detail_level].any?(&:nil?)
|
@@ -124,18 +126,18 @@ module FitbitAPI
|
|
124
126
|
end
|
125
127
|
|
126
128
|
unless %(1min 15min).include? detail_level
|
127
|
-
raise FitbitAPI::InvalidArgumentError,
|
129
|
+
raise FitbitAPI::InvalidArgumentError,
|
130
|
+
"Invalid detail_level: \"#{detail_level}\". Please provide one of the following: \"1min\" or \"15min\"."
|
128
131
|
end
|
129
132
|
|
130
133
|
if (start_time || end_time) && !(start_time && end_time)
|
131
134
|
raise FitbitAPI::InvalidArgumentError, 'Both start_time and end_time are required if time is being specified.'
|
132
135
|
end
|
133
136
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
end
|
137
|
+
path = "user/#{user_id}/activities/#{resource}/date/#{format_date(date)}/1d/#{detail_level}"
|
138
|
+
path += "/time/#{format_time(start_time)}/#{format_time(end_time)}" if start_time && end_time
|
139
|
+
|
140
|
+
get("#{path}.json")
|
139
141
|
end
|
140
142
|
|
141
143
|
# Creates log entry for an activity or user's private custom activity using units
|
@@ -147,7 +149,7 @@ module FitbitAPI
|
|
147
149
|
#
|
148
150
|
# @option body :activity_id [Integer, String] The activity ID
|
149
151
|
# @option body :activity_name [String] Custom activity name. Either activity ID or activity_name must be provided
|
150
|
-
# @option body :manual_calories [Integer] Calories burned, specified manually. Required
|
152
|
+
# @option body :manual_calories [Integer] Calories burned, specified manually. Required if activity_name is given
|
151
153
|
# @option body :start_time [String] Activity start time; formatted in HH:mm:ss
|
152
154
|
# @option body :duration_millis [Integer] Duration in milliseconds
|
153
155
|
# @option body :date [String] Log entry date; formatted in yyyy-MM-dd
|
data/lib/fitbit_api/alarms.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FitbitAPI
|
2
4
|
class Client
|
3
5
|
# Returns a list of the set alarms connected to a user's account.
|
@@ -18,9 +20,9 @@ module FitbitAPI
|
|
18
20
|
# @option body :time [String] Time of day that the alarm vibrates with a UTC timezone offset, e.g. 07:15-08:00
|
19
21
|
# @option body :enabled [Boolean] If false, alarm does not vibrate until enabled is set to true
|
20
22
|
# @option body :recurring [Boolean] If false, the alarm is a single event
|
21
|
-
# @option body :week_days [String] Comma separated list of days
|
23
|
+
# @option body :week_days [String] Comma separated list of days on which the alarm vibrates (e.g. MONDAY,TUESDAY)
|
22
24
|
|
23
|
-
def add_alarm(tracker_id, body={})
|
25
|
+
def add_alarm(tracker_id, body = {})
|
24
26
|
post("user/#{user_id}/devices/tracker/#{tracker_id}/alarms.json", body)
|
25
27
|
end
|
26
28
|
|
@@ -35,13 +37,13 @@ module FitbitAPI
|
|
35
37
|
# @option body :time [String] Time of day that the alarm vibrates with a UTC timezone offset, e.g. 07:15-08:00
|
36
38
|
# @option body :enabled [Boolean] If false, alarm does not vibrate until enabled is set to true
|
37
39
|
# @option body :recurring [Boolean] If false, the alarm is a single event
|
38
|
-
# @option body :week_days [String] Comma separated list of days
|
40
|
+
# @option body :week_days [String] Comma separated list of days on which the alarm vibrates (e.g. MONDAY,TUESDAY)
|
39
41
|
# @option body :snooze_length [Integer] Minutes between alarms
|
40
42
|
# @option body :snooze_count [Integer] Maximum snooze count
|
41
43
|
# @option body :label [String] Label for alarm
|
42
44
|
# @option body :vibe [String] Vibe pattern; only one value for now (DEFAULT)
|
43
45
|
|
44
|
-
def update_alarm(tracker_id, alarm_id, body={})
|
46
|
+
def update_alarm(tracker_id, alarm_id, body = {})
|
45
47
|
post("user/#{user_id}/devices/tracker/#{tracker_id}/alarms/#{alarm_id}.json", body)
|
46
48
|
end
|
47
49
|
|
data/lib/fitbit_api/base.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'fitbit_api/helpers/configuration'
|
2
4
|
require 'fitbit_api/helpers/utils'
|
3
5
|
require 'fitbit_api/helpers/exceptions'
|
@@ -15,7 +17,9 @@ module FitbitAPI
|
|
15
17
|
|
16
18
|
define_setting :unit_system, 'en_US'
|
17
19
|
define_setting :locale, 'en_US'
|
18
|
-
define_setting :scope,
|
20
|
+
define_setting :scope, %w[activity nutrition profile settings sleep social weight
|
21
|
+
heartrate respiratory_rate oxygen_saturation cardio_fitness
|
22
|
+
temperature]
|
19
23
|
|
20
24
|
define_setting :api_version, '1'
|
21
25
|
|
data/lib/fitbit_api/body.rb
CHANGED
@@ -1,40 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FitbitAPI
|
2
4
|
class Client
|
3
|
-
BODY_RESOURCES = %w
|
5
|
+
BODY_RESOURCES = %w[bmi fat weight].freeze
|
4
6
|
|
5
|
-
def weight_logs(date=Date.today)
|
7
|
+
def weight_logs(date = Date.today)
|
6
8
|
get("user/#{user_id}/body/log/weight/date/#{format_date(date)}.json")
|
7
9
|
end
|
8
10
|
|
9
|
-
def body_fat_logs(date=Date.today)
|
11
|
+
def body_fat_logs(date = Date.today)
|
10
12
|
get("user/#{user_id}/body/log/fat/date/#{format_date(date)}.json")
|
11
13
|
end
|
12
14
|
|
13
|
-
def body_time_series(resource, opts={})
|
15
|
+
def body_time_series(resource, opts = {})
|
14
16
|
start_date = opts[:start_date]
|
15
17
|
end_date = opts[:end_date] || Date.today
|
16
18
|
period = opts[:period]
|
17
19
|
|
18
20
|
unless BODY_RESOURCES.include?(resource)
|
19
|
-
raise FitbitAPI::InvalidArgumentError,
|
21
|
+
raise FitbitAPI::InvalidArgumentError,
|
22
|
+
"Invalid resource: \"#{resource}\". Please provide one of the following: #{BODY_RESOURCES}."
|
20
23
|
end
|
21
24
|
|
22
|
-
if [period, start_date].none?
|
23
|
-
raise FitbitAPI::InvalidArgumentError, 'A start_date or period is required.'
|
24
|
-
end
|
25
|
+
raise FitbitAPI::InvalidArgumentError, 'A start_date or period is required.' if [period, start_date].none?
|
25
26
|
|
26
27
|
if period && !PERIODS.include?(period)
|
27
|
-
raise FitbitAPI::InvalidArgumentError,
|
28
|
+
raise FitbitAPI::InvalidArgumentError,
|
29
|
+
"Invalid period: \"#{period}\". Please provide one of the following: #{PERIODS}."
|
28
30
|
end
|
29
31
|
|
30
|
-
if period
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
result = if period
|
33
|
+
get("user/#{user_id}/body/#{resource}/date/#{format_date(end_date)}/#{period}.json")
|
34
|
+
else
|
35
|
+
get("user/#{user_id}/body/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json")
|
36
|
+
end
|
35
37
|
|
36
|
-
|
37
|
-
result.values[0]
|
38
|
+
strip_root_key(result)
|
38
39
|
end
|
39
40
|
|
40
41
|
def log_weight(body)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FitbitAPI
|
2
4
|
class Client
|
3
5
|
# Returns the average breathing rate data for a given date or date range.
|
@@ -12,27 +14,22 @@ module FitbitAPI
|
|
12
14
|
# @option params :start_date [Date] The start of the date range
|
13
15
|
# @option params :end_date [Date] The end of the date range
|
14
16
|
|
15
|
-
def breathing_rate_summary(opts={})
|
17
|
+
def breathing_rate_summary(opts = {})
|
16
18
|
date = opts[:date] || Date.today
|
17
19
|
start_date = opts[:start_date]
|
18
20
|
end_date = opts[:end_date]
|
19
21
|
|
20
|
-
if start_date && !end_date
|
21
|
-
end_date = Date.today
|
22
|
-
end
|
22
|
+
end_date = Date.today if start_date && !end_date
|
23
23
|
|
24
|
-
unless date || start_date
|
25
|
-
raise FitbitAPI::InvalidArgumentError, 'A date or start_date and end_date are required.'
|
26
|
-
end
|
24
|
+
raise FitbitAPI::InvalidArgumentError, 'A date or start_date and end_date are required.' unless date || start_date
|
27
25
|
|
28
|
-
if start_date
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
result = if start_date
|
27
|
+
get("user/#{user_id}/br/date/#{format_date(start_date)}/#{format_date(end_date)}.json")
|
28
|
+
else
|
29
|
+
get("user/#{user_id}/br/date/#{format_date(date)}.json")
|
30
|
+
end
|
33
31
|
|
34
|
-
|
35
|
-
result.values[0]
|
32
|
+
strip_root_key(result)
|
36
33
|
end
|
37
34
|
|
38
35
|
# Returns the intraday breathing rate data for a given date or date range.
|
@@ -47,27 +44,22 @@ module FitbitAPI
|
|
47
44
|
# @option params :start_date [Date] The start of the date range
|
48
45
|
# @option params :end_date [Date] The end of the date range
|
49
46
|
|
50
|
-
def breathing_rate_intraday(opts={})
|
47
|
+
def breathing_rate_intraday(opts = {})
|
51
48
|
date = opts[:date] || Date.today
|
52
49
|
start_date = opts[:start_date]
|
53
50
|
end_date = opts[:end_date]
|
54
51
|
|
55
|
-
if start_date && !end_date
|
56
|
-
end_date = Date.today
|
57
|
-
end
|
52
|
+
end_date = Date.today if start_date && !end_date
|
58
53
|
|
59
|
-
unless date || start_date
|
60
|
-
raise FitbitAPI::InvalidArgumentError, 'A date or start_date and end_date are required.'
|
61
|
-
end
|
54
|
+
raise FitbitAPI::InvalidArgumentError, 'A date or start_date and end_date are required.' unless date || start_date
|
62
55
|
|
63
|
-
if start_date
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
56
|
+
result = if start_date
|
57
|
+
get("user/#{user_id}/br/date/#{format_date(start_date)}/#{format_date(end_date)}/all.json")
|
58
|
+
else
|
59
|
+
get("user/#{user_id}/br/date/#{format_date(date)}/all.json")
|
60
|
+
end
|
68
61
|
|
69
|
-
|
70
|
-
result.values[0]
|
62
|
+
strip_root_key(result)
|
71
63
|
end
|
72
64
|
end
|
73
65
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FitbitAPI
|
2
4
|
class Client
|
3
5
|
# Returns the cardio fitness score data for a given date or date range.
|
@@ -12,27 +14,22 @@ module FitbitAPI
|
|
12
14
|
# @option params :start_date [Date] The start of the date range
|
13
15
|
# @option params :end_date [Date] The end of the date range
|
14
16
|
|
15
|
-
def cardio_score_summary(opts={})
|
17
|
+
def cardio_score_summary(opts = {})
|
16
18
|
date = opts[:date] || Date.today
|
17
19
|
start_date = opts[:start_date]
|
18
20
|
end_date = opts[:end_date]
|
19
21
|
|
20
|
-
if start_date && !end_date
|
21
|
-
end_date = Date.today
|
22
|
-
end
|
22
|
+
end_date = Date.today if start_date && !end_date
|
23
23
|
|
24
|
-
unless date || start_date
|
25
|
-
raise FitbitAPI::InvalidArgumentError, 'A date or start_date and end_date are required.'
|
26
|
-
end
|
24
|
+
raise FitbitAPI::InvalidArgumentError, 'A date or start_date and end_date are required.' unless date || start_date
|
27
25
|
|
28
|
-
if start_date
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
result = if start_date
|
27
|
+
get("user/#{user_id}/cardioscore/date/#{format_date(start_date)}/#{format_date(end_date)}.json")
|
28
|
+
else
|
29
|
+
get("user/#{user_id}/cardioscore/date/#{format_date(date)}.json")
|
30
|
+
end
|
33
31
|
|
34
|
-
|
35
|
-
result.values[0]
|
32
|
+
strip_root_key(result)
|
36
33
|
end
|
37
34
|
end
|
38
35
|
end
|
data/lib/fitbit_api/client.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'fitbit_api/base'
|
2
4
|
require 'fitbit_api/activities'
|
3
5
|
require 'fitbit_api/breathing_rate'
|
@@ -24,7 +26,7 @@ module FitbitAPI
|
|
24
26
|
:snake_case_keys, :symbolize_keys, :auto_refresh_token, :on_token_refresh
|
25
27
|
attr_reader :token, :user_id
|
26
28
|
|
27
|
-
def initialize(opts={})
|
29
|
+
def initialize(opts = {})
|
28
30
|
validate_args(opts)
|
29
31
|
assign_attrs(opts)
|
30
32
|
set_client
|
@@ -34,7 +36,7 @@ module FitbitAPI
|
|
34
36
|
# Returns the authorize endpoint URL of the OAuth2 provider.
|
35
37
|
|
36
38
|
def auth_url
|
37
|
-
@client.auth_code.authorize_url(redirect_uri: @redirect_uri, scope: @scope)
|
39
|
+
@client.auth_code.authorize_url(redirect_uri: @redirect_uri, scope: format_scope(@scope))
|
38
40
|
end
|
39
41
|
|
40
42
|
# Returns an OAuth2::AccessToken instance obtained from the given authorization code.
|
@@ -77,7 +79,7 @@ module FitbitAPI
|
|
77
79
|
# @param params [Hash] The query parameters
|
78
80
|
# @param opts [Hash] Additional request options (e.g. headers)
|
79
81
|
|
80
|
-
def get(path, params={}, opts={}, &block)
|
82
|
+
def get(path, params = {}, opts = {}, &block)
|
81
83
|
request(:get, path, opts.merge(params: params), &block)
|
82
84
|
end
|
83
85
|
|
@@ -87,7 +89,7 @@ module FitbitAPI
|
|
87
89
|
# @param body [Hash] The request body
|
88
90
|
# @param opts [Hash] Additional request options (e.g. headers)
|
89
91
|
|
90
|
-
def post(path, body={}, opts={}, &block)
|
92
|
+
def post(path, body = {}, opts = {}, &block)
|
91
93
|
request(:post, path, opts.merge(body: body), &block)
|
92
94
|
end
|
93
95
|
|
@@ -97,7 +99,7 @@ module FitbitAPI
|
|
97
99
|
# @param params [Hash] The query parameters
|
98
100
|
# @param opts [Hash] Additional request options (e.g. headers)
|
99
101
|
|
100
|
-
def delete(path, params={}, opts={}, &block)
|
102
|
+
def delete(path, params = {}, opts = {}, &block)
|
101
103
|
request(:delete, path, opts.merge(params: params), &block)
|
102
104
|
end
|
103
105
|
|
@@ -112,6 +114,7 @@ module FitbitAPI
|
|
112
114
|
end
|
113
115
|
|
114
116
|
return if missing_args.empty?
|
117
|
+
|
115
118
|
raise FitbitAPI::InvalidArgumentError,
|
116
119
|
"Required arguments: #{missing_args.join(', ')}"
|
117
120
|
end
|
@@ -157,7 +160,7 @@ module FitbitAPI
|
|
157
160
|
refresh_token! if @token.token.empty?
|
158
161
|
end
|
159
162
|
|
160
|
-
def request(verb, path, opts={}, &block)
|
163
|
+
def request(verb, path, opts = {}, &block)
|
161
164
|
request_path = "#{@api_version}/#{path}"
|
162
165
|
request_headers = default_request_headers.merge(opts[:headers] || {})
|
163
166
|
request_options = opts.merge(headers: request_headers)
|
@@ -174,7 +177,7 @@ module FitbitAPI
|
|
174
177
|
end
|
175
178
|
|
176
179
|
def auth_headers
|
177
|
-
{ 'Authorization' =>
|
180
|
+
{ 'Authorization' => "Basic #{Base64.encode64("#{@client_id}:#{@client_secret}")}" }
|
178
181
|
end
|
179
182
|
|
180
183
|
def default_request_headers
|