fitgem_oauth2 1.3.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,163 +1,163 @@
1
- module FitgemOauth2
2
- 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)
7
-
8
- # ======================================
9
- # Boday Fat
10
- # ======================================
11
-
12
- # retrieves a list of all user's body fat log entries
13
- # note: provide either end_date or period
14
- # @param start_date start date for the logs
15
- # @param end_date (optional)end date for the logs
16
- # @param period (optional) period for the logs
17
- 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
21
- 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
25
-
26
- if period
27
- if FAT_PERIODS.include?(period)
28
- url = [url, period].join('/')
29
- else
30
- raise FitgemOauth2::InvalidArgumentError, "period must be one in #{FAT_PERIODS}"
31
- end
32
- end
33
-
34
- url = url + '.json'
35
-
36
- get_call(url)
37
- end
38
-
39
- # logs body fat
40
- # @param params POST parameters for logging body fat
41
- def log_body_fat(params)
42
- post_call("user/#{user_id}/body/log/fat.json", params)
43
- end
44
-
45
- # delete logged body fat
46
- # @param id ID of the log to be deleted.
47
- def delete_logged_body_fat(id)
48
- delete_call("user/#{user_id}/body/log/fat/#{id}.json")
49
- end
50
-
51
-
52
- # ==================================
53
- # Body Time Series
54
- # ==================================
55
-
56
- # retrieve body time series for the user; provide at least one of end_date and period
57
- # @param resource (required)the resource requested ['bmi', 'fat', or 'weight']
58
- # @param start_date (required)the start date for the series
59
- # @param end_date (optional)the end date for the series
60
- # @param period (optional)period for the time series. valid periods are BODY_TIME_SERIES_PERIODS
61
- def body_time_series(resource: nil, start_date: nil, end_date: nil, period: nil)
62
- unless resource && start_date
63
- raise FitgemOauth2::InvalidArgumentError, 'resource and start_date are required parameters. Please specify both.'
64
- end
65
-
66
- url = ['user', user_id, 'body', resource, 'date', format_date(start_date)].join('/')
67
-
68
- second = ''
69
- if end_date && period
70
- raise FitgemOauth2::InvalidArgumentError, 'Please specify either period or end date, not both.'
71
- end
72
-
73
- if period
74
- if BODY_TIME_SERIES_PERIODS.include?(period)
75
- second = period
76
- else
77
- raise FitgemOauth2::InvalidArgumentError, "Invalid Period. Body time series period must be in #{BODY_TIME_SERIES_PERIODS}"
78
- end
79
- end
80
-
81
- if end_date
82
- second = format_date(end_date)
83
- end
84
-
85
- url = [url, second].join('/')
86
-
87
- get_call(url + '.json')
88
- end
89
-
90
-
91
- # ======================================
92
- # Body Goals
93
- # ======================================
94
-
95
- # retrieves body goals based on the type specified
96
- # @param type 'fat' or 'weight'
97
- def body_goals(type)
98
- if type && BODY_GOALS.include?(type)
99
- get_call("user/#{user_id}/body/log/#{type}/goal.json")
100
- else
101
- raise FitgemOauth2::InvalidArgumentError, "invalid goal type : #{type}. must be one of #{BODY_GOALS}"
102
- end
103
- end
104
-
105
- # update body fat goal
106
- # @param params POST params for updating body fat goal
107
- def update_body_fat_goal(params)
108
- post_call("user/#{user_id}/body/log/fat/goal.json", params)
109
- end
110
-
111
- # update weight goal
112
- # @param params POST params for updating weight goal
113
- def update_weight_goal(params)
114
- post_call("user/#{user_id}/body/log/weight/goal.json", params)
115
- end
116
-
117
- # ======================================
118
- # Body Weight
119
- # ======================================
120
-
121
- # retrieve weight logs; specify either the end_date or period
122
- # @param start_date start date for the logs
123
- # @param end_date (optional)end_date for the logs
124
- # @param period (optional)period for the logs
125
- 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
129
-
130
- if period && end_date
131
- raise FitgemOauth2::InvalidArgumentError, 'both end_date and period specified. please provide only one.'
132
- end
133
-
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
138
- end
139
-
140
- first = format_date(start_date)
141
- url = ['user', user_id, 'body/log/weight/date', first].join('/')
142
- if period || end_date
143
- second = period || format_date(end_date)
144
- url = [url, second].join('/')
145
- end
146
-
147
- get_call(url + '.json')
148
- end
149
-
150
- # logs weight for the user
151
- # @param params POST message for logging weight
152
- def log_weight(params)
153
- post_call("user/#{user_id}/body/log/weight.json", params)
154
- end
155
-
156
- # delete logged weight
157
- # @param id ID of the weight log to be deleted
158
- def delete_logged_weight(id)
159
- delete_call("user/#{user_id}/body/log/weight/#{id}.json")
160
- end
161
-
162
- end
163
- end
1
+ module FitgemOauth2
2
+ 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)
7
+
8
+ # ======================================
9
+ # Boday Fat
10
+ # ======================================
11
+
12
+ # retrieves a list of all user's body fat log entries
13
+ # note: provide either end_date or period
14
+ # @param start_date start date for the logs
15
+ # @param end_date (optional)end date for the logs
16
+ # @param period (optional) period for the logs
17
+ 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
21
+ 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
25
+
26
+ if period
27
+ if FAT_PERIODS.include?(period)
28
+ url = [url, period].join('/')
29
+ else
30
+ raise FitgemOauth2::InvalidArgumentError, "period must be one in #{FAT_PERIODS}"
31
+ end
32
+ end
33
+
34
+ url = url + '.json'
35
+
36
+ get_call(url)
37
+ end
38
+
39
+ # logs body fat
40
+ # @param params POST parameters for logging body fat
41
+ def log_body_fat(params)
42
+ post_call("user/#{user_id}/body/log/fat.json", params)
43
+ end
44
+
45
+ # delete logged body fat
46
+ # @param id ID of the log to be deleted.
47
+ def delete_logged_body_fat(id)
48
+ delete_call("user/#{user_id}/body/log/fat/#{id}.json")
49
+ end
50
+
51
+
52
+ # ==================================
53
+ # Body Time Series
54
+ # ==================================
55
+
56
+ # retrieve body time series for the user; provide at least one of end_date and period
57
+ # @param resource (required)the resource requested ['bmi', 'fat', or 'weight']
58
+ # @param start_date (required)the start date for the series
59
+ # @param end_date (optional)the end date for the series
60
+ # @param period (optional)period for the time series. valid periods are BODY_TIME_SERIES_PERIODS
61
+ def body_time_series(resource: nil, start_date: nil, end_date: nil, period: nil)
62
+ unless resource && start_date
63
+ raise FitgemOauth2::InvalidArgumentError, 'resource and start_date are required parameters. Please specify both.'
64
+ end
65
+
66
+ url = ['user', user_id, 'body', resource, 'date', format_date(start_date)].join('/')
67
+
68
+ second = ''
69
+ if end_date && period
70
+ raise FitgemOauth2::InvalidArgumentError, 'Please specify either period or end date, not both.'
71
+ end
72
+
73
+ if period
74
+ if BODY_TIME_SERIES_PERIODS.include?(period)
75
+ second = period
76
+ else
77
+ raise FitgemOauth2::InvalidArgumentError, "Invalid Period. Body time series period must be in #{BODY_TIME_SERIES_PERIODS}"
78
+ end
79
+ end
80
+
81
+ if end_date
82
+ second = format_date(end_date)
83
+ end
84
+
85
+ url = [url, second].join('/')
86
+
87
+ get_call(url + '.json')
88
+ end
89
+
90
+
91
+ # ======================================
92
+ # Body Goals
93
+ # ======================================
94
+
95
+ # retrieves body goals based on the type specified
96
+ # @param type 'fat' or 'weight'
97
+ def body_goals(type)
98
+ if type && BODY_GOALS.include?(type)
99
+ get_call("user/#{user_id}/body/log/#{type}/goal.json")
100
+ else
101
+ raise FitgemOauth2::InvalidArgumentError, "invalid goal type : #{type}. must be one of #{BODY_GOALS}"
102
+ end
103
+ end
104
+
105
+ # update body fat goal
106
+ # @param params POST params for updating body fat goal
107
+ def update_body_fat_goal(params)
108
+ post_call("user/#{user_id}/body/log/fat/goal.json", params)
109
+ end
110
+
111
+ # update weight goal
112
+ # @param params POST params for updating weight goal
113
+ def update_weight_goal(params)
114
+ post_call("user/#{user_id}/body/log/weight/goal.json", params)
115
+ end
116
+
117
+ # ======================================
118
+ # Body Weight
119
+ # ======================================
120
+
121
+ # retrieve weight logs; specify either the end_date or period
122
+ # @param start_date start date for the logs
123
+ # @param end_date (optional)end_date for the logs
124
+ # @param period (optional)period for the logs
125
+ 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
129
+
130
+ if period && end_date
131
+ raise FitgemOauth2::InvalidArgumentError, 'both end_date and period specified. please provide only one.'
132
+ end
133
+
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
138
+ end
139
+
140
+ first = format_date(start_date)
141
+ url = ['user', user_id, 'body/log/weight/date', first].join('/')
142
+ if period || end_date
143
+ second = period || format_date(end_date)
144
+ url = [url, second].join('/')
145
+ end
146
+
147
+ get_call(url + '.json')
148
+ end
149
+
150
+ # logs weight for the user
151
+ # @param params POST message for logging weight
152
+ def log_weight(params)
153
+ post_call("user/#{user_id}/body/log/weight.json", params)
154
+ end
155
+
156
+ # delete logged weight
157
+ # @param id ID of the weight log to be deleted
158
+ def delete_logged_weight(id)
159
+ delete_call("user/#{user_id}/body/log/weight/#{id}.json")
160
+ end
161
+
162
+ end
163
+ end
@@ -1,125 +1,126 @@
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'
13
-
14
- require 'base64'
15
- require 'faraday'
16
-
17
- module FitgemOauth2
18
- class Client
19
-
20
- DEFAULT_USER_ID = '-'
21
- API_VERSION = '1'
22
-
23
- attr_reader :client_id
24
- attr_reader :client_secret
25
- attr_reader :token
26
- attr_reader :user_id
27
- attr_reader :unit_system
28
-
29
- 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
34
-
35
- @client_id = opts[:client_id]
36
- @client_secret = opts[:client_secret]
37
- @token = opts[:token]
38
- @user_id = (opts[:user_id] || DEFAULT_USER_ID)
39
- @unit_system = opts[:unit_system]
40
- @connection = Faraday.new('https://api.fitbit.com')
41
- end
42
-
43
- def refresh_access_token(refresh_token)
44
- response = connection.post('/oauth2/token') do |request|
45
- encoded = Base64.strict_encode64("#{@client_id}:#{@client_secret}")
46
- request.headers['Authorization'] = "Basic #{encoded}"
47
- request.headers['Content-Type'] = 'application/x-www-form-urlencoded'
48
- request.params['grant_type'] = 'refresh_token'
49
- request.params['refresh_token'] = refresh_token
50
- end
51
- JSON.parse(response.body)
52
- end
53
-
54
- def get_call(url)
55
- url = "#{API_VERSION}/#{url}"
56
- response = connection.get(url) { |request| set_headers(request) }
57
- parse_response(response)
58
- end
59
-
60
- # This method is a helper method (like get_call) for 1.2 version of the API_VERSION
61
- # This method is needed because Fitbit API supports both versions as of current
62
- # date (Nov 5, 2017)
63
- def get_call_1_2(url)
64
- url = "1.2/#{url}"
65
- response = connection.get(url) {|request| set_headers(request)}
66
- parse_response(response)
67
- end
68
-
69
- def post_call(url, params = {})
70
- url = "#{API_VERSION}/#{url}"
71
- response = connection.post(url, params) { |request| set_headers(request) }
72
- parse_response(response)
73
- end
74
-
75
- def post_call_1_2(url, params = {})
76
- url = "1.2/#{url}"
77
- response = connection.post(url, params) { |request| set_headers(request) }
78
- parse_response(response)
79
- end
80
-
81
- def delete_call(url)
82
- url = "#{API_VERSION}/#{url}"
83
- response = connection.delete(url) { |request| set_headers(request) }
84
- parse_response(response)
85
- end
86
-
87
- private
88
- attr_reader :connection
89
-
90
- def set_headers(request)
91
- request.headers['Authorization'] = "Bearer #{token}"
92
- request.headers['Content-Type'] = 'application/x-www-form-urlencoded'
93
- request.headers['Accept-Language'] = unit_system unless unit_system == nil
94
- end
95
-
96
- def parse_response(response)
97
- headers_to_keep = %w(fitbit-rate-limit-limit fitbit-rate-limit-remaining fitbit-rate-limit-reset)
98
-
99
- 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
- 500..599 => lambda { raise FitgemOauth2::ServerError }
115
- }
116
-
117
- fn = error_handler.detect { |k, _| k === response.status }
118
- if fn === nil
119
- raise StandardError, "Unexpected response status #{response.status}"
120
- else
121
- fn.last.call
122
- end
123
- end
124
- end
125
- end
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'
13
+
14
+ require 'base64'
15
+ require 'faraday'
16
+
17
+ module FitgemOauth2
18
+ class Client
19
+
20
+ DEFAULT_USER_ID = '-'
21
+ API_VERSION = '1'
22
+
23
+ attr_reader :client_id
24
+ attr_reader :client_secret
25
+ attr_reader :token
26
+ attr_reader :user_id
27
+ attr_reader :unit_system
28
+
29
+ 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
34
+
35
+ @client_id = opts[:client_id]
36
+ @client_secret = opts[:client_secret]
37
+ @token = opts[:token]
38
+ @user_id = (opts[:user_id] || DEFAULT_USER_ID)
39
+ @unit_system = opts[:unit_system]
40
+ @connection = Faraday.new('https://api.fitbit.com')
41
+ end
42
+
43
+ def refresh_access_token(refresh_token)
44
+ response = connection.post('/oauth2/token') do |request|
45
+ encoded = Base64.strict_encode64("#{@client_id}:#{@client_secret}")
46
+ request.headers['Authorization'] = "Basic #{encoded}"
47
+ request.headers['Content-Type'] = 'application/x-www-form-urlencoded'
48
+ request.params['grant_type'] = 'refresh_token'
49
+ request.params['refresh_token'] = refresh_token
50
+ end
51
+ JSON.parse(response.body)
52
+ end
53
+
54
+ def get_call(url)
55
+ url = "#{API_VERSION}/#{url}"
56
+ response = connection.get(url) { |request| set_headers(request) }
57
+ parse_response(response)
58
+ end
59
+
60
+ # This method is a helper method (like get_call) for 1.2 version of the API_VERSION
61
+ # This method is needed because Fitbit API supports both versions as of current
62
+ # date (Nov 5, 2017)
63
+ def get_call_1_2(url)
64
+ url = "1.2/#{url}"
65
+ response = connection.get(url) {|request| set_headers(request)}
66
+ parse_response(response)
67
+ end
68
+
69
+ def post_call(url, params = {})
70
+ url = "#{API_VERSION}/#{url}"
71
+ response = connection.post(url, params) { |request| set_headers(request) }
72
+ parse_response(response)
73
+ end
74
+
75
+ def post_call_1_2(url, params = {})
76
+ url = "1.2/#{url}"
77
+ response = connection.post(url, params) { |request| set_headers(request) }
78
+ parse_response(response)
79
+ end
80
+
81
+ def delete_call(url)
82
+ url = "#{API_VERSION}/#{url}"
83
+ response = connection.delete(url) { |request| set_headers(request) }
84
+ parse_response(response)
85
+ end
86
+
87
+ private
88
+ attr_reader :connection
89
+
90
+ def set_headers(request)
91
+ request.headers['Authorization'] = "Bearer #{token}"
92
+ request.headers['Content-Type'] = 'application/x-www-form-urlencoded'
93
+ request.headers['Accept-Language'] = unit_system unless unit_system == nil
94
+ end
95
+
96
+ def parse_response(response)
97
+ headers_to_keep = %w(fitbit-rate-limit-limit fitbit-rate-limit-remaining fitbit-rate-limit-reset)
98
+
99
+ 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 }
116
+ }
117
+
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
124
+ end
125
+ end
126
+ end