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
data/lib/fitbit_api/food.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FitbitAPI
|
2
4
|
class Client
|
3
|
-
FOOD_RESOURCES = %w
|
5
|
+
FOOD_RESOURCES = %w[caloriesIn water].freeze
|
4
6
|
|
5
|
-
def food_logs(date=Date.today)
|
7
|
+
def food_logs(date = Date.today)
|
6
8
|
get("user/#{user_id}/foods/log/date/#{format_date(date)}.json")
|
7
9
|
end
|
8
10
|
|
@@ -11,7 +13,7 @@ module FitbitAPI
|
|
11
13
|
# @param query [String] The search query
|
12
14
|
|
13
15
|
def search_foods(params)
|
14
|
-
get(
|
16
|
+
get('foods/search.json', params)
|
15
17
|
end
|
16
18
|
|
17
19
|
def recent_foods
|
@@ -81,43 +83,43 @@ module FitbitAPI
|
|
81
83
|
delete("user/#{user_id}/foods/log/favorite/#{food_id}.json")
|
82
84
|
end
|
83
85
|
|
84
|
-
def food_time_series(resource, opts={})
|
86
|
+
def food_time_series(resource, opts = {})
|
85
87
|
start_date = opts[:start_date]
|
86
88
|
end_date = opts[:end_date] || Date.today
|
87
89
|
period = opts[:period]
|
88
90
|
|
89
91
|
unless FOOD_RESOURCES.include?(resource)
|
90
|
-
raise FitbitAPI::InvalidArgumentError,
|
92
|
+
raise FitbitAPI::InvalidArgumentError,
|
93
|
+
"Invalid resource: \"#{resource}\". Please provide one of the following: #{FOOD_RESOURCES}."
|
91
94
|
end
|
92
95
|
|
93
|
-
if [period, start_date].none?
|
94
|
-
raise FitbitAPI::InvalidArgumentError, 'A start_date or period is required.'
|
95
|
-
end
|
96
|
+
raise FitbitAPI::InvalidArgumentError, 'A start_date or period is required.' if [period, start_date].none?
|
96
97
|
|
97
98
|
if period && !PERIODS.include?(period)
|
98
|
-
raise FitbitAPI::InvalidArgumentError,
|
99
|
+
raise FitbitAPI::InvalidArgumentError,
|
100
|
+
"Invalid period: \"#{period}\". Please provide one of the following: #{PERIODS}."
|
99
101
|
end
|
100
102
|
|
101
|
-
if period
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
103
|
+
path = if period
|
104
|
+
"user/#{user_id}/foods/log/#{resource}/date/#{format_date(end_date)}/#{period}.json"
|
105
|
+
else
|
106
|
+
"user/#{user_id}/foods/log/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json"
|
107
|
+
end
|
108
|
+
result = get(path)
|
106
109
|
|
107
|
-
|
108
|
-
result.values[0]
|
110
|
+
strip_root_key(result)
|
109
111
|
end
|
110
112
|
|
111
113
|
# Retrieves the food locales used to search, log or create food
|
112
114
|
|
113
115
|
def food_locales
|
114
|
-
get(
|
116
|
+
get('foods/locales.json')
|
115
117
|
end
|
116
118
|
|
117
119
|
# Retrieves a list of all valid Fitbit food units
|
118
120
|
|
119
121
|
def food_units
|
120
|
-
get(
|
122
|
+
get('foods/units.json')
|
121
123
|
end
|
122
124
|
end
|
123
125
|
end
|
data/lib/fitbit_api/friends.rb
CHANGED
data/lib/fitbit_api/goals.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FitbitAPI
|
2
4
|
class Client
|
3
5
|
# Retrieves a user's current weight goal.
|
@@ -55,7 +57,7 @@ module FitbitAPI
|
|
55
57
|
# @option body :distance [Integer, Float] Distance goal value
|
56
58
|
# @option body :steps [Integer] Steps goal value
|
57
59
|
|
58
|
-
def update_daily_activity_goals(body={})
|
60
|
+
def update_daily_activity_goals(body = {})
|
59
61
|
post("user/#{user_id}/activities/goals/daily.json", body)
|
60
62
|
end
|
61
63
|
|
@@ -72,7 +74,7 @@ module FitbitAPI
|
|
72
74
|
# @option body :distance [Integer, Float] Distance goal value
|
73
75
|
# @option body :steps [Integer] Steps goal value
|
74
76
|
|
75
|
-
def update_weekly_activity_goals(body={})
|
77
|
+
def update_weekly_activity_goals(body = {})
|
76
78
|
post("user/#{user_id}/activities/goals/weekly.json", body)
|
77
79
|
end
|
78
80
|
|
@@ -1,29 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FitbitAPI
|
2
4
|
class Client
|
3
|
-
def heart_rate_time_series(opts={})
|
5
|
+
def heart_rate_time_series(opts = {})
|
4
6
|
start_date = opts[:start_date]
|
5
7
|
end_date = opts[:end_date] || Date.today
|
6
8
|
period = opts[:period]
|
7
9
|
|
8
|
-
if [period, start_date].none?
|
9
|
-
raise FitbitAPI::InvalidArgumentError, 'A start_date or period is required.'
|
10
|
-
end
|
10
|
+
raise FitbitAPI::InvalidArgumentError, 'A start_date or period is required.' if [period, start_date].none?
|
11
11
|
|
12
12
|
if period && !PERIODS.include?(period)
|
13
|
-
raise FitbitAPI::InvalidArgumentError,
|
13
|
+
raise FitbitAPI::InvalidArgumentError,
|
14
|
+
"Invalid period: \"#{period}\". Please provide one of the following: #{PERIODS}."
|
14
15
|
end
|
15
16
|
|
16
|
-
if period
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
result = if period
|
18
|
+
get("user/#{user_id}/activities/heart/date/#{format_date(end_date)}/#{period}.json")
|
19
|
+
else
|
20
|
+
get("user/#{user_id}/activities/heart/date/#{format_date(start_date)}/#{format_date(end_date)}.json")
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
-
result.values[0]
|
23
|
+
strip_root_key(result)
|
24
24
|
end
|
25
25
|
|
26
|
-
def heart_rate_intraday_time_series(opts={})
|
26
|
+
def heart_rate_intraday_time_series(opts = {})
|
27
27
|
date = opts[:date] || Date.today
|
28
28
|
detail_level = opts[:detail_level]
|
29
29
|
start_time = opts[:start_time]
|
@@ -34,18 +34,18 @@ module FitbitAPI
|
|
34
34
|
end
|
35
35
|
|
36
36
|
unless %(1sec 1min).include? detail_level
|
37
|
-
raise FitbitAPI::InvalidArgumentError,
|
37
|
+
raise FitbitAPI::InvalidArgumentError,
|
38
|
+
"Invalid detail_level: \"#{detail_level}\". Please provide one of the following: \"1sec\" or \"1min\"."
|
38
39
|
end
|
39
40
|
|
40
41
|
if (start_time || end_time) && !(start_time && end_time)
|
41
42
|
raise FitbitAPI::InvalidArgumentError, 'Both start_time and end_time are required if time is being specified.'
|
42
43
|
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
45
|
+
path = "user/#{user_id}/activities/heart/date/#{format_date(date)}/1d/#{detail_level}"
|
46
|
+
path += "/time/#{format_time(start_time)}/#{format_time(end_time)}" if start_time && end_time
|
47
|
+
|
48
|
+
get("#{path}.json")
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FitbitAPI
|
2
4
|
class Client
|
3
5
|
# Returns the heart rate variability 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 heart_rate_variability_summary(opts={})
|
17
|
+
def heart_rate_variability_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}/hrv/date/#{format_date(start_date)}/#{format_date(end_date)}.json")
|
28
|
+
else
|
29
|
+
get("user/#{user_id}/hrv/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 heart rate variability intraday 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 heart_rate_variability_intraday(opts={})
|
47
|
+
def heart_rate_variability_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}/hrv/date/#{format_date(start_date)}/#{format_date(end_date)}/all.json")
|
58
|
+
else
|
59
|
+
get("user/#{user_id}/hrv/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
|
module Configuration
|
3
5
|
def configure
|
@@ -5,22 +7,14 @@ module FitbitAPI
|
|
5
7
|
end
|
6
8
|
|
7
9
|
def define_setting(name, default = nil)
|
8
|
-
|
9
|
-
|
10
|
-
define_class_method "#{name}=" do |value|
|
11
|
-
class_variable_set("@@#{name}", value)
|
12
|
-
end
|
10
|
+
instance_variable_set("@#{name}", default)
|
13
11
|
|
14
|
-
|
15
|
-
|
12
|
+
define_singleton_method("#{name}=") do |value|
|
13
|
+
instance_variable_set("@#{name}", value)
|
16
14
|
end
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
15
|
|
21
|
-
|
22
|
-
|
23
|
-
define_method name, &block
|
16
|
+
define_singleton_method(name) do
|
17
|
+
instance_variable_get("@#{name}")
|
24
18
|
end
|
25
19
|
end
|
26
20
|
end
|
@@ -1,18 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FitbitAPI
|
2
4
|
class Client
|
3
|
-
PERIODS = %w
|
5
|
+
PERIODS = %w[1d 7d 30d 1w 1m 3m 6m 1y max].freeze
|
4
6
|
|
5
7
|
def format_date(date)
|
6
8
|
if [Date, Time, DateTime].include?(date.class)
|
7
9
|
date.strftime('%Y-%m-%d')
|
8
10
|
elsif date.is_a? String
|
9
|
-
if date =~ /\d{4}
|
11
|
+
if date =~ /\d{4}-\d{2}-\d{2}/
|
10
12
|
date
|
11
13
|
else
|
12
|
-
raise FitbitAPI::InvalidArgumentError,
|
14
|
+
raise FitbitAPI::InvalidArgumentError,
|
15
|
+
"Invalid argument [\"#{date}\"] - string must follow yyyy-MM-dd format."
|
13
16
|
end
|
14
17
|
else
|
15
|
-
raise FitbitAPI::InvalidArgumentError,
|
18
|
+
raise FitbitAPI::InvalidArgumentError,
|
19
|
+
"Invalid type [#{date.class}] - provide a Date/Time/DateTime or a String(yyyy-MM-dd format)."
|
16
20
|
end
|
17
21
|
end
|
18
22
|
|
@@ -20,13 +24,15 @@ module FitbitAPI
|
|
20
24
|
if [Time, DateTime].include?(time.class)
|
21
25
|
time.strftime('%H:%M')
|
22
26
|
elsif time.is_a? String
|
23
|
-
|
24
|
-
time
|
25
|
-
else
|
27
|
+
unless time =~ /\d{2}:\d{2}/
|
26
28
|
raise FitbitAPI::InvalidArgumentError, "Invalid argument [\"#{time}\"] - string must follow HH:mm format."
|
27
29
|
end
|
30
|
+
|
31
|
+
time
|
32
|
+
|
28
33
|
else
|
29
|
-
raise FitbitAPI::InvalidArgumentError,
|
34
|
+
raise FitbitAPI::InvalidArgumentError,
|
35
|
+
"Invalid type [#{time.class}] - provide a Time/DateTime or a String(HH:mm format)."
|
30
36
|
end
|
31
37
|
end
|
32
38
|
|
@@ -34,6 +40,12 @@ module FitbitAPI
|
|
34
40
|
scope.is_a?(Array) ? scope.join(' ') : scope
|
35
41
|
end
|
36
42
|
|
43
|
+
def strip_root_key(object)
|
44
|
+
return object unless object.is_a?(Hash) && object.keys.length == 1
|
45
|
+
|
46
|
+
object.values[0]
|
47
|
+
end
|
48
|
+
|
37
49
|
def deep_keys_to_snake_case!(object)
|
38
50
|
deep_transform_keys!(object) { |key| to_snake_case(key, replace_dashes: true) }
|
39
51
|
end
|
@@ -43,40 +55,49 @@ module FitbitAPI
|
|
43
55
|
end
|
44
56
|
|
45
57
|
def deep_symbolize_keys!(object)
|
46
|
-
deep_transform_keys!(object)
|
58
|
+
deep_transform_keys!(object) do |key|
|
59
|
+
key.to_sym
|
60
|
+
rescue StandardError
|
61
|
+
key
|
62
|
+
end
|
47
63
|
end
|
48
64
|
|
49
65
|
# Inspired by ActiveSupport's implementation
|
50
66
|
def deep_transform_keys!(object, &block)
|
51
67
|
case object
|
52
68
|
when Hash
|
53
|
-
object.keys
|
69
|
+
keys = object.keys
|
70
|
+
keys.each do |key|
|
54
71
|
value = object.delete(key)
|
55
|
-
object[yield(key)] = deep_transform_keys!(value
|
72
|
+
object[yield(key)] = deep_transform_keys!(value, &block)
|
56
73
|
end
|
57
74
|
object
|
58
75
|
when Array
|
59
|
-
object.map! { |e| deep_transform_keys!(e
|
76
|
+
object.map! { |e| deep_transform_keys!(e, &block) }
|
60
77
|
else
|
61
78
|
object
|
62
79
|
end
|
63
80
|
end
|
64
81
|
|
65
|
-
def to_snake_case(word, opts={})
|
82
|
+
def to_snake_case(word, opts = {})
|
66
83
|
string = word.to_s.dup
|
67
84
|
return string.downcase if string.match(/\A[A-Z]+\z/)
|
85
|
+
|
68
86
|
string.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
69
87
|
string.gsub!(/([a-z])([A-Z])/, '\1_\2')
|
70
88
|
string.gsub!('-', '_') if opts[:replace_dashes]
|
71
89
|
string.downcase
|
72
90
|
end
|
73
91
|
|
74
|
-
def to_camel_case(word, opts={})
|
92
|
+
def to_camel_case(word, opts = {})
|
75
93
|
string = word.to_s
|
76
|
-
|
94
|
+
if string.match(/[A-Z]|[a-z]([A-Z0-9]*[a-z][a-z0-9]*[A-Z]|[a-z0-9]*[A-Z][A-Z0-9]*[a-z])[A-Za-z0-9]*/)
|
95
|
+
return string
|
96
|
+
end
|
97
|
+
|
77
98
|
string = word.to_s.split('_').collect(&:capitalize).join
|
78
|
-
string.gsub!(/^\w{1}
|
79
|
-
|
99
|
+
string.gsub!(/^\w{1}/, &:downcase) if opts[:lower]
|
100
|
+
string
|
80
101
|
end
|
81
102
|
end
|
82
103
|
end
|
data/lib/fitbit_api/meals.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FitbitAPI
|
2
4
|
class Client
|
3
5
|
# Returns the oxygen saturation summary data for a given date or date range.
|
@@ -12,18 +14,14 @@ 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 oxygen_saturation_summary(opts={})
|
17
|
+
def oxygen_saturation_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
26
|
if start_date
|
29
27
|
get("user/#{user_id}/spo2/date/#{format_date(start_date)}/#{format_date(end_date)}.json")
|
@@ -44,18 +42,14 @@ module FitbitAPI
|
|
44
42
|
# @option params :start_date [Date] The start of the date range
|
45
43
|
# @option params :end_date [Date] The end of the date range
|
46
44
|
|
47
|
-
def oxygen_saturation_intraday(opts={})
|
45
|
+
def oxygen_saturation_intraday(opts = {})
|
48
46
|
date = opts[:date] || Date.today
|
49
47
|
start_date = opts[:start_date]
|
50
48
|
end_date = opts[:end_date]
|
51
49
|
|
52
|
-
if start_date && !end_date
|
53
|
-
end_date = Date.today
|
54
|
-
end
|
50
|
+
end_date = Date.today if start_date && !end_date
|
55
51
|
|
56
|
-
unless date || start_date
|
57
|
-
raise FitbitAPI::InvalidArgumentError, 'A date or start_date and end_date are required.'
|
58
|
-
end
|
52
|
+
raise FitbitAPI::InvalidArgumentError, 'A date or start_date and end_date are required.' unless date || start_date
|
59
53
|
|
60
54
|
if start_date
|
61
55
|
get("user/#{user_id}/spo2/date/#{format_date(start_date)}/#{format_date(end_date)}/all.json")
|
data/lib/fitbit_api/sleep.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FitbitAPI
|
2
4
|
class Client
|
3
|
-
SLEEP_RESOURCES = %w
|
4
|
-
minutesAwake minutesToFallAsleep minutesAfterWakeup efficiency
|
5
|
+
SLEEP_RESOURCES = %w[startTime timeInBed minutesAsleep awakeningsCount
|
6
|
+
minutesAwake minutesToFallAsleep minutesAfterWakeup efficiency].freeze
|
5
7
|
|
6
8
|
# Returns a list of a user's sleep log entries for a given date. The data returned can include sleep
|
7
9
|
# periods that began on the previous date. For example, if you request a Sleep Log for 2021-12-22,
|
@@ -9,7 +11,7 @@ module FitbitAPI
|
|
9
11
|
#
|
10
12
|
# @param date [Date, String] The date for the sleep log to be returned in the format yyyy-MM-dd
|
11
13
|
|
12
|
-
def sleep_logs(date=Date.today)
|
14
|
+
def sleep_logs(date = Date.today)
|
13
15
|
get("user/#{user_id}/sleep/date/#{format_date(date)}.json")
|
14
16
|
end
|
15
17
|
|
@@ -28,7 +30,7 @@ module FitbitAPI
|
|
28
30
|
# @option params :offset [Integer] The offset number of entries. Must always be 0
|
29
31
|
# @option params :limit [Integer] The max of the number of entries returned (max: 100)
|
30
32
|
|
31
|
-
def sleep_logs_list(params={})
|
33
|
+
def sleep_logs_list(params = {})
|
32
34
|
default_params = { before_date: Date.today, after_date: nil, sort: 'desc', limit: 20, offset: 0 }
|
33
35
|
get("user/#{user_id}/sleep/list.json", default_params.merge(params))
|
34
36
|
end
|
@@ -44,31 +46,30 @@ module FitbitAPI
|
|
44
46
|
delete("user/#{user_id}/sleep/#{sleep_log_id}.json")
|
45
47
|
end
|
46
48
|
|
47
|
-
def sleep_time_series(resource, opts={})
|
49
|
+
def sleep_time_series(resource, opts = {})
|
48
50
|
start_date = opts[:start_date]
|
49
51
|
end_date = opts[:end_date] || Date.today
|
50
52
|
period = opts[:period]
|
51
53
|
|
52
54
|
unless SLEEP_RESOURCES.include?(resource)
|
53
|
-
raise FitbitAPI::InvalidArgumentError,
|
55
|
+
raise FitbitAPI::InvalidArgumentError,
|
56
|
+
"Invalid resource: \"#{resource}\". Please provide one of the following: #{SLEEP_RESOURCES}."
|
54
57
|
end
|
55
58
|
|
56
|
-
if [period, start_date].none?
|
57
|
-
raise FitbitAPI::InvalidArgumentError, 'A start_date or period is required.'
|
58
|
-
end
|
59
|
+
raise FitbitAPI::InvalidArgumentError, 'A start_date or period is required.' if [period, start_date].none?
|
59
60
|
|
60
61
|
if period && !PERIODS.include?(period)
|
61
|
-
raise FitbitAPI::InvalidArgumentError,
|
62
|
+
raise FitbitAPI::InvalidArgumentError,
|
63
|
+
"Invalid period: \"#{period}\". Please provide one of the following: #{PERIODS}."
|
62
64
|
end
|
63
65
|
|
64
|
-
if period
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
result = if period
|
67
|
+
get("user/#{user_id}/sleep/#{resource}/date/#{format_date(end_date)}/#{period}.json")
|
68
|
+
else
|
69
|
+
get("user/#{user_id}/sleep/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json")
|
70
|
+
end
|
69
71
|
|
70
|
-
|
71
|
-
result.values[0]
|
72
|
+
strip_root_key(result)
|
72
73
|
end
|
73
74
|
end
|
74
75
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FitbitAPI
|
2
4
|
class Client
|
3
5
|
# Retrieves a list of subscriptions created by your application for a specific user.
|
@@ -6,31 +8,31 @@ module FitbitAPI
|
|
6
8
|
#
|
7
9
|
# @param collection_path [String] Collection of data to retrieve notifications
|
8
10
|
|
9
|
-
def subscriptions(collection_path=nil)
|
11
|
+
def subscriptions(collection_path = nil)
|
10
12
|
get("#{subscriptions_path(collection_path)}.json")
|
11
13
|
end
|
12
14
|
|
13
15
|
# Creates a subscription to notify the application when a user has new data available.
|
14
16
|
#
|
15
|
-
# @param collection_path [String] Collection of data to retrieve notifications
|
16
17
|
# @param subscription_id [Integer] The unique ID of the subscription created by the API client application
|
18
|
+
# @param collection_path [String] Collection of data to retrieve notifications
|
17
19
|
|
18
|
-
def create_subscription(collection_path=nil
|
20
|
+
def create_subscription(subscription_id, collection_path = nil)
|
19
21
|
post("#{subscriptions_path(collection_path)}/#{subscription_id}.json")
|
20
22
|
end
|
21
23
|
|
22
24
|
# Deletes a subscription for a specific user.
|
23
25
|
#
|
24
|
-
# @param collection_path [String] Collection of data to retrieve notifications
|
25
26
|
# @param subscription_id [Integer] The unique ID of the subscription created by the API client application
|
27
|
+
# @param collection_path [String] Collection of data to retrieve notifications
|
26
28
|
|
27
|
-
def delete_subscription(collection_path=nil
|
29
|
+
def delete_subscription(subscription_id, collection_path = nil)
|
28
30
|
delete("#{subscriptions_path(collection_path)}/#{subscription_id}.json")
|
29
31
|
end
|
30
32
|
|
31
33
|
private
|
32
34
|
|
33
|
-
def subscriptions_path(collection_path=nil)
|
35
|
+
def subscriptions_path(collection_path = nil)
|
34
36
|
collection_path = "#{collection_path}/" if collection_path
|
35
37
|
"user/#{user_id}/#{collection_path}apiSubscriptions"
|
36
38
|
end
|