fitbark 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +6 -0
  5. data/.travis.yml +7 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +4 -0
  8. data/Gemfile.lock +80 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +194 -0
  11. data/Rakefile +6 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/fitbark.gemspec +37 -0
  15. data/lib/fitbark.rb +45 -0
  16. data/lib/fitbark/auth.rb +125 -0
  17. data/lib/fitbark/client.rb +54 -0
  18. data/lib/fitbark/constants.rb +17 -0
  19. data/lib/fitbark/data/activity_daily.rb +52 -0
  20. data/lib/fitbark/data/activity_hourly.rb +46 -0
  21. data/lib/fitbark/data/activity_level.rb +28 -0
  22. data/lib/fitbark/data/breed.rb +12 -0
  23. data/lib/fitbark/data/daily_goal.rb +25 -0
  24. data/lib/fitbark/data/dog_info.rb +118 -0
  25. data/lib/fitbark/data/dog_relation.rb +27 -0
  26. data/lib/fitbark/data/medical_condition.rb +12 -0
  27. data/lib/fitbark/data/picture.rb +21 -0
  28. data/lib/fitbark/data/shared.rb +36 -0
  29. data/lib/fitbark/data/similar_dogs_stat.rb +22 -0
  30. data/lib/fitbark/data/token.rb +35 -0
  31. data/lib/fitbark/data/token_info.rb +29 -0
  32. data/lib/fitbark/data/user_info.rb +27 -0
  33. data/lib/fitbark/data/user_preview.rb +25 -0
  34. data/lib/fitbark/data/user_relation.rb +26 -0
  35. data/lib/fitbark/errors.rb +33 -0
  36. data/lib/fitbark/handler/v2/activity_series.rb +90 -0
  37. data/lib/fitbark/handler/v2/activity_total.rb +65 -0
  38. data/lib/fitbark/handler/v2/base.rb +54 -0
  39. data/lib/fitbark/handler/v2/daily_goals.rb +37 -0
  40. data/lib/fitbark/handler/v2/dog_info.rb +39 -0
  41. data/lib/fitbark/handler/v2/dog_picture.rb +39 -0
  42. data/lib/fitbark/handler/v2/dog_relations.rb +37 -0
  43. data/lib/fitbark/handler/v2/friend_dogs.rb +39 -0
  44. data/lib/fitbark/handler/v2/own_dogs.rb +38 -0
  45. data/lib/fitbark/handler/v2/set_daily_goal.rb +68 -0
  46. data/lib/fitbark/handler/v2/similar_dogs_stats.rb +37 -0
  47. data/lib/fitbark/handler/v2/time_breakdown.rb +63 -0
  48. data/lib/fitbark/handler/v2/user_info.rb +35 -0
  49. data/lib/fitbark/handler/v2/user_picture.rb +39 -0
  50. data/lib/fitbark/handler/v2/user_relations.rb +37 -0
  51. data/lib/fitbark/version.rb +4 -0
  52. metadata +234 -0
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
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
@@ -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,12 @@
1
+ module Fitbark
2
+ module Data
3
+ # Defines structure for dog's breed data.
4
+ #
5
+ # Original attribute names from source API:
6
+ # - *id*,
7
+ # - *name*
8
+ class Breed < StrictOpenStruct
9
+ include Fitbark::Data::Shared
10
+ end
11
+ end
12
+ 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