jirafe 0.1.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.
Files changed (148) hide show
  1. data/.autotest +5 -0
  2. data/.gitignore +23 -0
  3. data/.rbenv-version +1 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +11 -0
  6. data/Gemfile +8 -0
  7. data/LICENSE +13 -0
  8. data/README.md +104 -0
  9. data/Rakefile +27 -0
  10. data/fixtures/responses/application_get_with_cloud_token.yml +40 -0
  11. data/fixtures/responses/application_get_with_invalid_token.yml +41 -0
  12. data/fixtures/responses/application_get_with_master_token.yml +784 -0
  13. data/fixtures/responses/application_get_with_reporting_token.yml +38 -0
  14. data/fixtures/responses/application_post_with_app_token.yml +38 -0
  15. data/fixtures/responses/application_post_with_cloud_token.yml +76 -0
  16. data/fixtures/responses/application_post_with_invalid_token.yml +79 -0
  17. data/fixtures/responses/application_post_with_master_token.yml +784 -0
  18. data/fixtures/responses/application_post_with_master_token_blank_name.yml +79 -0
  19. data/fixtures/responses/application_post_with_master_token_dupe_name.yml +76 -0
  20. data/fixtures/responses/application_post_with_master_token_no_name.yml +79 -0
  21. data/fixtures/responses/application_post_with_reporting_token.yml +76 -0
  22. data/fixtures/responses/application_put_with_cloud_token.yml +68 -0
  23. data/fixtures/responses/application_put_with_invalid_token.yml +145 -0
  24. data/fixtures/responses/application_put_with_master_token.yml +68 -0
  25. data/fixtures/responses/application_put_with_reporting_token.yml +68 -0
  26. data/fixtures/responses/application_sites_get_with_master_token.yml +38 -0
  27. data/fixtures/responses/callback_event_post_event.yml +2000 -0
  28. data/fixtures/responses/callback_event_post_event_fetch_token.yml +1473 -0
  29. data/fixtures/responses/jirafe_resource_get_status_url.yml +38 -0
  30. data/fixtures/responses/jirafe_resource_get_status_url_with_query_param.yml +38 -0
  31. data/fixtures/responses/site_abandon_rate_get_with_master_token.yml +49 -0
  32. data/fixtures/responses/site_abandoned_average_ordervalue_get_with_master_token.yml +49 -0
  33. data/fixtures/responses/site_abandoned_carts_get_with_master_token.yml +49 -0
  34. data/fixtures/responses/site_abandoned_revenue_get_with_master_token.yml +49 -0
  35. data/fixtures/responses/site_average_order_value_get_with_master_token.yml +49 -0
  36. data/fixtures/responses/site_bounces_rate_get_with_master_token.yml +49 -0
  37. data/fixtures/responses/site_cart_segmentation_get_with_master_token.yml +38 -0
  38. data/fixtures/responses/site_conversion_rate_get_with_master_token.yml +49 -0
  39. data/fixtures/responses/site_conversions_get_with_master_token.yml +49 -0
  40. data/fixtures/responses/site_customers_get_with_master_token.yml +49 -0
  41. data/fixtures/responses/site_dashboard_get_with_master_token.yml +60 -0
  42. data/fixtures/responses/site_get_with_master_token.yml +73 -0
  43. data/fixtures/responses/site_keywords_get_with_master_token.yml +38 -0
  44. data/fixtures/responses/site_orders_status_get_with_master_token.yml +38 -0
  45. data/fixtures/responses/site_origins_get_with_master_token.yml +38 -0
  46. data/fixtures/responses/site_period_data_get_with_master_token.yml +38 -0
  47. data/fixtures/responses/site_post_with_app_token.yml +727 -0
  48. data/fixtures/responses/site_post_with_master_token.yml +1569 -0
  49. data/fixtures/responses/site_products_get_with_master_token.yml +38 -0
  50. data/fixtures/responses/site_referers_get_with_master_token.yml +38 -0
  51. data/fixtures/responses/site_revenues_average_get_with_master_token.yml +49 -0
  52. data/fixtures/responses/site_revenues_get_with_master_token.yml +49 -0
  53. data/fixtures/responses/site_segments_carts_get_with_admin_token.yml +108 -0
  54. data/fixtures/responses/site_segments_sales_get_with_admin_token.yml +143 -0
  55. data/fixtures/responses/site_total_carts_get_with_master_token.yml +49 -0
  56. data/fixtures/responses/site_translations__get_with_master_token.yml +155 -0
  57. data/fixtures/responses/site_translations_de_get_with_master_token.yml +156 -0
  58. data/fixtures/responses/site_translations_es_get_with_master_token.yml +155 -0
  59. data/fixtures/responses/site_translations_fr_get_with_master_token.yml +178 -0
  60. data/fixtures/responses/site_translations_german_get_with_master_token.yml +156 -0
  61. data/fixtures/responses/site_translations_get_with_master_token.yml +865 -0
  62. data/fixtures/responses/site_translations_xx_get_with_master_token.yml +155 -0
  63. data/fixtures/responses/site_visits_get_with_master_token.yml +49 -0
  64. data/fixtures/responses/status_get.yml +38 -0
  65. data/fixtures/responses/status_get_500.yml +31 -0
  66. data/fixtures/responses/test.yml +7364 -0
  67. data/fixtures/responses/version_get.yml +38 -0
  68. data/jirafe.gemspec +29 -0
  69. data/lib/jirafe.rb +64 -0
  70. data/lib/jirafe/callback/event.rb +57 -0
  71. data/lib/jirafe/callback/events/order.rb +48 -0
  72. data/lib/jirafe/callback/events/refund.rb +32 -0
  73. data/lib/jirafe/callback/jirafe_callback.rb +50 -0
  74. data/lib/jirafe/configuration.rb +47 -0
  75. data/lib/jirafe/error.rb +57 -0
  76. data/lib/jirafe/resource/application.rb +18 -0
  77. data/lib/jirafe/resource/jirafe_resource.rb +188 -0
  78. data/lib/jirafe/resource/site.rb +21 -0
  79. data/lib/jirafe/resource/sites/abandon_rate.rb +16 -0
  80. data/lib/jirafe/resource/sites/abandoned_average_order_value.rb +17 -0
  81. data/lib/jirafe/resource/sites/abandoned_carts.rb +16 -0
  82. data/lib/jirafe/resource/sites/abandoned_revenue.rb +16 -0
  83. data/lib/jirafe/resource/sites/average_order_value.rb +16 -0
  84. data/lib/jirafe/resource/sites/bounces_rate.rb +16 -0
  85. data/lib/jirafe/resource/sites/cart_segmentation.rb +11 -0
  86. data/lib/jirafe/resource/sites/conversion_rate.rb +16 -0
  87. data/lib/jirafe/resource/sites/conversions.rb +17 -0
  88. data/lib/jirafe/resource/sites/customers.rb +16 -0
  89. data/lib/jirafe/resource/sites/dashboard.rb +27 -0
  90. data/lib/jirafe/resource/sites/keywords.rb +11 -0
  91. data/lib/jirafe/resource/sites/orders_status.rb +15 -0
  92. data/lib/jirafe/resource/sites/origins.rb +11 -0
  93. data/lib/jirafe/resource/sites/period_data.rb +16 -0
  94. data/lib/jirafe/resource/sites/products.rb +12 -0
  95. data/lib/jirafe/resource/sites/referers.rb +12 -0
  96. data/lib/jirafe/resource/sites/revenues.rb +16 -0
  97. data/lib/jirafe/resource/sites/revenues_average.rb +16 -0
  98. data/lib/jirafe/resource/sites/segments_carts.rb +14 -0
  99. data/lib/jirafe/resource/sites/segments_sales.rb +14 -0
  100. data/lib/jirafe/resource/sites/total_carts.rb +16 -0
  101. data/lib/jirafe/resource/sites/translations.rb +18 -0
  102. data/lib/jirafe/resource/sites/visitors_interest.rb +14 -0
  103. data/lib/jirafe/resource/sites/visits.rb +16 -0
  104. data/lib/jirafe/resource/status.rb +19 -0
  105. data/lib/jirafe/resource/sync_service.rb +1 -0
  106. data/lib/jirafe/resource/time_series.rb +29 -0
  107. data/lib/jirafe/resource/user.rb +32 -0
  108. data/lib/jirafe/resource/version.rb +9 -0
  109. data/spec/jirafe/callback/event_spec.rb +85 -0
  110. data/spec/jirafe/configuration_spec.rb +150 -0
  111. data/spec/jirafe/jirafe_spec.rb +23 -0
  112. data/spec/jirafe/resource/application_spec.rb +220 -0
  113. data/spec/jirafe/resource/jirafe_resource_spec.rb +188 -0
  114. data/spec/jirafe/resource/site_spec.rb +61 -0
  115. data/spec/jirafe/resource/sites/abandon_rate_spec.rb +11 -0
  116. data/spec/jirafe/resource/sites/abandoned_average_order_value_spec.rb +11 -0
  117. data/spec/jirafe/resource/sites/abandoned_carts_spec.rb +11 -0
  118. data/spec/jirafe/resource/sites/abandoned_revenue_spec.rb +11 -0
  119. data/spec/jirafe/resource/sites/average_order_value_spec.rb +11 -0
  120. data/spec/jirafe/resource/sites/bounces_rate_spec.rb +11 -0
  121. data/spec/jirafe/resource/sites/cart_segmentation_spec.rb +11 -0
  122. data/spec/jirafe/resource/sites/conversion_rate_spec.rb +11 -0
  123. data/spec/jirafe/resource/sites/conversions_spec.rb +11 -0
  124. data/spec/jirafe/resource/sites/customers_spec.rb +11 -0
  125. data/spec/jirafe/resource/sites/dashboard_spec.rb +29 -0
  126. data/spec/jirafe/resource/sites/keywords_spec.rb +11 -0
  127. data/spec/jirafe/resource/sites/orders_status_spec.rb +34 -0
  128. data/spec/jirafe/resource/sites/origins_spec.rb +11 -0
  129. data/spec/jirafe/resource/sites/period_data_spec.rb +22 -0
  130. data/spec/jirafe/resource/sites/products_spec.rb +11 -0
  131. data/spec/jirafe/resource/sites/referers_spec.rb +11 -0
  132. data/spec/jirafe/resource/sites/revenues_average_spec.rb +11 -0
  133. data/spec/jirafe/resource/sites/revenues_spec.rb +11 -0
  134. data/spec/jirafe/resource/sites/segments_carts_spec.rb +29 -0
  135. data/spec/jirafe/resource/sites/segments_sales_spec.rb +29 -0
  136. data/spec/jirafe/resource/sites/total_carts_spec.rb +11 -0
  137. data/spec/jirafe/resource/sites/translations_spec.rb +76 -0
  138. data/spec/jirafe/resource/sites/visitors_interest_spec.rb +8 -0
  139. data/spec/jirafe/resource/sites/visits_spec.rb +11 -0
  140. data/spec/jirafe/resource/status_spec.rb +31 -0
  141. data/spec/jirafe/resource/version_spec.rb +15 -0
  142. data/spec/spec_helper.rb +58 -0
  143. data/spec/support/callback_server.rb +11 -0
  144. data/spec/support/response_helper.rb +31 -0
  145. data/spec/support/shared_examples/empty_resource.rb +17 -0
  146. data/spec/support/shared_examples/time_series.rb +31 -0
  147. data/spec/test_configuration.rb +15 -0
  148. metadata +360 -0
