fitbit_api 0.14.2 → 0.15.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://img.shields.io/gem/v/fitbit_api)](https://rubygems.org/gems/fitbit_api)
|
4
|
-
[![
|
4
|
+
[![CI Workflow](https://img.shields.io/github/workflow/status/zokioki/fitbit_api/CI)](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
|