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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d549d93c4f0c6e8c6c217f6d18ad69b11f5b90ed3ee42e39fe19ed25ca12a27a
4
- data.tar.gz: 0d5d8ecf9c0bb6563cd1ecba8d65f1458076113f2ba79d2e3d98b54fc5b0ed3c
3
+ metadata.gz: cb6abab3890862d921de4c7f36128afc601bbb2579382f67164929cbd4deba3e
4
+ data.tar.gz: 740cb87e8fdfdae9a3437b59d63486e85bb58567cdad1d22cdb5a90e7daa2b55
5
5
  SHA512:
6
- metadata.gz: 13211f94cbf789323aa48718019c6831022dd099e8926c20f3cd5c1fcb1382b61e111d3403253399bbce0d8a75b2f69ce8860c2002f810f9e95095fac44186b8
7
- data.tar.gz: 26ef31364d04f7fc7c8c218ffd669952712271204d415492d5d72650ada09a5cf3ba2542eb011c71f6cbec06a66a7d1603813f374da1612e9b655796f90ef1b5
6
+ metadata.gz: 94a1a3f44eef697b5de5a67a992322995e3184fd5142b9896b8e2827d97abf5949aaa5bd07dd88503787bc13defad8ae1215460bfd3a026bcbf3cb41504fd2b8
7
+ data.tar.gz: c85fab5f3b82b37fca9302fcf55f36c1e0f0b83be4f00a743919caafe879d97a1dd9d5df94c4336de221d063b2bd5923ccd08b654a6a01b30f4fa41d6ca9ab8b
@@ -1,6 +1,6 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- $:.unshift File.expand_path('../lib', __FILE__)
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(fitgem_oauth2.gemspec) + `git ls-files -z`.split("\x0").select { |f| f.start_with?('lib/') }
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.add_runtime_dependency 'faraday', '~> 1.0.1'
18
+ s.required_ruby_version = '>= 3.2.0'
18
19
 
19
- s.add_development_dependency 'rake', '~> 13.0.1'
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. If specifying end_date, do not specify period
29
- # @param period the period starting from start_date for which the series needs to be retrieved. If specifying period,
30
- # do not use end_date
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, "Invalid resource: #{resource}. Valid resources are #{ACTIVITY_RESOURCES}."
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 + '.json')
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. one of 'calories', 'steps', 'distance', 'floors', 'elevation'
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
- ' One of (:calories, :steps, :distance, :floors, or :elevation) is required.'
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(1min 15min).include?(detail_level)
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
- ' One of (\"1d\" or \"15min\") is required.'
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
- 'user', @user_id,
89
- 'activities', resource,
90
- 'date', format_date(start_date),
91
- end_date, detail_level
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
- [resource_path, 'time', format_time(start_time), format_time(end_time)].join('/')
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 == "asc"
122
+ if sort == 'asc'
122
123
  date_param = "afterDate=#{date_param}"
123
- elsif sort == "desc"
124
+ elsif sort == 'desc'
124
125
  date_param = "beforeDate=#{date_param}"
125
126
  else
126
- raise FitgemOauth2::InvalidArgumentError, "sort can either be asc or desc"
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(daily weekly).include?(period)
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(daily weekly).include?(period)
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(1d 7d 1w 1m)
4
- WEIGHT_PERIODS = %w(1d 7d 30d 1w 1m)
5
- BODY_GOALS = %w(fat weight)
6
- BODY_TIME_SERIES_PERIODS = %w(1d 7d 30d 1w 1m 3m 6m 1y max)
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
- raise FitgemOauth2::InvalidArgumentError, 'must specify start_date'
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
- if FAT_PERIODS.include?(period)
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 = url + '.json'
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, 'resource and start_date are required parameters. Please specify both.'
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, "Invalid Period. Body time series period must be in #{BODY_TIME_SERIES_PERIODS}"
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 + '.json')
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
- if type && BODY_GOALS.include?(type)
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
- unless WEIGHT_PERIODS.include?(period)
136
- raise FitgemOauth2::InvalidArgumentError, "valid period not specified. please choose a period from #{WEIGHT_PERIODS}"
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 + '.json')
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
@@ -1,41 +1,36 @@
1
- require 'fitgem_oauth2/activity.rb'
2
- require 'fitgem_oauth2/body_measurements.rb'
3
- require 'fitgem_oauth2/devices.rb'
4
- require 'fitgem_oauth2/errors.rb'
5
- require 'fitgem_oauth2/food.rb'
6
- require 'fitgem_oauth2/friends.rb'
7
- require 'fitgem_oauth2/heartrate.rb'
8
- require 'fitgem_oauth2/sleep.rb'
9
- require 'fitgem_oauth2/subscriptions.rb'
10
- require 'fitgem_oauth2/users.rb'
11
- require 'fitgem_oauth2/utils.rb'
12
- require 'fitgem_oauth2/version.rb'
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 = [:client_id, :client_secret, :token] - opts.keys
31
- if missing.size > 0
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 = (opts[:user_id] || DEFAULT_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) { |request| set_headers(request) }
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 get_call_1_2(url)
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) { |request| set_headers(request) }
76
+ response = connection.post(url, params) {|request| set_headers(request) }
72
77
  parse_response(response)
73
78
  end
74
79
 
75
- def post_call_1_2(url, params = {})
80
+ def post_call12(url, params={})
76
81
  url = "1.2/#{url}"
77
- response = connection.post(url, params) { |request| set_headers(request) }
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) { |request| set_headers(request) }
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 == nil
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(fitbit-rate-limit-limit fitbit-rate-limit-remaining fitbit-rate-limit-reset)
105
+ headers_to_keep = %w[fitbit-rate-limit-limit fitbit-rate-limit-remaining fitbit-rate-limit-reset]
98
106
 
