fitgem_oauth2 2.2.0 → 4.0.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 +4 -4
- data/fitgem_oauth2.gemspec +9 -6
- data/lib/fitgem_oauth2/activity.rb +30 -28
- data/lib/fitgem_oauth2/body_measurements.rb +28 -34
- data/lib/fitgem_oauth2/client.rb +61 -55
- data/lib/fitgem_oauth2/devices.rb +2 -1
- data/lib/fitgem_oauth2/errors.rb +2 -1
- data/lib/fitgem_oauth2/food/collection.rb +2 -0
- data/lib/fitgem_oauth2/food/metadata.rb +2 -0
- data/lib/fitgem_oauth2/food/series.rb +2 -28
- data/lib/fitgem_oauth2/food.rb +11 -9
- data/lib/fitgem_oauth2/friends.rb +2 -0
- data/lib/fitgem_oauth2/heartrate.rb +19 -40
- data/lib/fitgem_oauth2/sleep.rb +11 -12
- data/lib/fitgem_oauth2/subscriptions.rb +3 -2
- data/lib/fitgem_oauth2/users.rb +2 -0
- data/lib/fitgem_oauth2/utils.rb +12 -9
- data/lib/fitgem_oauth2/version.rb +3 -1
- data/lib/fitgem_oauth2.rb +3 -2
- metadata +20 -19
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cb6abab3890862d921de4c7f36128afc601bbb2579382f67164929cbd4deba3e
|
|
4
|
+
data.tar.gz: 740cb87e8fdfdae9a3437b59d63486e85bb58567cdad1d22cdb5a90e7daa2b55
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 94a1a3f44eef697b5de5a67a992322995e3184fd5142b9896b8e2827d97abf5949aaa5bd07dd88503787bc13defad8ae1215460bfd3a026bcbf3cb41504fd2b8
|
|
7
|
+
data.tar.gz: c85fab5f3b82b37fca9302fcf55f36c1e0f0b83be4f00a743919caafe879d97a1dd9d5df94c4336de221d063b2bd5923ccd08b654a6a01b30f4fa41d6ca9ab8b
|
data/fitgem_oauth2.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
$LOAD_PATH.unshift File.expand_path('lib', __dir__)
|
|
4
4
|
require 'fitgem_oauth2/version'
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
@@ -10,13 +10,16 @@ Gem::Specification.new do |s|
|
|
|
10
10
|
s.description = 'This gem allows requesting data from Fitbit API using OAuth2'
|
|
11
11
|
s.authors = ['Ankit Gupta']
|
|
12
12
|
s.email = 'ankit.gupta2801@gmail.com'
|
|
13
|
-
s.files = %w
|
|
13
|
+
s.files = %w[fitgem_oauth2.gemspec] + `git ls-files -z`.split("\x0").select {|f| f.start_with?('lib/') }
|
|
14
14
|
s.homepage = 'http://rubygems.org/gems/fitgem_oauth2'
|
|
15
15
|
s.license = 'MIT'
|
|
16
|
+
s.metadata = {'rubygems_mfa_required' => 'true'}
|
|
16
17
|
|
|
17
|
-
s.
|
|
18
|
+
s.required_ruby_version = '>= 3.2.0'
|
|
18
19
|
|
|
19
|
-
s.
|
|
20
|
+
s.add_dependency 'faraday', '~> 2.0'
|
|
21
|
+
|
|
22
|
+
s.add_development_dependency 'factory_bot', '~> 6.0'
|
|
23
|
+
s.add_development_dependency 'rake', '~> 13.0'
|
|
20
24
|
s.add_development_dependency 'rspec', '~> 3.4'
|
|
21
|
-
s.add_development_dependency 'factory_girl', '~> 4.5'
|
|
22
25
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module FitgemOauth2
|
|
2
4
|
class Client
|
|
3
|
-
|
|
4
5
|
ACTIVITY_RESOURCES = %w[
|
|
5
6
|
calories caloriesBMR steps distance floors elevation minutesSedentary
|
|
6
7
|
minutesLightlyActive minutesFairlyActive minutesVeryActive
|
|
@@ -25,18 +26,16 @@ module FitgemOauth2
|
|
|
25
26
|
# retrieves activity time series, based on the arguments provided
|
|
26
27
|
# @param resource the resource for which the series needs to be retrieved. one of ALLOWED_RESOURCES
|
|
27
28
|
# @param start_date the start date for the series
|
|
28
|
-
# @param end_date the end date for the series.
|
|
29
|
-
# @param period the period starting from start_date for which the series
|
|
30
|
-
#
|
|
29
|
+
# @param end_date the end date for the series. do not specify period
|
|
30
|
+
# @param period the period starting from start_date for which the series
|
|
31
|
+
# needs to be retrieved. If specifying period, do not use end_date
|
|
31
32
|
def activity_time_series(resource: nil, start_date: nil, end_date: nil, period: nil)
|
|
32
|
-
|
|
33
33
|
unless resource && ACTIVITY_RESOURCES.include?(resource)
|
|
34
|
-
raise FitgemOauth2::InvalidArgumentError,
|
|
34
|
+
raise FitgemOauth2::InvalidArgumentError,
|
|
35
|
+
"Invalid resource: #{resource}. Valid resources are #{ACTIVITY_RESOURCES}."
|
|
35
36
|
end
|
|
36
37
|
|
|
37
|
-
unless start_date
|
|
38
|
-
raise FitgemOauth2::InvalidArgumentError, 'Start date must be specified.'
|
|
39
|
-
end
|
|
38
|
+
raise FitgemOauth2::InvalidArgumentError, 'Start date must be specified.' unless start_date
|
|
40
39
|
|
|
41
40
|
if period && end_date
|
|
42
41
|
raise FitgemOauth2::InvalidArgumentError, 'Both period and end_date are specified. Please specify only one.'
|
|
@@ -49,26 +48,27 @@ module FitgemOauth2
|
|
|
49
48
|
first = format_date(start_date)
|
|
50
49
|
second = period || format_date(end_date)
|
|
51
50
|
url = ['user', user_id, 'activities', resource, 'date', first, second].join('/')
|
|
52
|
-
get_call(url
|
|
51
|
+
get_call("#{url}.json")
|
|
53
52
|
end
|
|
54
53
|
|
|
55
54
|
# retrieves intraday activity time series.
|
|
56
|
-
# @param resource (required) for which the intrady series is retrieved.
|
|
55
|
+
# @param resource (required) for which the intrady series is retrieved.
|
|
56
|
+
# one of 'calories', 'steps', 'distance', 'floors', 'elevation'
|
|
57
57
|
# @param start_date (required) start date for the series
|
|
58
58
|
# @param end_date (optional) end date for the series, if not specified, the series is for 1 day
|
|
59
59
|
# @param detail_level (required) level of detail for the series
|
|
60
60
|
# @param start_time (optional)start time for the series
|
|
61
61
|
# @param end_time the (optional)end time for the series. specify both start_time and end_time, if using either
|
|
62
|
+
# rubocop:disable Metrics/ParameterLists
|
|
62
63
|
def intraday_activity_time_series(resource: nil, start_date: nil, end_date: nil, detail_level: nil,
|
|
63
64
|
start_time: nil, end_time: nil)
|
|
64
|
-
|
|
65
65
|
# converting to symbol to allow developer to use either 'calories' or :calories
|
|
66
66
|
resource = resource.to_sym
|
|
67
67
|
|
|
68
68
|
unless %i[calories steps distance floors elevation].include?(resource)
|
|
69
69
|
raise FitgemOauth2::InvalidArgumentError,
|
|
70
|
-
'Must specify resource to fetch intraday time series data for.'\
|
|
71
|
-
'
|
|
70
|
+
'Must specify resource to fetch intraday time series data for. ' \
|
|
71
|
+
'One of (:calories, :steps, :distance, :floors, or :elevation) is required.'
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
unless start_date
|
|
@@ -78,25 +78,26 @@ module FitgemOauth2
|
|
|
78
78
|
|
|
79
79
|
end_date ||= '1d'
|
|
80
80
|
|
|
81
|
-
unless detail_level && %w
|
|
81
|
+
unless detail_level && %w[1min 15min].include?(detail_level)
|
|
82
82
|
raise FitgemOauth2::InvalidArgumentError,
|
|
83
|
-
'Must specify the data resolution to fetch intraday time series data for.'\
|
|
84
|
-
'
|
|
83
|
+
'Must specify the data resolution to fetch intraday time series data for. ' \
|
|
84
|
+
'One of (\"1d\" or \"15min\") is required.'
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
resource_path = [
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
88
|
+
'user', @user_id,
|
|
89
|
+
'activities', resource,
|
|
90
|
+
'date', format_date(start_date),
|
|
91
|
+
end_date, detail_level
|
|
92
92
|
].join('/')
|
|
93
93
|
|
|
94
94
|
if start_time || end_time
|
|
95
95
|
resource_path =
|
|
96
|
-
|
|
96
|
+
[resource_path, 'time', format_time(start_time), format_time(end_time)].join('/')
|
|
97
97
|
end
|
|
98
98
|
get_call("#{resource_path}.json")
|
|
99
99
|
end
|
|
100
|
+
# rubocop:enable Metrics/ParameterLists
|
|
100
101
|
|
|
101
102
|
# ======================================
|
|
102
103
|
# Activity Logging Methods
|
|
@@ -118,12 +119,12 @@ module FitgemOauth2
|
|
|
118
119
|
# retrieves activity list for the user
|
|
119
120
|
def activity_list(date, sort, limit)
|
|
120
121
|
date_param = format_date(date)
|
|
121
|
-
if sort ==
|
|
122
|
+
if sort == 'asc'
|
|
122
123
|
date_param = "afterDate=#{date_param}"
|
|
123
|
-
elsif sort ==
|
|
124
|
+
elsif sort == 'desc'
|
|
124
125
|
date_param = "beforeDate=#{date_param}"
|
|
125
126
|
else
|
|
126
|
-
raise FitgemOauth2::InvalidArgumentError,
|
|
127
|
+
raise FitgemOauth2::InvalidArgumentError, 'sort can either be asc or desc'
|
|
127
128
|
end
|
|
128
129
|
get_call("user/#{user_id}/activities/list.json?offset=0&limit=#{limit}&sort=#{sort}&#{date_param}")
|
|
129
130
|
end
|
|
@@ -133,7 +134,6 @@ module FitgemOauth2
|
|
|
133
134
|
get_call("user/#{user_id}/activities/#{id}.tcx")
|
|
134
135
|
end
|
|
135
136
|
|
|
136
|
-
|
|
137
137
|
# ======================================
|
|
138
138
|
# Activity Types
|
|
139
139
|
# ======================================
|
|
@@ -185,9 +185,10 @@ module FitgemOauth2
|
|
|
185
185
|
# retrieve activity goals for a period
|
|
186
186
|
# @period the period for which the goals need to be retrieved. either 'weekly' or 'daily'
|
|
187
187
|
def goals(period)
|
|
188
|
-
unless period && %w
|
|
188
|
+
unless period && %w[daily weekly].include?(period)
|
|
189
189
|
raise FitgemOauth2::InvalidArgumentError, "Goal period should either be 'daily' or 'weekly'"
|
|
190
190
|
end
|
|
191
|
+
|
|
191
192
|
get_call("user/#{user_id}/activities/goals/#{period}.json")
|
|
192
193
|
end
|
|
193
194
|
|
|
@@ -195,9 +196,10 @@ module FitgemOauth2
|
|
|
195
196
|
# @param period period for the goal ('weekly' or 'daily')
|
|
196
197
|
# @param params the POST params for the request. Refer to Fitbit documentation for accepted format
|
|
197
198
|
def update_activity_goals(period, params)
|
|
198
|
-
unless period && %w
|
|
199
|
+
unless period && %w[daily weekly].include?(period)
|
|
199
200
|
raise FitgemOauth2::InvalidArgumentError, "Goal period should either be 'daily' or 'weekly'"
|
|
200
201
|
end
|
|
202
|
+
|
|
201
203
|
post_call("user/#{user_id}/activities/goals/#{period}.json", params)
|
|
202
204
|
end
|
|
203
205
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module FitgemOauth2
|
|
2
4
|
class Client
|
|
3
|
-
FAT_PERIODS = %w
|
|
4
|
-
WEIGHT_PERIODS = %w
|
|
5
|
-
BODY_GOALS = %w
|
|
6
|
-
BODY_TIME_SERIES_PERIODS = %w
|
|
5
|
+
FAT_PERIODS = %w[1d 7d 1w 1m].freeze
|
|
6
|
+
WEIGHT_PERIODS = %w[1d 7d 30d 1w 1m].freeze
|
|
7
|
+
BODY_GOALS = %w[fat weight].freeze
|
|
8
|
+
BODY_TIME_SERIES_PERIODS = %w[1d 7d 30d 1w 1m 3m 6m 1y max].freeze
|
|
7
9
|
|
|
8
10
|
# ======================================
|
|
9
11
|
# Boday Fat
|
|
@@ -15,23 +17,21 @@ module FitgemOauth2
|
|
|
15
17
|
# @param end_date (optional)end date for the logs
|
|
16
18
|
# @param period (optional) period for the logs
|
|
17
19
|
def body_fat_logs(start_date: nil, end_date: nil, period: nil)
|
|
18
|
-
unless start_date
|
|
19
|
-
|
|
20
|
-
end
|
|
20
|
+
raise FitgemOauth2::InvalidArgumentError, 'must specify start_date' unless start_date
|
|
21
|
+
|
|
21
22
|
url = ['user', user_id, 'body/log/fat/date', format_date(start_date)].join('/')
|
|
22
|
-
if end_date
|
|
23
|
-
url = [url, format_date(end_date)].join('/')
|
|
24
|
-
end
|
|
23
|
+
url = [url, format_date(end_date)].join('/') if end_date
|
|
25
24
|
|
|
26
25
|
if period
|
|
27
|
-
|
|
28
|
-
url = [url, period].join('/')
|
|
29
|
-
else
|
|
26
|
+
unless FAT_PERIODS.include?(period)
|
|
30
27
|
raise FitgemOauth2::InvalidArgumentError, "period must be one in #{FAT_PERIODS}"
|
|
31
28
|
end
|
|
29
|
+
|
|
30
|
+
url = [url, period].join('/')
|
|
31
|
+
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
url
|
|
34
|
+
url += '.json'
|
|
35
35
|
|
|
36
36
|
get_call(url)
|
|
37
37
|
end
|
|
@@ -48,7 +48,6 @@ module FitgemOauth2
|
|
|
48
48
|
delete_call("user/#{user_id}/body/log/fat/#{id}.json")
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
|
|
52
51
|
# ==================================
|
|
53
52
|
# Body Time Series
|
|
54
53
|
# ==================================
|
|
@@ -60,7 +59,8 @@ module FitgemOauth2
|
|
|
60
59
|
# @param period (optional)period for the time series. valid periods are BODY_TIME_SERIES_PERIODS
|
|
61
60
|
def body_time_series(resource: nil, start_date: nil, end_date: nil, period: nil)
|
|
62
61
|
unless resource && start_date
|
|
63
|
-
raise FitgemOauth2::InvalidArgumentError,
|
|
62
|
+
raise FitgemOauth2::InvalidArgumentError,
|
|
63
|
+
'resource and start_date are required parameters. Please specify both.'
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
url = ['user', user_id, 'body', resource, 'date', format_date(start_date)].join('/')
|
|
@@ -74,20 +74,18 @@ module FitgemOauth2
|
|
|
74
74
|
if BODY_TIME_SERIES_PERIODS.include?(period)
|
|
75
75
|
second = period
|
|
76
76
|
else
|
|
77
|
-
raise FitgemOauth2::InvalidArgumentError,
|
|
77
|
+
raise FitgemOauth2::InvalidArgumentError,
|
|
78
|
+
"Invalid Period. Body time series period must be in #{BODY_TIME_SERIES_PERIODS}"
|
|
78
79
|
end
|
|
79
80
|
end
|
|
80
81
|
|
|
81
|
-
if end_date
|
|
82
|
-
second = format_date(end_date)
|
|
83
|
-
end
|
|
82
|
+
second = format_date(end_date) if end_date
|
|
84
83
|
|
|
85
84
|
url = [url, second].join('/')
|
|
86
85
|
|
|
87
|
-
get_call(url
|
|
86
|
+
get_call("#{url}.json")
|
|
88
87
|
end
|
|
89
88
|
|
|
90
|
-
|
|
91
89
|
# ======================================
|
|
92
90
|
# Body Goals
|
|
93
91
|
# ======================================
|
|
@@ -95,11 +93,11 @@ module FitgemOauth2
|
|
|
95
93
|
# retrieves body goals based on the type specified
|
|
96
94
|
# @param type 'fat' or 'weight'
|
|
97
95
|
def body_goals(type)
|
|
98
|
-
|
|
99
|
-
get_call("user/#{user_id}/body/log/#{type}/goal.json")
|
|
100
|
-
else
|
|
96
|
+
unless type && BODY_GOALS.include?(type)
|
|
101
97
|
raise FitgemOauth2::InvalidArgumentError, "invalid goal type : #{type}. must be one of #{BODY_GOALS}"
|
|
102
98
|
end
|
|
99
|
+
|
|
100
|
+
get_call("user/#{user_id}/body/log/#{type}/goal.json")
|
|
103
101
|
end
|
|
104
102
|
|
|
105
103
|
# update body fat goal
|
|
@@ -123,18 +121,15 @@ module FitgemOauth2
|
|
|
123
121
|
# @param end_date (optional)end_date for the logs
|
|
124
122
|
# @param period (optional)period for the logs
|
|
125
123
|
def weight_logs(start_date: nil, end_date: nil, period: nil)
|
|
126
|
-
unless start_date
|
|
127
|
-
raise FitgemOauth2::InvalidArgumentError, 'start_date not specified.'
|
|
128
|
-
end
|
|
124
|
+
raise FitgemOauth2::InvalidArgumentError, 'start_date not specified.' unless start_date
|
|
129
125
|
|
|
130
126
|
if period && end_date
|
|
131
127
|
raise FitgemOauth2::InvalidArgumentError, 'both end_date and period specified. please provide only one.'
|
|
132
128
|
end
|
|
133
129
|
|
|
134
|
-
if period
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
end
|
|
130
|
+
if period && !WEIGHT_PERIODS.include?(period)
|
|
131
|
+
raise FitgemOauth2::InvalidArgumentError,
|
|
132
|
+
"valid period not specified. please choose a period from #{WEIGHT_PERIODS}"
|
|
138
133
|
end
|
|
139
134
|
|
|
140
135
|
first = format_date(start_date)
|
|
@@ -144,7 +139,7 @@ module FitgemOauth2
|
|
|
144
139
|
url = [url, second].join('/')
|
|
145
140
|
end
|
|
146
141
|
|
|
147
|
-
get_call(url
|
|
142
|
+
get_call("#{url}.json")
|
|
148
143
|
end
|
|
149
144
|
|
|
150
145
|
# logs weight for the user
|
|
@@ -158,6 +153,5 @@ module FitgemOauth2
|
|
|
158
153
|
def delete_logged_weight(id)
|
|
159
154
|
delete_call("user/#{user_id}/body/log/weight/#{id}.json")
|
|
160
155
|
end
|
|
161
|
-
|
|
162
156
|
end
|
|
163
157
|
end
|
data/lib/fitgem_oauth2/client.rb
CHANGED
|
@@ -1,41 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require 'fitgem_oauth2/
|
|
4
|
-
require 'fitgem_oauth2/
|
|
5
|
-
require 'fitgem_oauth2/
|
|
6
|
-
require 'fitgem_oauth2/
|
|
7
|
-
require 'fitgem_oauth2/
|
|
8
|
-
require 'fitgem_oauth2/
|
|
9
|
-
require 'fitgem_oauth2/
|
|
10
|
-
require 'fitgem_oauth2/
|
|
11
|
-
require 'fitgem_oauth2/
|
|
12
|
-
require 'fitgem_oauth2/
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'fitgem_oauth2/activity'
|
|
4
|
+
require 'fitgem_oauth2/body_measurements'
|
|
5
|
+
require 'fitgem_oauth2/devices'
|
|
6
|
+
require 'fitgem_oauth2/errors'
|
|
7
|
+
require 'fitgem_oauth2/food'
|
|
8
|
+
require 'fitgem_oauth2/friends'
|
|
9
|
+
require 'fitgem_oauth2/heartrate'
|
|
10
|
+
require 'fitgem_oauth2/sleep'
|
|
11
|
+
require 'fitgem_oauth2/subscriptions'
|
|
12
|
+
require 'fitgem_oauth2/users'
|
|
13
|
+
require 'fitgem_oauth2/utils'
|
|
14
|
+
require 'fitgem_oauth2/version'
|
|
13
15
|
|
|
14
16
|
require 'base64'
|
|
15
17
|
require 'faraday'
|
|
16
18
|
|
|
17
19
|
module FitgemOauth2
|
|
18
20
|
class Client
|
|
19
|
-
|
|
20
21
|
DEFAULT_USER_ID = '-'
|
|
21
22
|
API_VERSION = '1'
|
|
22
23
|
|
|
23
|
-
attr_reader :client_id
|
|
24
|
-
attr_reader :client_secret
|
|
25
|
-
attr_reader :token
|
|
26
|
-
attr_reader :user_id
|
|
27
|
-
attr_reader :unit_system
|
|
24
|
+
attr_reader :client_id, :client_secret, :token, :user_id, :unit_system
|
|
28
25
|
|
|
29
26
|
def initialize(opts)
|
|
30
|
-
missing = [
|
|
31
|
-
|
|
32
|
-
raise FitgemOauth2::InvalidArgumentError, "Missing required options: #{missing.join(',')}"
|
|
33
|
-
end
|
|
27
|
+
missing = %i[client_id client_secret token] - opts.keys
|
|
28
|
+
raise FitgemOauth2::InvalidArgumentError, "Missing required options: #{missing.join(',')}" unless missing.empty?
|
|
34
29
|
|
|
35
30
|
@client_id = opts[:client_id]
|
|
36
31
|
@client_secret = opts[:client_secret]
|
|
37
32
|
@token = opts[:token]
|
|
38
|
-
@user_id =
|
|
33
|
+
@user_id = opts[:user_id] || DEFAULT_USER_ID
|
|
39
34
|
@unit_system = opts[:unit_system]
|
|
40
35
|
@connection = Faraday.new('https://api.fitbit.com')
|
|
41
36
|
end
|
|
@@ -51,76 +46,87 @@ module FitgemOauth2
|
|
|
51
46
|
JSON.parse(response.body)
|
|
52
47
|
end
|
|
53
48
|
|
|
49
|
+
def revoke_token(token)
|
|
50
|
+
response = connection.post('/oauth2/revoke') do |request|
|
|
51
|
+
encoded = Base64.strict_encode64("#{@client_id}:#{@client_secret}")
|
|
52
|
+
request.headers['Authorization'] = "Basic #{encoded}"
|
|
53
|
+
request.headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
|
54
|
+
request.params['token'] = token
|
|
55
|
+
end
|
|
56
|
+
JSON.parse(response.body)
|
|
57
|
+
end
|
|
58
|
+
|
|
54
59
|
def get_call(url)
|
|
55
60
|
url = "#{API_VERSION}/#{url}"
|
|
56
|
-
response = connection.get(url) {
|
|
61
|
+
response = connection.get(url) {|request| set_headers(request) }
|
|
57
62
|
parse_response(response)
|
|
58
63
|
end
|
|
59
64
|
|
|
60
65
|
# This method is a helper method (like get_call) for 1.2 version of the API_VERSION
|
|
61
66
|
# This method is needed because Fitbit API supports both versions as of current
|
|
62
67
|
# date (Nov 5, 2017)
|
|
63
|
-
def
|
|
68
|
+
def get_call12(url)
|
|
64
69
|
url = "1.2/#{url}"
|
|
65
|
-
response = connection.get(url) {|request| set_headers(request)}
|
|
70
|
+
response = connection.get(url) {|request| set_headers(request) }
|
|
66
71
|
parse_response(response)
|
|
67
72
|
end
|
|
68
73
|
|
|
69
|
-
def post_call(url, params
|
|
74
|
+
def post_call(url, params={})
|
|
70
75
|
url = "#{API_VERSION}/#{url}"
|
|
71
|
-
response = connection.post(url, params) {
|
|
76
|
+
response = connection.post(url, params) {|request| set_headers(request) }
|
|
72
77
|
parse_response(response)
|
|
73
78
|
end
|
|
74
79
|
|
|
75
|
-
def
|
|
80
|
+
def post_call12(url, params={})
|
|
76
81
|
url = "1.2/#{url}"
|
|
77
|
-
response = connection.post(url, params) {
|
|
82
|
+
response = connection.post(url, params) {|request| set_headers(request) }
|
|
78
83
|
parse_response(response)
|
|
79
84
|
end
|
|
80
85
|
|
|
81
86
|
def delete_call(url)
|
|
82
87
|
url = "#{API_VERSION}/#{url}"
|
|
83
|
-
response = connection.delete(url) {
|
|
88
|
+
response = connection.delete(url) {|request| set_headers(request) }
|
|
84
89
|
parse_response(response)
|
|
85
90
|
end
|
|
86
91
|
|
|
87
92
|
private
|
|
93
|
+
|
|
88
94
|
attr_reader :connection
|
|
89
95
|
|
|
96
|
+
# rubocop:disable Naming/AccessorMethodName
|
|
90
97
|
def set_headers(request)
|
|
91
98
|
request.headers['Authorization'] = "Bearer #{token}"
|
|
92
99
|
request.headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
|
93
|
-
request.headers['Accept-Language'] = unit_system unless unit_system
|
|
100
|
+
request.headers['Accept-Language'] = unit_system unless unit_system.nil?
|
|
94
101
|
end
|
|
102
|
+
# rubocop:enable Naming/AccessorMethodName
|
|
95
103
|
|
|
96
104
|
def parse_response(response)
|
|
97
|
-
headers_to_keep = %w
|
|
105
|
+
headers_to_keep = %w[fitbit-rate-limit-limit fitbit-rate-limit-remaining fitbit-rate-limit-reset]
|
|
98
106
|
|
|
99
107
|
error_handler = {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
108
|
+
200 => lambda {
|
|
109
|
+
body = JSON.parse(response.body)
|
|
110
|
+
body = {body: body} if body.is_a?(Array)
|
|
111
|
+
headers = response.headers.to_hash.keep_if do |k, _v|
|
|
112
|
+
headers_to_keep.include? k
|
|
113
|
+
end
|
|
114
|
+
body.merge!(headers)
|
|
115
|
+
},
|
|
116
|
+
201 => -> {},
|
|
117
|
+
204 => -> {},
|
|
118
|
+
400 => -> { raise FitgemOauth2::BadRequestError },
|
|
119
|
+
401 => -> { raise FitgemOauth2::UnauthorizedError },
|
|
120
|
+
403 => -> { raise FitgemOauth2::ForbiddenError },
|
|
121
|
+
404 => -> { raise FitgemOauth2::NotFoundError },
|
|
122
|
+
429 => -> { raise FitgemOauth2::ApiLimitError },
|
|
123
|
+
500..599 => -> { raise FitgemOauth2::ServerError }
|
|
116
124
|
}
|
|
117
125
|
|
|
118
|
-
fn = error_handler.
|
|
119
|
-
if fn
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
fn.last.call
|
|
123
|
-
end
|
|
126
|
+
fn = error_handler.find {|k, _| k == response.status }
|
|
127
|
+
raise StandardError, "Unexpected response status #{response.status}" if fn.nil?
|
|
128
|
+
|
|
129
|
+
fn.last.call
|
|
124
130
|
end
|
|
125
131
|
end
|
|
126
132
|
end
|
data/lib/fitgem_oauth2/errors.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module FitgemOauth2
|
|
2
4
|
class Client
|
|
3
5
|
def food_series_for_date_range(start_date, end_date)
|
|
@@ -23,33 +25,5 @@ module FitgemOauth2
|
|
|
23
25
|
validate_food_series_period(period)
|
|
24
26
|
get_call(water_series_url(user_id, format_date(start_date), period))
|
|
25
27
|
end
|
|
26
|
-
|
|
27
|
-
def food_series(resource: nil, start_date: nil, end_date: nil, period: nil)
|
|
28
|
-
warn '[DEPRECATED] use `food_series_for_date_range`, `food_series_for_period`, `water_series_for_date_range`, or `water_series_for_period` instead.'
|
|
29
|
-
unless FOOD_SERIES_RESOURCES.include?(resource)
|
|
30
|
-
raise FitgemOauth2::InvalidArgumentError, "Invalid resource: #{resource}. Specify a valid resource from #{FOOD_SERIES_RESOURCES}"
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
if end_date && period
|
|
34
|
-
raise FitgemOauth2::InvalidArgumentError, 'Provide only one of end_date and period.'
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
if !end_date && !period
|
|
38
|
-
raise FitgemOauth2::InvalidArgumentError, 'Provide at least one of end_date and period.'
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
url = ['user', user_id, 'foods/log', resource, 'date', start_date].join('/')
|
|
42
|
-
|
|
43
|
-
if period
|
|
44
|
-
unless FOOD_SERIES_PERIODS.include?(period)
|
|
45
|
-
raise FitgemOauth2::InvalidArgumentError, "Invalid period: #{period}. Specify a valid period from #{FOOD_SERIES_PERIODS}"
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
second = period || format_date(end_date)
|
|
50
|
-
url = [url, second].join('/')
|
|
51
|
-
|
|
52
|
-
get_call(url + '.json')
|
|
53
|
-
end
|
|
54
28
|
end
|
|
55
29
|
end
|
data/lib/fitgem_oauth2/food.rb
CHANGED
|
@@ -1,27 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require 'fitgem_oauth2/food/
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'fitgem_oauth2/food/collection'
|
|
4
|
+
require 'fitgem_oauth2/food/series'
|
|
5
|
+
require 'fitgem_oauth2/food/metadata'
|
|
4
6
|
|
|
5
7
|
module FitgemOauth2
|
|
6
8
|
class Client
|
|
7
|
-
|
|
8
9
|
FOOD_SERIES_RESOURCES = %w[caloriesIn water].freeze
|
|
9
10
|
FOOD_SERIES_PERIODS = %w[1d 7d 30d 1w 1m 3m 6m 1y max].freeze
|
|
10
11
|
|
|
11
12
|
private
|
|
12
13
|
|
|
13
14
|
def validate_food_series_period(period)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
return if FOOD_SERIES_PERIODS.include?(period)
|
|
16
|
+
|
|
17
|
+
raise FitgemOauth2::InvalidArgumentError,
|
|
18
|
+
"Invalid period: #{period}. Specify a valid period from #{FOOD_SERIES_PERIODS}"
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
def food_series_url(user_id, start_date, end_date_or_period)
|
|
20
|
-
['user', user_id, 'foods/log/caloriesIn', 'date', start_date, end_date_or_period].join('/')
|
|
22
|
+
"#{['user', user_id, 'foods/log/caloriesIn', 'date', start_date, end_date_or_period].join('/')}.json"
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def water_series_url(user_id, start_date, end_date_or_period)
|
|
24
|
-
['user', user_id, 'foods/log/water', 'date', start_date, end_date_or_period].join('/')
|
|
26
|
+
"#{['user', user_id, 'foods/log/water', 'date', start_date, end_date_or_period].join('/')}.json"
|
|
25
27
|
end
|
|
26
28
|
end
|
|
27
29
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module FitgemOauth2
|
|
2
4
|
class Client
|
|
3
|
-
|
|
4
5
|
HR_PERIODS = %w[1d 7d 30d 1w 1m].freeze
|
|
5
6
|
HR_DETAIL_LEVELS = %w[1sec 1min].freeze
|
|
6
7
|
|
|
@@ -9,7 +10,7 @@ module FitgemOauth2
|
|
|
9
10
|
validate_end_date(end_date)
|
|
10
11
|
|
|
11
12
|
url = ['user', user_id, 'activities/heart/date', format_date(start_date), format_date(end_date)].join('/')
|
|
12
|
-
get_call(url
|
|
13
|
+
get_call("#{url}.json")
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
def hr_series_for_period(start_date, period)
|
|
@@ -17,31 +18,14 @@ module FitgemOauth2
|
|
|
17
18
|
validate_hr_period(period)
|
|
18
19
|
|
|
19
20
|
url = ['user', user_id, 'activities/heart/date', format_date(start_date), period].join('/')
|
|
20
|
-
get_call(url
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# retrieve heartrate time series
|
|
24
|
-
def heartrate_time_series(start_date: nil, end_date: nil, period: nil)
|
|
25
|
-
warn '[DEPRECATION] `heartrate_time_series` is deprecated. Please use `hr_series_for_date_range` or `hr_series_for_period` instead.'
|
|
26
|
-
|
|
27
|
-
regular_time_series_guard(
|
|
28
|
-
start_date: start_date,
|
|
29
|
-
end_date: end_date,
|
|
30
|
-
period: period
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
second = period || format_date(end_date)
|
|
34
|
-
|
|
35
|
-
url = ['user', user_id, 'activities/heart/date', format_date(start_date), second].join('/')
|
|
36
|
-
|
|
37
|
-
get_call(url + '.json')
|
|
21
|
+
get_call("#{url}.json")
|
|
38
22
|
end
|
|
39
23
|
|
|
40
24
|
# retrieve intraday series for heartrate
|
|
41
|
-
def intraday_heartrate_time_series(start_date: nil, end_date: nil, detail_level: nil, start_time: nil,
|
|
25
|
+
def intraday_heartrate_time_series(start_date: nil, end_date: nil, detail_level: nil, start_time: nil,
|
|
26
|
+
end_time: nil)
|
|
42
27
|
intraday_series_guard(
|
|
43
28
|
start_date: start_date,
|
|
44
|
-
end_date: end_date,
|
|
45
29
|
detail_level: detail_level,
|
|
46
30
|
start_time: start_time,
|
|
47
31
|
end_time: end_time
|
|
@@ -51,35 +35,30 @@ module FitgemOauth2
|
|
|
51
35
|
|
|
52
36
|
url = ['user', user_id, 'activities/heart/date', format_date(start_date), end_date, detail_level].join('/')
|
|
53
37
|
|
|
54
|
-
if start_time && end_time
|
|
55
|
-
url = [url, 'time', format_time(start_time), format_time(end_time)].join('/')
|
|
56
|
-
end
|
|
38
|
+
url = [url, 'time', format_time(start_time), format_time(end_time)].join('/') if start_time && end_time
|
|
57
39
|
|
|
58
|
-
get_call(url
|
|
40
|
+
get_call("#{url}.json")
|
|
59
41
|
end
|
|
60
42
|
|
|
61
43
|
private
|
|
62
44
|
|
|
63
45
|
def validate_hr_period(period)
|
|
64
|
-
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def regular_time_series_guard(start_date:, end_date:, period:)
|
|
68
|
-
validate_start_date(start_date)
|
|
46
|
+
return if period && HR_PERIODS.include?(period)
|
|
69
47
|
|
|
70
|
-
raise FitgemOauth2::InvalidArgumentError,
|
|
71
|
-
|
|
72
|
-
raise FitgemOauth2::InvalidArgumentError, 'Neither end_date nor period specified. Specify at least one.' if !end_date && !period
|
|
73
|
-
|
|
74
|
-
validate_hr_period(period) if period
|
|
48
|
+
raise FitgemOauth2::InvalidArgumentError, "Invalid period: #{period}. Valid periods are #{HR_PERIODS}."
|
|
75
49
|
end
|
|
76
50
|
|
|
77
|
-
def intraday_series_guard(start_date:,
|
|
78
|
-
raise FitgemOauth2::InvalidArgumentError, 'Start date not provided.' unless
|
|
51
|
+
def intraday_series_guard(start_date:, detail_level:, start_time:, end_time:)
|
|
52
|
+
raise FitgemOauth2::InvalidArgumentError, 'Start date not provided.' unless start_date
|
|
53
|
+
|
|
54
|
+
unless detail_level && HR_DETAIL_LEVELS.include?(detail_level)
|
|
55
|
+
raise FitgemOauth2::InvalidArgumentError,
|
|
56
|
+
"Please specify the defail level. Detail level should be one of #{HR_DETAIL_LEVELS}."
|
|
57
|
+
end
|
|
79
58
|
|
|
80
|
-
|
|
59
|
+
return unless (start_time && !end_time) || (end_time && !start_time)
|
|
81
60
|
|
|
82
|
-
raise FitgemOauth2::InvalidArgumentError, 'Either specify both the start_time and end_time or specify neither.'
|
|
61
|
+
raise FitgemOauth2::InvalidArgumentError, 'Either specify both the start_time and end_time or specify neither.'
|
|
83
62
|
end
|
|
84
63
|
end
|
|
85
64
|
end
|
data/lib/fitgem_oauth2/sleep.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
module FitgemOauth2
|
|
3
4
|
class Client
|
|
4
|
-
|
|
5
5
|
SLEEP_RESOURCES = %w[
|
|
6
6
|
startTime timeInBed minutesAsleep awakeningsCount minutesAwake
|
|
7
7
|
minutesToFallAsleep minutesAfterWakeup efficiency
|
|
@@ -12,11 +12,11 @@ module FitgemOauth2
|
|
|
12
12
|
# retrieve sleep logs for a date
|
|
13
13
|
# @param date date for which sleep logs needs to be accessed
|
|
14
14
|
def sleep_logs(date)
|
|
15
|
-
|
|
15
|
+
get_call12("user/#{user_id}/sleep/date/#{format_date(date)}.json")
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def sleep_logs_by_date_range(start_date, end_date)
|
|
19
|
-
|
|
19
|
+
get_call12("user/#{user_id}/sleep/date/#{format_date(start_date)}/#{format_date(end_date)}.json")
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def sleep_logs_list(date, sort, limit)
|
|
@@ -26,9 +26,9 @@ module FitgemOauth2
|
|
|
26
26
|
elsif sort == 'desc'
|
|
27
27
|
date_param = "beforeDate=#{date_param}"
|
|
28
28
|
else
|
|
29
|
-
raise FitgemOauth2::InvalidArgumentError,
|
|
29
|
+
raise FitgemOauth2::InvalidArgumentError, 'sort can either be asc or desc'
|
|
30
30
|
end
|
|
31
|
-
|
|
31
|
+
get_call12("user/#{user_id}/sleep/list.json?#{date_param}&offset=0&sort=#{sort}&limit=#{limit}")
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
# retrieve sleep goal for the user
|
|
@@ -48,12 +48,11 @@ module FitgemOauth2
|
|
|
48
48
|
# @param end_date ending date for sleep time series
|
|
49
49
|
# @param period period for sleep time series
|
|
50
50
|
def sleep_time_series(resource: nil, start_date: nil, end_date: nil, period: nil)
|
|
51
|
-
unless start_date
|
|
52
|
-
raise FitgemOauth2::InvalidArgumentError, 'Start date not provided.'
|
|
53
|
-
end
|
|
51
|
+
raise FitgemOauth2::InvalidArgumentError, 'Start date not provided.' unless start_date
|
|
54
52
|
|
|
55
53
|
unless resource && SLEEP_RESOURCES.include?(resource)
|
|
56
|
-
raise FitgemOauth2::InvalidArgumentError,
|
|
54
|
+
raise FitgemOauth2::InvalidArgumentError,
|
|
55
|
+
"Invalid resource: #{resource}. Valid resources are #{SLEEP_RESOURCES}."
|
|
57
56
|
end
|
|
58
57
|
|
|
59
58
|
if period && end_date
|
|
@@ -68,13 +67,13 @@ module FitgemOauth2
|
|
|
68
67
|
|
|
69
68
|
url = ['user', user_id, 'sleep', resource, 'date', format_date(start_date), second].join('/')
|
|
70
69
|
|
|
71
|
-
get_call(url
|
|
70
|
+
get_call("#{url}.json")
|
|
72
71
|
end
|
|
73
72
|
|
|
74
73
|
# log sleep
|
|
75
74
|
# @param params POST params for creating sleep log
|
|
76
75
|
def log_sleep(params)
|
|
77
|
-
|
|
76
|
+
post_call12("user/#{user_id}/sleep.json", params)
|
|
78
77
|
end
|
|
79
78
|
|
|
80
79
|
# deleted sleep log
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module FitgemOauth2
|
|
2
4
|
class Client
|
|
3
|
-
|
|
4
5
|
SUBSCRIBABLE_TYPES = %i[sleep body activities foods all].freeze
|
|
5
6
|
|
|
6
7
|
def subscriptions(opts)
|
|
@@ -26,7 +27,7 @@ module FitgemOauth2
|
|
|
26
27
|
url << 'apiSubscriptions'
|
|
27
28
|
url << subscription_id if subscription_id
|
|
28
29
|
|
|
29
|
-
url.join('/')
|
|
30
|
+
"#{url.join('/')}.json"
|
|
30
31
|
end
|
|
31
32
|
end
|
|
32
33
|
end
|
data/lib/fitgem_oauth2/users.rb
CHANGED
data/lib/fitgem_oauth2/utils.rb
CHANGED
|
@@ -1,29 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module FitgemOauth2
|
|
2
4
|
class Client
|
|
3
5
|
def format_date(date)
|
|
4
|
-
|
|
5
6
|
return nil if date.nil?
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
valid_date_string = (date =~ /\d{4}\-\d{2}\-\d{2}/) == 0
|
|
9
|
-
if valid_date_string
|
|
8
|
+
if date.is_a?(String) && date.match?(/\A\d{4}-\d{2}-\d{2}\z/)
|
|
10
9
|
date
|
|
11
|
-
elsif
|
|
10
|
+
elsif date.is_a?(String) && %w[today yesterday].include?(date)
|
|
12
11
|
date_from_semantic(date)
|
|
13
12
|
elsif date.is_a?(Date) || date.is_a?(Time) || date.is_a?(DateTime)
|
|
14
13
|
date.strftime('%Y-%m-%d')
|
|
15
14
|
else
|
|
16
|
-
raise FitgemOauth2::InvalidDateArgument,
|
|
15
|
+
raise FitgemOauth2::InvalidDateArgument,
|
|
16
|
+
'Date used must be a date/time object or a string in the format YYYY-MM-DD; ' \
|
|
17
|
+
"supplied argument is a #{date.class}"
|
|
17
18
|
end
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
def format_time(time)
|
|
21
|
-
if (
|
|
22
|
+
if time.is_a?(String) && time.match?(/\A\d{2}:\d{2}\z/)
|
|
22
23
|
time
|
|
23
24
|
elsif time.is_a?(DateTime) || time.is_a?(Time)
|
|
24
25
|
time.strftime('%H:%M')
|
|
25
26
|
else
|
|
26
|
-
raise FitgemOauth2::InvalidTimeArgument,
|
|
27
|
+
raise FitgemOauth2::InvalidTimeArgument,
|
|
28
|
+
'Time used must be a DateTime/Time object or a string in the format hh:mm; ' \
|
|
29
|
+
"supplied argument is a #{time.class}"
|
|
27
30
|
end
|
|
28
31
|
end
|
|
29
32
|
|
|
@@ -38,7 +41,7 @@ module FitgemOauth2
|
|
|
38
41
|
private
|
|
39
42
|
|
|
40
43
|
def date_from_semantic(semantic)
|
|
41
|
-
if semantic
|
|
44
|
+
if semantic == 'yesterday'
|
|
42
45
|
(Date.today - 1).strftime('%Y-%m-%d')
|
|
43
46
|
elsif semantic == 'today'
|
|
44
47
|
Date.today.strftime('%Y-%m-%d')
|
data/lib/fitgem_oauth2.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fitgem_oauth2
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 4.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ankit Gupta
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-02-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -16,56 +16,56 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: '2.0'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
26
|
+
version: '2.0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
28
|
+
name: factory_bot
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
33
|
+
version: '6.0'
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
40
|
+
version: '6.0'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
42
|
+
name: rake
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '
|
|
47
|
+
version: '13.0'
|
|
48
48
|
type: :development
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '
|
|
54
|
+
version: '13.0'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
56
|
+
name: rspec
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
59
|
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '4
|
|
61
|
+
version: '3.4'
|
|
62
62
|
type: :development
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '4
|
|
68
|
+
version: '3.4'
|
|
69
69
|
description: This gem allows requesting data from Fitbit API using OAuth2
|
|
70
70
|
email: ankit.gupta2801@gmail.com
|
|
71
71
|
executables: []
|
|
@@ -93,8 +93,9 @@ files:
|
|
|
93
93
|
homepage: http://rubygems.org/gems/fitgem_oauth2
|
|
94
94
|
licenses:
|
|
95
95
|
- MIT
|
|
96
|
-
metadata:
|
|
97
|
-
|
|
96
|
+
metadata:
|
|
97
|
+
rubygems_mfa_required: 'true'
|
|
98
|
+
post_install_message:
|
|
98
99
|
rdoc_options: []
|
|
99
100
|
require_paths:
|
|
100
101
|
- lib
|
|
@@ -102,15 +103,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
102
103
|
requirements:
|
|
103
104
|
- - ">="
|
|
104
105
|
- !ruby/object:Gem::Version
|
|
105
|
-
version:
|
|
106
|
+
version: 3.2.0
|
|
106
107
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
108
|
requirements:
|
|
108
109
|
- - ">="
|
|
109
110
|
- !ruby/object:Gem::Version
|
|
110
111
|
version: '0'
|
|
111
112
|
requirements: []
|
|
112
|
-
rubygems_version: 3.
|
|
113
|
-
signing_key:
|
|
113
|
+
rubygems_version: 3.4.10
|
|
114
|
+
signing_key:
|
|
114
115
|
specification_version: 4
|
|
115
116
|
summary: Fitbit API client library
|
|
116
117
|
test_files: []
|