@@ -0,0 +1,188 @@
1
+ module Jirafe
2
+ module Resource
3
+ class JirafeResource
4
+ include HTTParty
5
+ base_uri Jirafe.config.url
6
+ format :json
7
+ default_params :token => Jirafe.config.token
8
+ debug_output Jirafe.config.logger if ENV["DEBUG_JIRAFE"]
9
+
10
+ class << self
11
+ def logger
12
+ Jirafe.config.logger
13
+ end
14
+
15
+ def attributes(attrs = {})
16
+ attrs.each do |attr|
17
+ attr_name, options = attr
18
+ attr_accessor attr_name
19
+ if options.include?(:identifier)
20
+ define_method attr_name do
21
+ ivar = instance_variable_get("@#{attr_name}")
22
+ ivar.nil? ? nil : ivar.to_i
23
+ end
24
+ alias_method :identifier, attr_name
25
+ alias_method :identifier=, "#{attr_name}="
26
+ end
27
+ end
28
+ @attributes ||= attrs
29
+ end
30
+
31
+ def path(path = nil)
32
+ return Jirafe.config.url unless superclass == JirafeResource
33
+ @path ||= path
34
+ @path || raise(Jirafe::Error::MissingResourcePath)
35
+ end
36
+ alias_method :url, :path
37
+
38
+ def parent(parent = nil)
39
+ return nil if self == Jirafe::Resource::JirafeResource
40
+ @parent ||= parent
41
+ @parent || Jirafe::Resource::JirafeResource
42
+ end
43
+
44
+ def parent_path(*parent_identifiers)
45
+ parent.nil? ? nil : parent.resource_url(*parent_identifiers)
46
+ end
47
+
48
+ def resource_url(identifier = nil, *parent_identifiers)
49
+ # puts "#{self} START"
50
+ # p parent_path(*parent_identifiers)
51
+ # p parent_identifiers
52
+ # p path
53
+ # puts "ID: #{identifier.inspect}"
54
+ # puts "#{self} END"
55
+ [parent_path(*parent_identifiers), path, identifier].compact.join("/")
56
+ end
57
+
58
+ def list(*parent_identifiers)
59
+ if parent_identifiers.last.is_a?(Hash)
60
+ options = {:query => parent_identifiers.pop }
61
+ options = parent_identifiers.pop
62
+ end
63
+ response = get(resource_url(nil, *parent_identifiers), options_with_token(options || {}))
64
+ check_response_for_exception(response)
65
+ response.parsed_response.map do |item|
66
+ self.new(item)
67
+ end
68
+ end
69
+
70
+ def retrieve(identifier = nil, *parent_identifiers)
71
+ if parent_identifiers.last.is_a?(Hash)
72
+ options = {:query => parent_identifiers.pop }
73
+ end
74
+ response = get(resource_url(identifier, *parent_identifiers), options_with_token(options || {}))
75
+ check_response_for_exception(response)
76
+ self.new(response.parsed_response)
77
+ end
78
+
79
+ def create(resource)
80
+ resource_id, parent_identifiers = identifiers_from_resource(resource)
81
+ response = post(resource_url(resource_id, *parent_identifiers), options_with_token({:body => resource.attributes_for_change(:create)}))
82
+ check_response_for_exception(response)
83
+ resource.reinitialize(response.parsed_response)
84
+ end
85
+
86
+ def update(resource)
87
+ resource_id, parent_identifiers = identifiers_from_resource(resource)
88
+ response = put(resource_url(resource_id, parent_identifiers), options_with_token({:body => resource.attributes_for_change(:update)}))
89
+ check_response_for_exception(response)
90
+ resource.reinitalize(response.parsed_response)
91
+ end
92
+
93
+ private
94
+
95
+ def identifiers_from_resource(resource)
96
+ return [] if resource.nil? || !resource.respond_to?(:identifier)
97
+ [resource.identifier] + identifiers_from_resource(resource.parent)
98
+ end
99
+
100
+ def options_with_token(options = {})
101
+ query_options = options.delete(:query) || {}
102
+ {:query => { :token => Jirafe.config.token }.merge(query_options) }.merge(options)
103
+ end
104
+
105
+ def check_response_for_exception(response)
106
+ return if (200..399).include?(response.code) # Allow any 2xx or 3xx
107
+ exception = case response.code.to_i
108
+ when 400 # NOTE: Being thrown for what should be 422's
109
+ Jirafe::Error::BadRequest
110
+ when 401
111
+ Jirafe::Error::Unauthorized
112
+ when 403
113
+ Jirafe::Error::Forbidden
114
+ when 404
115
+ Jirafe::Error::ResourceNotFound
116
+ when 405
117
+ Jirafe::Error::NotAllowed
118
+ when 500
119
+ Jirafe::Error::ServerError
120
+ else
121
+ Jirafe::Error::UnknownError
122
+ end
123
+ raise exception.new(response)
124
+ end
125
+ end
126
+
127
+ def initialize(attributes = {})
128
+ reinitialize(attributes)
129
+ end
130
+
131
+ def reinitialize(attributes = {})
132
+ attributes.each do |attr, value|
133
+ self.send("#{attr}=", value) if self.respond_to?("#{attr}=")
134
+ end
135
+ self
136
+ end
137
+
138
+ def attributes
139
+ self.class.attributes.keys.inject({}) do |hash, attr|
140
+ hash[attr] = self.send(attr)
141
+ hash
142
+ end
143
+ end
144
+
145
+ def create
146
+ self.class.create(self)
147
+ end
148
+
149
+ def update
150
+ self.class.update(self)
151
+ end
152
+
153
+ def parent
154
+ if self.class.parent == Jirafe::Resource::JirafeResource
155
+ self.class.parent
156
+ else
157
+ @parent
158
+ end
159
+ end
160
+
161
+ def parent=(parent_instance)
162
+ @parent = parent_instance
163
+ end
164
+
165
+ def parent_resource_url
166
+ parent.nil? ? nil : parent.resource_url
167
+ end
168
+
169
+ def identifier
170
+ end
171
+
172
+ def resource_url
173
+ [parent_resource_url, self.class.path, self.identifier].compact.join("/")
174
+ end
175
+
176
+ def attributes_for_change(key)
177
+ attrs = self.class.attributes.select do |attribute|
178
+ self.class.attributes[attribute].include?(key)
179
+ end
180
+ attrs.keys.inject({}) do |hash, attr|
181
+ hash[attr] = self.send(attr)
182
+ hash
183
+ end
184
+ end
185
+
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,21 @@
1
+ module Jirafe
2
+ module Resource
3
+ class Site < JirafeResource
4
+ path "sites"
5
+ parent Application
6
+ attributes({
7
+ :site_id => [:identifier],
8
+ :app_id => [],
9
+ :description => [:create, :update],
10
+ :url => [:create, :update],
11
+ :timezone => [],
12
+ :currency => [],
13
+ :external_id => [],
14
+ :store_api_url => [:create, :update],
15
+ :timezone_diff => []
16
+ })
17
+
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,16 @@
1
+ module Jirafe
2
+ module Resource
3
+ module Sites
4
+ class AbandonRate < JirafeResource
5
+ include Jirafe::Resource::TimeSeries
6
+ count_keys "ab_rate"
7
+
8
+ path "abandon/rate"
9
+ parent Site
10
+ attributes({
11
+ :observe => []
12
+ })
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module Jirafe
2
+ module Resource
3
+ module Sites
4
+ class AbandonedAverageOrderValue < JirafeResource
5
+ include Jirafe::Resource::TimeSeries
6
+ count_keys "ab_aov"
7
+
8
+ path "abandoned/average/ordervalue"
9
+ parent Site
10
+ attributes({
11
+ :observe => []
12
+ })
13
+ end
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,16 @@
1
+ module Jirafe
2
+ module Resource
3
+ module Sites
4
+ class AbandonedCarts < JirafeResource
5
+ include Jirafe::Resource::TimeSeries
6
+ count_keys "ab_carts"
7
+
8
+ path "abandoned/carts"
9
+ parent Site
10
+ attributes({
11
+ :observe => []
12
+ })
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Jirafe
2
+ module Resource
3
+ module Sites
4
+ class AbandonedRevenue < JirafeResource
5
+ include Jirafe::Resource::TimeSeries
6
+ count_keys "ab_revenue"
7
+
8
+ path "abandoned/revenue"
9
+ parent Site
10
+ attributes({
11
+ :observe => []
12
+ })
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Jirafe
2
+ module Resource
3
+ module Sites
4
+ class AverageOrderValue < JirafeResource
5
+ include Jirafe::Resource::TimeSeries
6
+ count_keys "aov"
7
+
8
+ path "average/ordervalue"
9
+ parent Site
10
+ attributes({
11
+ :observe => []
12
+ })
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Jirafe
2
+ module Resource
3
+ module Sites
4
+ class BouncesRate < JirafeResource
5
+ include Jirafe::Resource::TimeSeries
6
+ count_keys "bounce_rate"
7
+
8
+ path "bounces/rate"
9
+ parent Site
10
+ attributes({
11
+ :observe => []
12
+ })
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module Jirafe
2
+ module Resource
3
+ module Sites
4
+ class CartSegmentation < JirafeResource
5
+ path "cart/segmentation"
6
+ parent Site
7
+ attributes({})
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ module Jirafe
2
+ module Resource
3
+ module Sites
4
+ class ConversionRate < JirafeResource
5
+ include Jirafe::Resource::TimeSeries
6
+ count_keys "conv_rate"
7
+
8
+ path "conversion/rate"
9
+ parent Site
10
+ attributes({
11
+ :observe => []
12
+ })
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module Jirafe
2
+ module Resource
3
+ module Sites
4
+ class Conversions < JirafeResource
5
+ include Jirafe::Resource::TimeSeries
6
+ count_keys "orders"
7
+
8
+ path "conversions"
9
+ parent Site
10
+ attributes({
11
+ :observe => []
12
+ })
13
+ end
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,16 @@
1
+ module Jirafe
2
+ module Resource
3
+ module Sites
4
+ class Customers < JirafeResource
5
+ include Jirafe::Resource::TimeSeries
6
+ count_keys "customers", "customers_returning"
7
+
8
+ path "customers"
9
+ parent Site
10
+ attributes({
11
+ :observe => []
12
+ })
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,27 @@
1
+ module Jirafe
2
+ module Resource
3
+ module Sites
4
+ class Dashboard < JirafeResource
5
+ path "dashboard/freebird"
6
+ parent Site
7
+ attributes({
8
+ :observe => {
9
+ :visits => [],
10
+ :customers => [],
11
+ :referrer => [],
12
+ :keyword => [],
13
+ :origin => [],
14
+ :product => [],
15
+ :category => [],
16
+ :abandoned_product => [],
17
+ :abandoned_category => [],
18
+ :metrics => [],
19
+ :carts => [],
20
+ :sales => []
21
+ },
22
+ :tracked_customers => []
23
+ })
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ module Jirafe
2
+ module Resource
3
+ module Sites
4
+ class Keywords < JirafeResource
5
+ path "keywords"
6
+ parent Site
7
+ attributes({})
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ module Jirafe
2
+ module Resource
3
+ module Sites
4
+ class OrdersStatus < JirafeResource
5
+ path "orders/status"
6
+ parent Site
7
+ attributes({
8
+ :ok => [],
9
+ :version => [],
10
+ :errors => []
11
+ })
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ module Jirafe
2
+ module Resource
3
+ module Sites
4
+ class Origins < JirafeResource
5
+ path "origins"
6
+ parent Site
7
+ attributes({})
8
+ end
9
+ end
10
+ end
11
+ end