99
107
  error_handler = {
100
- 200 => lambda {
101
- body = JSON.parse(response.body)
102
- body = {body: body} if body.is_a?(Array)
103
- headers = response.headers.to_hash.keep_if { |k,v|
104
- headers_to_keep.include? k
105
- }
106
- body.merge!(headers)
107
- },
108
- 201 => lambda { },
109
- 204 => lambda { },
110
- 400 => lambda { raise FitgemOauth2::BadRequestError },
111
- 401 => lambda { raise FitgemOauth2::UnauthorizedError },
112
- 403 => lambda { raise FitgemOauth2::ForbiddenError },
113
- 404 => lambda { raise FitgemOauth2::NotFoundError },
114
- 429 => lambda { raise FitgemOauth2::ApiLimitError },
115
- 500..599 => lambda { raise FitgemOauth2::ServerError }
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.detect { |k, _| k === response.status }
119
- if fn === nil
120
- raise StandardError, "Unexpected response status #{response.status}"
121
- else
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
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FitgemOauth2
2
4
  class Client
3
-
4
5
  # ==================================
5
6
  # Devices
6
7
  # ==================================
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FitgemOauth2
2
4
  class InvalidDateArgument < ArgumentError
3
5
  end
4
6
 
5
7
  class InvalidTimeArgument < ArgumentError
6
-
7
8
  end
8
9
 
9
10
  class InvalidArgumentError < ArgumentError
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FitgemOauth2
2
4
  class Client
3
5
  def food_goals
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FitgemOauth2
2
4
  class Client
3
5
  def add_favorite_food(food_id)
@@ -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
@@ -1,27 +1,29 @@
1
- require 'fitgem_oauth2/food/collection.rb'
2
- require 'fitgem_oauth2/food/series.rb'
3
- require 'fitgem_oauth2/food/metadata.rb'
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
- unless FOOD_SERIES_PERIODS.include?(period)
15
- raise FitgemOauth2::InvalidArgumentError, "Invalid period: #{period}. Specify a valid period from #{FOOD_SERIES_PERIODS}"
16
- end
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('/') + '.json'
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('/') + '.json'
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,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FitgemOauth2
2
4
  class Client
3
5
  # retrieves list of friends for the current user
@@ -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 + '.json')
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 + '.json')
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, end_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 + '.json')
40
+ get_call("#{url}.json")
59
41
  end
60
42
 
61
43
  private
62
44
 
63
45
  def validate_hr_period(period)
64
- raise FitgemOauth2::InvalidArgumentError, "Invalid period: #{period}. Valid periods are #{HR_PERIODS}." unless period && HR_PERIODS.include?(period)
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, 'Both end_date and period specified. Specify only one.' if end_date && period
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:, end_date:, detail_level:, start_time:, end_time:)
78
- raise FitgemOauth2::InvalidArgumentError, 'Start date not provided.' unless start_date
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
- raise FitgemOauth2::InvalidArgumentError, "Please specify the defail level. Detail level should be one of #{HR_DETAIL_LEVELS}." unless detail_level && HR_DETAIL_LEVELS.include?(detail_level)
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.' if (start_time && !end_time) || (end_time && !start_time)
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
@@ -1,7 +1,7 @@
1
- module FitgemOauth2
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
- get_call_1_2("user/#{user_id}/sleep/date/#{format_date(date)}.json")
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
- get_call_1_2("user/#{user_id}/sleep/date/#{format_date(start_date)}/#{format_date(end_date)}.json")
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, "sort can either be asc or desc"
29
+ raise FitgemOauth2::InvalidArgumentError, 'sort can either be asc or desc'
30
30
  end
31
- get_call_1_2("user/#{user_id}/sleep/list.json?#{date_param}&offset=0&sort=#{sort}&limit=#{limit}")
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, "Invalid resource: #{resource}. Valid resources are #{SLEEP_RESOURCES}."
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 + '.json')
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
- post_call_1_2("user/#{user_id}/sleep.json", params)
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('/') + '.json'
30
+ "#{url.join('/')}.json"
30
31
  end
31
32
  end
32
33
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FitgemOauth2
2
4
  class Client
3
5
  def user_info
@@ -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
- valid_semantic_date = %w[today yesterday].include? date
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 valid_semantic_date
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, "Date used must be a date/time object or a string in the format YYYY-MM-DD; supplied argument is a #{date.class}"
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 (time =~ /\d{2}:\d{2}/) == 0
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, "Time used must be a DateTime/Time object or a string in the format hh:mm; supplied argument is a #{time.class}"
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 === 'yesterday'
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')
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FitgemOauth2
2
- VERSION = '2.2.0'.freeze
4
+ VERSION = '4.0.0'
3
5
  end
data/lib/fitgem_oauth2.rb CHANGED
@@ -1,6 +1,7 @@
1
- require 'fitgem_oauth2/client.rb'
1
+ # frozen_string_literal: true
2
+
3
+ require 'fitgem_oauth2/client'
2
4
 
3
5
  # Top level module for the classes for this gem
4
6
  module FitgemOauth2
5
-
6
7
  end
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: 2.2.0
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: 2020-08-26 00:00:00.000000000 Z
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: 1.0.1
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: 1.0.1
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: factory_bot
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 13.0.1
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: 13.0.1
40
+ version: '6.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '3.4'
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: '3.4'
54
+ version: '13.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: factory_girl
56
+ name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '4.5'
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.5'
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
- post_install_message:
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: '0'
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.0.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: []