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.
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
@@ -0,0 +1,118 @@
1
+ module Fitbark
2
+ module Data
3
+ # Defines structure for dog's informations.
4
+ #
5
+ # Original attribute names from source API:
6
+ # - *slug*
7
+ # - *name*
8
+ # - *bluetooth_id*
9
+ # - *activity_value*
10
+ # - *birth*
11
+ # - *breed1*
12
+ # - *breed2*
13
+ # - *gender*
14
+ # - *weight*
15
+ # - *weight_unit*
16
+ # - *country*
17
+ # - *zip*
18
+ # - *tzoffset*
19
+ # - *tzname*
20
+ # - *min_play*
21
+ # - *min_active*
22
+ # - *min_rest*
23
+ # - *medical_conditions*
24
+ # - *hourly_average*
25
+ # - *picture_hash*
26
+ # - *neutered*
27
+ # - *last_min_time*
28
+ # - *last_min_activity*
29
+ # - *daily_goal*
30
+ # - *battery_level*
31
+ # - *last_sync*
32
+ class DogInfo < StrictOpenStruct
33
+ include Fitbark::Data::Shared
34
+
35
+ # parse source String value into Date for *birth* attribute
36
+ def birth
37
+ date_parser(self[:birth])
38
+ end
39
+
40
+ alias birth_on birth
41
+
42
+ # an alias for source *gender* attribute
43
+ def sex
44
+ self[:gender]
45
+ end
46
+
47
+ # an alias for *zip* attribute
48
+ def postal_code
49
+ self[:zip]
50
+ end
51
+
52
+ # an alias for *zip* attribute
53
+ def zip_code
54
+ self[:zip]
55
+ end
56
+
57
+ # an alias for *min_play* attribute
58
+ def today_minutes_playing
59
+ self[:min_play]
60
+ end
61
+
62
+ # an alias for *min_active* attribute
63
+ def today_minutes_active
64
+ self[:min_active]
65
+ end
66
+
67
+ # an alias for *min_rest* attribute
68
+ def today_minutes_resting
69
+ self[:min_rest]
70
+ end
71
+
72
+ # parse String value into Time for *last_min_time* attribute
73
+ def last_min_time
74
+ time_parser(self[:last_min_time])
75
+ end
76
+
77
+ alias last_minute_at last_min_time
78
+
79
+ # parse String value into Time for *last_min_activity* attribute
80
+ def last_minute_activity
81
+ self[:last_min_activity]
82
+ end
83
+
84
+ # an alias for *activity_value* attribute
85
+ def today_activity_points
86
+ self[:activity_value]
87
+ end
88
+
89
+ # parse String value into Time for *last_sync* attribute
90
+ def last_sync
91
+ time_parser(self[:last_sync])
92
+ end
93
+
94
+ alias sync_at last_sync
95
+
96
+ # first breed according to Fitbark::Data::Breed
97
+ def breed1
98
+ init_breed(self[:breed1])
99
+ end
100
+
101
+ alias first_breed breed1
102
+
103
+ # second breed according to Fitbark::Data::Breed
104
+ def breed2
105
+ init_breed(self[:breed2])
106
+ end
107
+
108
+ alias second_breed breed2
109
+
110
+ # an array of Fitbark::Data::MedicalCondition objects
111
+ def medical_conditions
112
+ self[:medical_conditions].map do |mc|
113
+ init_medical_condition(mc)
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,27 @@
1
+ module Fitbark
2
+ module Data
3
+ # Defines structure for dog relation between user.
4
+ #
5
+ # Original attribute names from source API:
6
+ # - *id*
7
+ # - *date*
8
+ # - *dog_slug*
9
+ # - *status*
10
+ # - *user*
11
+ class DogRelation < StrictOpenStruct
12
+ include Fitbark::Data::Shared
13
+
14
+ # user as object kind Fitbark::Data::UserPreview
15
+ def user
16
+ Fitbark::Data::UserPreview.new(self[:user])
17
+ end
18
+
19
+ # parse source String value into Date for *date* attribute
20
+ def date
21
+ date_parser(self[:date])
22
+ end
23
+
24
+ alias related_on date
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,12 @@
1
+ module Fitbark
2
+ module Data
3
+ # Defines structure for dog medical condition.
4
+ #
5
+ # Original attribute names from source API:
6
+ # - *id*
7
+ # - *name*
8
+ class MedicalCondition < StrictOpenStruct
9
+ include Fitbark::Data::Shared
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ module Fitbark
2
+ module Data
3
+ # Defines structure for picture data.
4
+ #
5
+ # Original attribute names from source API:
6
+ # - *data*
7
+ class Picture < StrictOpenStruct
8
+ include Fitbark::Data::Shared
9
+
10
+ # an alias for *data* attribute
11
+ def base64
12
+ self[:data]
13
+ end
14
+
15
+ # decode data from base64
16
+ def bytes
17
+ Base64.decode64(data)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,36 @@
1
+ module Fitbark
2
+ module Data
3
+ # Provides general behaviour for data classes.
4
+ module Shared
5
+ # :nodoc:
6
+ def self.included(base)
7
+ base.send :extend, ClassMethods
8
+ end
9
+
10
+ module ClassMethods
11
+ end
12
+
13
+ private
14
+
15
+ def time_parser(attr)
16
+ Time.parse(attr.to_s)
17
+ rescue ArgumentError
18
+ nil
19
+ end
20
+
21
+ def date_parser(attr)
22
+ Date.parse(attr.to_s)
23
+ rescue ArgumentError
24
+ nil
25
+ end
26
+
27
+ def init_breed(attr)
28
+ Fitbark::Data::Breed.new(attr)
29
+ end
30
+
31
+ def init_medical_condition(attr)
32
+ Fitbark::Data::MedicalCondition.new(attr)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,22 @@
1
+ module Fitbark
2
+ module Data
3
+ # Defines structure for similar dogs stats.
4
+ #
5
+ # Original attribute names from source API:
6
+
7
+ # - *this_best_daily_activity*
8
+ # - *this_best_week_activity*
9
+ # - *this_current_goals_streak*
10
+ # - *this_best_goals_streak*
11
+ # - *this_average_daily_activity*
12
+ # - *median_same_age_weight_daily_activity*
13
+ # - *this_average_daily_rest_minutes*
14
+ # - *median_same_age_weight_range_dogs_daily_rest_minutes*
15
+ # - *median_all_dogs_daily_activity*
16
+ # - *median_same_breed_daily_activity*
17
+ class SimilarDogsStat < StrictOpenStruct
18
+ include Fitbark::Data::Shared
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,35 @@
1
+ module Fitbark
2
+ module Data
3
+ # Defines structure for access token.
4
+ #
5
+ # Original attribute names from source API:
6
+
7
+ # - *access_token*
8
+ # - *token_type*
9
+ # - *expires_in*
10
+ # - *scope*
11
+ class Token < StrictOpenStruct
12
+ include Fitbark::Data::Shared
13
+
14
+ # an alias for *access_token* source attribute
15
+ def token
16
+ self[:access_token]
17
+ end
18
+
19
+ # an alias for *token_type* source attribute
20
+ def type
21
+ self[:token_type]
22
+ end
23
+
24
+ # return Time of expiring based on *expires_in* source attribute
25
+ def expires_at
26
+ Time.now.utc + self[:expires_in].to_i
27
+ end
28
+
29
+ # return token's scopes as Array
30
+ def scopes
31
+ Array(self[:scope])
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,29 @@
1
+ module Fitbark
2
+ module Data
3
+ # Defines structure for access token informations.
4
+ #
5
+ # Original attribute names from source API:
6
+
7
+ # - *resource_owner_id*
8
+ # - *scopes*
9
+ # - *expires_in_seconds*
10
+ # - *application*
11
+ class TokenInfo < StrictOpenStruct
12
+ include Fitbark::Data::Shared
13
+
14
+ # Defines structure for Application data inside TokenInfo
15
+ class Application < StrictOpenStruct
16
+ include Fitbark::Data::Shared
17
+ end
18
+
19
+ # return Time of expiring based on *expires_in_seconds* source attribute
20
+ def expires_at
21
+ Time.now.utc + self[:expires_in_seconds].to_i
22
+ end
23
+ # application as object kind Fitbark::Data::TokenInfo::Application
24
+ def application
25
+ Application.new self[:application]
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ module Fitbark
2
+ module Data
3
+ # Defines structure for user's informations.
4
+ #
5
+ # Original attribute names from source API:
6
+ # - *slug*
7
+ # - *slug*
8
+ # - *username*
9
+ # - *name*
10
+ # - *first_name*
11
+ # - *last_name*
12
+ # - *picture_hash*
13
+ class UserInfo < StrictOpenStruct
14
+ include Fitbark::Data::Shared
15
+
16
+ # an alias for source *username* attribute
17
+ def email
18
+ self[:username]
19
+ end
20
+
21
+ # an alias for source *name* attribute
22
+ def fullname
23
+ self[:name]
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ module Fitbark
2
+ module Data
3
+ # Defines structure for dog relation between user.
4
+ #
5
+ # Original attribute names from source API:
6
+ # - *slug*
7
+ # - *username*
8
+ # - *name*
9
+ # - *first_name*
10
+ # - *last_name*
11
+ class UserPreview < StrictOpenStruct
12
+ include Fitbark::Data::Shared
13
+
14
+ # an alias for source *username* attribute
15
+ def email
16
+ self[:username]
17
+ end
18
+
19
+ # an alias for source *name* attribute
20
+ def fullname
21
+ self[:name]
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,26 @@
1
+ module Fitbark
2
+ module Data
3
+ # Defines structure for user relation between a dog.
4
+ #
5
+ # Original attribute names from source API:
6
+ # - *id*
7
+ # - *date*
8
+ # - *status*
9
+ # - *dog*
10
+ class UserRelation < StrictOpenStruct
11
+ include Fitbark::Data::Shared
12
+
13
+ # dog as object kind Fitbark::Data::DogInfo
14
+ def dog
15
+ Fitbark::Data::DogInfo.new(self[:dog])
16
+ end
17
+
18
+ # parse source String value into Date for *date* attribute
19
+ def date
20
+ date_parser(self[:date])
21
+ end
22
+
23
+ alias related_on date
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,33 @@
1
+ module Fitbark
2
+ # Provides namespace for error classes.
3
+ module Errors
4
+ # provide base behaviour for all errors classes.
5
+ class BaseError < StandardError
6
+ def initialize(message: nil, code: 400)
7
+ @message = message
8
+ @code = code
9
+ end
10
+
11
+ attr_accessor :message, :code
12
+
13
+ def to_s
14
+ "#{code} - #{message}"
15
+ end
16
+ end
17
+
18
+ # FetchTokenError
19
+ class FetchTokenError < BaseError; end
20
+ # TokenNotProvidedError
21
+ class TokenNotProvidedError < BaseError
22
+ def initialize
23
+ @message = 'Token is required for this operation'
24
+ end
25
+ end
26
+ # ConnectionError
27
+ class ConnectionError < BaseError; end
28
+ # DataError
29
+ class DataError < BaseError; end
30
+ # FormatError
31
+ class FormatError < BaseError; end
32
+ end
33
+ end
@@ -0,0 +1,90 @@
1
+ module Fitbark
2
+ module Handler
3
+ module V2
4
+ # = \#activity_series
5
+ # Fitbark::Handler::V2::ActivitySeries define method *activity_series*
6
+ # inside Client object
7
+ #
8
+ # === params (key/value):
9
+ #
10
+ # - *dog_slug*: slug ID relative to dog (String)
11
+ # - *from*: data start date (Date)
12
+ # - *to*: data end date (Date)
13
+ # - *resolution*: can be +:daily+ or +:hourly+ (Symbol)
14
+ #
15
+ # example usage:
16
+ # client = Client.new(token: 'a5b3f8...')
17
+ # client.activity_series(dog_slug: 'v4s1...', from: 3.days.ago, to: Date.today, resolution: :daily)
18
+ #
19
+ # === response:
20
+ # when resolution is +:daily+:: An array of
21
+ # Fitbark::Data::ActivityDaily objects.
22
+ # when resolution is +:hourly+:: An array of
23
+ # Fitbark::Data::ActivityHourly objects.
24
+ class ActivitySeries
25
+ include Fitbark::Handler::V2::Base
26
+
27
+ # :nodoc:
28
+ RESOLUTIONS = %i[daily hourly].freeze
29
+
30
+ def initialize(token:, opts: {})
31
+ super
32
+ @resolution = opts.fetch(:resolution, '').to_s.downcase.to_sym
33
+ validate_input
34
+ end
35
+
36
+ attr_reader :resolution
37
+
38
+ # https://app.fitbark.com/api/v2/activity_series
39
+ def response
40
+ json_response.dig('activity_series', 'records').map do |as|
41
+ data_class.new(as)
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def raw_response
48
+ connection(verb: :post, fragment: 'activity_series',
49
+ params: build_params(opts[:dog_slug], opts[:from],
50
+ opts[:to], resolution)).body
51
+ end
52
+
53
+ def build_params(slug, from, to, res)
54
+ {
55
+ "activity_series": {
56
+ "slug": slug,
57
+ "from": from,
58
+ "to": to,
59
+ "resolution": format_resolution(res)
60
+ }
61
+ }
62
+ end
63
+
64
+ def format_resolution(val)
65
+ val.to_s.upcase
66
+ end
67
+
68
+ def validate_input
69
+ unless RESOLUTIONS.include? resolution
70
+ raise(Fitbark::Errors::FormatError
71
+ .new(message: "Wrong or missing param 'resolution', must be kind of:
72
+ #{Fitbark::Handler::V2::ActivitySeries::RESOLUTIONS.join(', ')}"))
73
+ end
74
+ unless opts[:from].instance_of?(Date)
75
+ raise Fitbark::Errors::FormatError
76
+ .new(message: "Wrong or missing date for param 'from'")
77
+ end
78
+ unless opts[:to].instance_of?(Date)
79
+ raise Fitbark::Errors::FormatError
80
+ .new(message: "Wrong or missing date for param 'to'")
81
+ end
82
+ end
83
+
84
+ def data_class
85
+ eval("Fitbark::Data::Activity#{camel(resolution.to_s)}")
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end