fitbark 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +6 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +80 -0
- data/LICENSE.txt +21 -0
- data/README.md +194 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/fitbark.gemspec +37 -0
- data/lib/fitbark.rb +45 -0
- data/lib/fitbark/auth.rb +125 -0
- data/lib/fitbark/client.rb +54 -0
- data/lib/fitbark/constants.rb +17 -0
- data/lib/fitbark/data/activity_daily.rb +52 -0
- data/lib/fitbark/data/activity_hourly.rb +46 -0
- data/lib/fitbark/data/activity_level.rb +28 -0
- data/lib/fitbark/data/breed.rb +12 -0
- data/lib/fitbark/data/daily_goal.rb +25 -0
- data/lib/fitbark/data/dog_info.rb +118 -0
- data/lib/fitbark/data/dog_relation.rb +27 -0
- data/lib/fitbark/data/medical_condition.rb +12 -0
- data/lib/fitbark/data/picture.rb +21 -0
- data/lib/fitbark/data/shared.rb +36 -0
- data/lib/fitbark/data/similar_dogs_stat.rb +22 -0
- data/lib/fitbark/data/token.rb +35 -0
- data/lib/fitbark/data/token_info.rb +29 -0
- data/lib/fitbark/data/user_info.rb +27 -0
- data/lib/fitbark/data/user_preview.rb +25 -0
- data/lib/fitbark/data/user_relation.rb +26 -0
- data/lib/fitbark/errors.rb +33 -0
- data/lib/fitbark/handler/v2/activity_series.rb +90 -0
- data/lib/fitbark/handler/v2/activity_total.rb +65 -0
- data/lib/fitbark/handler/v2/base.rb +54 -0
- data/lib/fitbark/handler/v2/daily_goals.rb +37 -0
- data/lib/fitbark/handler/v2/dog_info.rb +39 -0
- data/lib/fitbark/handler/v2/dog_picture.rb +39 -0
- data/lib/fitbark/handler/v2/dog_relations.rb +37 -0
- data/lib/fitbark/handler/v2/friend_dogs.rb +39 -0
- data/lib/fitbark/handler/v2/own_dogs.rb +38 -0
- data/lib/fitbark/handler/v2/set_daily_goal.rb +68 -0
- data/lib/fitbark/handler/v2/similar_dogs_stats.rb +37 -0
- data/lib/fitbark/handler/v2/time_breakdown.rb +63 -0
- data/lib/fitbark/handler/v2/user_info.rb +35 -0
- data/lib/fitbark/handler/v2/user_picture.rb +39 -0
- data/lib/fitbark/handler/v2/user_relations.rb +37 -0
- data/lib/fitbark/version.rb +4 -0
- metadata +234 -0
data/bin/setup
ADDED
data/fitbark.gemspec
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'fitbark/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'fitbark'
|
7
|
+
spec.version = Fitbark::VERSION
|
8
|
+
spec.authors = ['NatyDev']
|
9
|
+
spec.email = ['natydev@aol.com']
|
10
|
+
|
11
|
+
spec.summary = 'Wrapper for FitBark API.'
|
12
|
+
spec.description = 'Wrapper for FitBark API: It provides simple methods to handle ' \
|
13
|
+
'authorization and to execute HTTP calls.'
|
14
|
+
spec.homepage = 'https://github.com/natydev/fitbark'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
# Specify which files should be added to the gem when it is released.
|
18
|
+
# The `git ls-files -z` loads the files in the RubyGem.
|
19
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
20
|
+
`git ls-files -z`.split("\x0")
|
21
|
+
.reject { |f| f.match(%r{^(test|spec|features)/}) }
|
22
|
+
end
|
23
|
+
spec.bindir = 'exe'
|
24
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
|
+
spec.require_paths = ['lib']
|
26
|
+
|
27
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
28
|
+
spec.add_development_dependency 'faker', '~> 1.9'
|
29
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
30
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
31
|
+
spec.add_development_dependency 'rubocop', '~> 0.63'
|
32
|
+
spec.add_development_dependency 'webmock', '~> 3.5'
|
33
|
+
spec.add_dependency 'addressable', '~> 2.6'
|
34
|
+
spec.add_dependency 'faraday', '~> 0.15'
|
35
|
+
spec.add_dependency 'oj', '~> 3.7'
|
36
|
+
spec.add_dependency 'strict_open_struct', '~> 0.0.2'
|
37
|
+
end
|
data/lib/fitbark.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'addressable'
|
2
|
+
require 'faraday'
|
3
|
+
require 'oj'
|
4
|
+
require 'base64'
|
5
|
+
require 'strict_open_struct'
|
6
|
+
|
7
|
+
require_relative 'fitbark/version'
|
8
|
+
require_relative 'fitbark/constants'
|
9
|
+
require_relative 'fitbark/errors'
|
10
|
+
require_relative 'fitbark/auth'
|
11
|
+
require_relative 'fitbark/client'
|
12
|
+
require_relative 'fitbark/data/shared'
|
13
|
+
require_relative 'fitbark/data/token'
|
14
|
+
require_relative 'fitbark/data/token_info'
|
15
|
+
require_relative 'fitbark/data/user_info'
|
16
|
+
require_relative 'fitbark/data/picture'
|
17
|
+
require_relative 'fitbark/data/breed'
|
18
|
+
require_relative 'fitbark/data/medical_condition'
|
19
|
+
require_relative 'fitbark/data/dog_info'
|
20
|
+
require_relative 'fitbark/data/user_relation'
|
21
|
+
require_relative 'fitbark/data/dog_relation'
|
22
|
+
require_relative 'fitbark/data/activity_daily'
|
23
|
+
require_relative 'fitbark/data/activity_hourly'
|
24
|
+
require_relative 'fitbark/data/similar_dogs_stat'
|
25
|
+
require_relative 'fitbark/data/activity_level'
|
26
|
+
require_relative 'fitbark/data/daily_goal'
|
27
|
+
require_relative 'fitbark/handler/v2/base'
|
28
|
+
require_relative 'fitbark/handler/v2/user_info'
|
29
|
+
require_relative 'fitbark/handler/v2/user_picture'
|
30
|
+
require_relative 'fitbark/handler/v2/dog_relations'
|
31
|
+
require_relative 'fitbark/handler/v2/dog_info'
|
32
|
+
require_relative 'fitbark/handler/v2/dog_picture'
|
33
|
+
require_relative 'fitbark/handler/v2/user_relations'
|
34
|
+
require_relative 'fitbark/handler/v2/activity_series'
|
35
|
+
require_relative 'fitbark/handler/v2/similar_dogs_stats'
|
36
|
+
require_relative 'fitbark/handler/v2/activity_total'
|
37
|
+
require_relative 'fitbark/handler/v2/time_breakdown'
|
38
|
+
require_relative 'fitbark/handler/v2/daily_goals'
|
39
|
+
require_relative 'fitbark/handler/v2/set_daily_goal'
|
40
|
+
require_relative 'fitbark/handler/v2/own_dogs'
|
41
|
+
require_relative 'fitbark/handler/v2/friend_dogs'
|
42
|
+
|
43
|
+
module Fitbark
|
44
|
+
# :nodoc:
|
45
|
+
end
|
data/lib/fitbark/auth.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
module Fitbark
|
2
|
+
# Provides oauth2 methods
|
3
|
+
class Auth
|
4
|
+
include Fitbark::Constants
|
5
|
+
# == A sample usage:
|
6
|
+
# First step to generate an authorization uri:
|
7
|
+
# client_id = 'CLIENT-ID-PROVIDED-BY-FITBARK'
|
8
|
+
# client_secret = 'CLIENT-SECRET-PROVIDED-BY-FITBARK'
|
9
|
+
# redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
|
10
|
+
# auth = Fitbark::Auth.new(client_id: client_id, redirect_uri: redirect_uri)
|
11
|
+
# auth.authorization_uri
|
12
|
+
#
|
13
|
+
# Once that authorization uri was open and fetched the authorization
|
14
|
+
# code from html (normally this operation is done with browser),
|
15
|
+
# proceed with 2nd step to retieve access token:
|
16
|
+
# authorization_code = '27e5dd1307cddc7b5d8d72264ef1...'
|
17
|
+
# auth = Fitbark::Auth.new(client_id: client_id, redirect_uri: redirect_uri,
|
18
|
+
# code: authorization_code, client_secret: client_secret)
|
19
|
+
# auth.fetch_access_token!
|
20
|
+
def initialize(client_id: nil, client_secret: nil,
|
21
|
+
redirect_uri: nil, code: nil, token: nil)
|
22
|
+
@client_id = client_id
|
23
|
+
@client_secret = client_secret
|
24
|
+
@redirect_uri = redirect_uri
|
25
|
+
@code = code
|
26
|
+
@token = read_token(token)
|
27
|
+
@uri = Addressable::URI.new(host: API_HOST, scheme: API_SCHEME)
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_accessor :code
|
31
|
+
attr_writer :token
|
32
|
+
attr_reader :client_id, :client_secret, :redirect_uri,
|
33
|
+
:token_data, :token_info
|
34
|
+
|
35
|
+
# return an URI to fetch the authorization code
|
36
|
+
def authorization_uri
|
37
|
+
uri.path = AUTHORIZE_PATH
|
38
|
+
uri.query_values = {
|
39
|
+
response_type: :code,
|
40
|
+
client_id: client_id,
|
41
|
+
redirect_uri: redirect_uri
|
42
|
+
}
|
43
|
+
uri.to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
# return a Fitbark::Data::Token object
|
47
|
+
def fetch_access_token!
|
48
|
+
if token_response.success?
|
49
|
+
apply_token_data(token_response)
|
50
|
+
else
|
51
|
+
token_error(token_response)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# return a Fitbark::Data::TokenInfo object
|
56
|
+
def fetch_token_info
|
57
|
+
response = token_info_response
|
58
|
+
if response.success?
|
59
|
+
apply_token_info(response)
|
60
|
+
else
|
61
|
+
token_error(response)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# return the raw access_token (String)
|
66
|
+
def token
|
67
|
+
read_token
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
attr_accessor :uri
|
73
|
+
|
74
|
+
def token_response
|
75
|
+
@token_response ||= Faraday.new(url: uri.site).post do |req|
|
76
|
+
req.url TOKEN_PATH
|
77
|
+
req.body = request_token_body
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def request_token_body
|
82
|
+
{
|
83
|
+
client_id: client_id,
|
84
|
+
client_secret: client_secret,
|
85
|
+
grant_type: :authorization_code,
|
86
|
+
redirect_uri: redirect_uri,
|
87
|
+
code: code
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
def token_info_response
|
92
|
+
raise Fitbark::Errors::TokenNotProvidedError if token.nil?
|
93
|
+
|
94
|
+
Faraday.new(url: uri.site).get do |req|
|
95
|
+
req.url TOKEN_INFO_PATH
|
96
|
+
req.headers = {
|
97
|
+
'Content-Type' => 'application/json',
|
98
|
+
'Authorization' => "Bearer #{token}"
|
99
|
+
}
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def apply_token_data(resp)
|
104
|
+
@token_data = Fitbark::Data::Token.new(parsed_body(resp))
|
105
|
+
end
|
106
|
+
|
107
|
+
def apply_token_info(resp)
|
108
|
+
@token_info = Fitbark::Data::TokenInfo.new(parsed_body(resp))
|
109
|
+
end
|
110
|
+
|
111
|
+
def token_error(resp)
|
112
|
+
raise(Fitbark::Errors::FetchTokenError
|
113
|
+
.new(code: resp.status, message:
|
114
|
+
parsed_body(resp)['error_description']))
|
115
|
+
end
|
116
|
+
|
117
|
+
def read_token(val = @token)
|
118
|
+
(token_data.respond_to?(:token) && token_data.token) || val
|
119
|
+
end
|
120
|
+
|
121
|
+
def parsed_body(resp)
|
122
|
+
Oj.load(resp.body)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Fitbark
|
2
|
+
# Provides all methods to connect to the API
|
3
|
+
# endpoints and retrieve data
|
4
|
+
class Client
|
5
|
+
include Fitbark::Constants
|
6
|
+
|
7
|
+
# === params (key/value):
|
8
|
+
#
|
9
|
+
# - *token*: access token retrieved from Fitbark::Auth
|
10
|
+
#
|
11
|
+
# alla available API methods inside
|
12
|
+
# this calss are dynamical defined by all Fitbark::Handler::V2 classes
|
13
|
+
# please read specific documentation for each of them
|
14
|
+
# == Sample usage:
|
15
|
+
#
|
16
|
+
# token = "9083a4b0d701542c9b..."
|
17
|
+
# client = Fitbark::Client.new(token: token)
|
18
|
+
# user = client.user_info
|
19
|
+
# first_dog = client.dog_relations.first.dog
|
20
|
+
# client.dog_picture(dog_slug: first_dog.slug)
|
21
|
+
|
22
|
+
def initialize(token:)
|
23
|
+
raise Fitbark::Errors::TokenNotProvidedError if token.nil?
|
24
|
+
|
25
|
+
@token = token
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :uri
|
29
|
+
|
30
|
+
# :nodoc:
|
31
|
+
def method_missing(method, **args)
|
32
|
+
if respond_to?(method)
|
33
|
+
klass_handler(method).new(token: token, opts: args).response
|
34
|
+
else
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# :nodoc:
|
40
|
+
def respond_to?(method, include_private = false)
|
41
|
+
return true if klass_handler(method)
|
42
|
+
rescue NameError => e
|
43
|
+
super
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def klass_handler(handler)
|
49
|
+
eval("#{PREFIX_NAME_HANDLER}#{camel(handler.to_s)}")
|
50
|
+
end
|
51
|
+
|
52
|
+
attr_reader :token
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Fitbark
|
2
|
+
# Provides general constants support.
|
3
|
+
module Constants
|
4
|
+
API_SCHEME = 'https'.freeze
|
5
|
+
API_HOST = 'app.fitbark.com'.freeze
|
6
|
+
API_SUBHOST = 'api/v2'.freeze
|
7
|
+
AUTHORIZE_PATH = '/oauth/authorize'.freeze
|
8
|
+
TOKEN_PATH = '/oauth/token'.freeze
|
9
|
+
TOKEN_INFO_PATH = TOKEN_PATH + '/info'.freeze
|
10
|
+
PREFIX_NAME_HANDLER = 'Fitbark::Handler::V2::'.freeze
|
11
|
+
|
12
|
+
# :nodoc:
|
13
|
+
def camel(str)
|
14
|
+
str.split('_').collect(&:capitalize).join
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Fitbark
|
2
|
+
module Data
|
3
|
+
# Defines structure for dog's daily activity data.
|
4
|
+
#
|
5
|
+
# Original attribute names from source API:
|
6
|
+
# - *date*
|
7
|
+
# - *activity_value*
|
8
|
+
# - *activity_average*,
|
9
|
+
# - *min_play*,
|
10
|
+
# - *min_active*
|
11
|
+
# - *min_rest*
|
12
|
+
# - *daily_target*
|
13
|
+
# - *has_trophy*
|
14
|
+
class ActivityDaily < StrictOpenStruct
|
15
|
+
include Fitbark::Data::Shared
|
16
|
+
|
17
|
+
# parse source String value into Date for *date* attribute
|
18
|
+
def date
|
19
|
+
date_parser(self[:date])
|
20
|
+
end
|
21
|
+
|
22
|
+
alias detected_on date
|
23
|
+
|
24
|
+
# an alias for *min_play* attribute
|
25
|
+
def minutes_playing
|
26
|
+
self[:min_play]
|
27
|
+
end
|
28
|
+
|
29
|
+
# an alias for *min_active* attribute
|
30
|
+
def minutes_active
|
31
|
+
self[:min_active]
|
32
|
+
end
|
33
|
+
|
34
|
+
# an alias for *min_rest* attribute
|
35
|
+
def minutes_resting
|
36
|
+
self[:min_rest]
|
37
|
+
end
|
38
|
+
|
39
|
+
# an alias for *daily_target* attribute
|
40
|
+
def daily_goal
|
41
|
+
self[:daily_target]
|
42
|
+
end
|
43
|
+
|
44
|
+
# a predicate alias for *has_trophy* attribute
|
45
|
+
def trophy?
|
46
|
+
!self[:has_trophy].zero?
|
47
|
+
end
|
48
|
+
|
49
|
+
alias daily_goal_reached? trophy?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Fitbark
|
2
|
+
module Data
|
3
|
+
# Defines structure for dog's hourly activity data.
|
4
|
+
#
|
5
|
+
# Original attribute names from source API:
|
6
|
+
# - *date*
|
7
|
+
# - *activity_value*
|
8
|
+
# - *min_play*,
|
9
|
+
# - *min_active*
|
10
|
+
# - *min_rest*
|
11
|
+
# - *distance_in_miles*
|
12
|
+
# - *kcalories*
|
13
|
+
# - *activity_goal*
|
14
|
+
class ActivityHourly < StrictOpenStruct
|
15
|
+
include Fitbark::Data::Shared
|
16
|
+
|
17
|
+
# parse String value into Time for *date* attribute
|
18
|
+
def date
|
19
|
+
time_parser(self[:date])
|
20
|
+
end
|
21
|
+
|
22
|
+
alias detected_at date
|
23
|
+
|
24
|
+
# an alias for *min_play* attribute
|
25
|
+
def minutes_playing
|
26
|
+
self[:min_play]
|
27
|
+
end
|
28
|
+
|
29
|
+
# an alias for *min_active* attribute
|
30
|
+
def minutes_active
|
31
|
+
self[:min_active]
|
32
|
+
end
|
33
|
+
|
34
|
+
# an alias for *min_rest* attribute
|
35
|
+
def minutes_resting
|
36
|
+
self[:min_rest]
|
37
|
+
end
|
38
|
+
|
39
|
+
# convert in kilometers from *distance_in_miles* attribute
|
40
|
+
def distance_in_kms
|
41
|
+
(self[:distance_in_miles].to_f * 1.60934).round(3)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Fitbark
|
2
|
+
module Data
|
3
|
+
# Defines structure for dog's activity data.
|
4
|
+
#
|
5
|
+
# Original attribute names from source API:
|
6
|
+
# - *min_play*,
|
7
|
+
# - *min_active*
|
8
|
+
# - *min_rest*
|
9
|
+
class ActivityLevel < StrictOpenStruct
|
10
|
+
include Fitbark::Data::Shared
|
11
|
+
|
12
|
+
# an alias for *min_play* attribute
|
13
|
+
def minutes_playing
|
14
|
+
self[:min_play]
|
15
|
+
end
|
16
|
+
|
17
|
+
# an alias for *min_active* attribute
|
18
|
+
def minutes_active
|
19
|
+
self[:min_active]
|
20
|
+
end
|
21
|
+
|
22
|
+
# an alias for *min_rest* attribute
|
23
|
+
def minutes_resting
|
24
|
+
self[:min_rest]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Fitbark
|
2
|
+
module Data
|
3
|
+
# Defines structure for dog's daily points goal.
|
4
|
+
#
|
5
|
+
# Original attribute names from source API:
|
6
|
+
# - *goal*,
|
7
|
+
# - *date*
|
8
|
+
class DailyGoal < StrictOpenStruct
|
9
|
+
include Fitbark::Data::Shared
|
10
|
+
|
11
|
+
# parse String value into Date for *date* attribute
|
12
|
+
def date
|
13
|
+
date_parser(self[:date])
|
14
|
+
end
|
15
|
+
|
16
|
+
alias set_on date
|
17
|
+
|
18
|
+
# an alias for *goal* attribute
|
19
|
+
def goal_points
|
20
|
+
self[:goal]
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|