zanox_publisher 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +178 -0
  7. data/Rakefile +10 -0
  8. data/lib/zanox_publisher/ad_medium.rb +232 -0
  9. data/lib/zanox_publisher/ad_space.rb +159 -0
  10. data/lib/zanox_publisher/base.rb +69 -0
  11. data/lib/zanox_publisher/category.rb +57 -0
  12. data/lib/zanox_publisher/connection.rb +291 -0
  13. data/lib/zanox_publisher/exclusive_incentive.rb +135 -0
  14. data/lib/zanox_publisher/format.rb +19 -0
  15. data/lib/zanox_publisher/incentive.rb +135 -0
  16. data/lib/zanox_publisher/incentive_base.rb +89 -0
  17. data/lib/zanox_publisher/policy.rb +42 -0
  18. data/lib/zanox_publisher/prize.rb +18 -0
  19. data/lib/zanox_publisher/product.rb +263 -0
  20. data/lib/zanox_publisher/profile.rb +123 -0
  21. data/lib/zanox_publisher/program.rb +241 -0
  22. data/lib/zanox_publisher/program_application.rb +135 -0
  23. data/lib/zanox_publisher/tracking_link.rb +42 -0
  24. data/lib/zanox_publisher/version.rb +3 -0
  25. data/lib/zanox_publisher/vertical.rb +19 -0
  26. data/lib/zanox_publisher.rb +39 -0
  27. data/spec/config/credentials.example.yml +2 -0
  28. data/spec/lib/requirements_spec.rb +9 -0
  29. data/spec/lib/zanox_publisher/ad_medium_spec.rb +162 -0
  30. data/spec/lib/zanox_publisher/ad_space_spec.rb +56 -0
  31. data/spec/lib/zanox_publisher/base_spec.rb +35 -0
  32. data/spec/lib/zanox_publisher/connection_spec.rb +68 -0
  33. data/spec/lib/zanox_publisher/exclusive_incentive_spec.rb +104 -0
  34. data/spec/lib/zanox_publisher/incentive_spec.rb +112 -0
  35. data/spec/lib/zanox_publisher/product_spec.rb +223 -0
  36. data/spec/lib/zanox_publisher/profile_spec.rb +26 -0
  37. data/spec/lib/zanox_publisher/program_application_spec.rb +51 -0
  38. data/spec/lib/zanox_publisher/program_spec.rb +192 -0
  39. data/spec/lib/zanox_ruby_spec.rb +17 -0
  40. data/spec/spec_helper.rb +21 -0
  41. data/spec/support/credentials.rb +3 -0
  42. data/spec/support/vcr.rb +8 -0
  43. data/spec/vcr_cassettes/.gitignore +4 -0
  44. data/zanox_publisher.gemspec +27 -0
  45. metadata +203 -0
@@ -0,0 +1,69 @@
1
+ module ZanoxPublisher
2
+ # Base class for resources with pagination
3
+ class Base
4
+ @@default_per_page = 10
5
+ @@maximum_per_page = 50
6
+
7
+ class << self
8
+ # Getter for the maximum per page
9
+ #
10
+ # @return [Integer]
11
+ def maximum_per_page
12
+ @@maximum_per_page
13
+ end
14
+
15
+ # Set the number of items to request per page.
16
+ #
17
+ # @param number [Integer] The number of items per page (default = 10; maximum = 50)
18
+ #
19
+ # @return [Integer]
20
+ #
21
+ # @example
22
+ # ZanoxPublisher::AdSpace.per_page = 20 #=> 20
23
+ # first_page = ZanoxPublisher::AdSpace.page #=> [Array<AdSpace>]
24
+ def per_page=(number)
25
+ if number.to_i < 0
26
+ @per_page = 0
27
+ elsif number.to_i > @@maximum_per_page
28
+ @per_page = @@maximum_per_page
29
+ else
30
+ @per_page = number.to_i
31
+ end
32
+
33
+ @per_page
34
+ end
35
+
36
+ # Returns the number of items to request per page.
37
+ # The default of 10 is returned if per_page is not set.
38
+ #
39
+ # @return [Integer]
40
+ def per_page
41
+ @per_page ||= @@default_per_page
42
+ end
43
+
44
+ # Internally set total item count.
45
+ #
46
+ # @param number [Integer] The total items from the API response
47
+ #
48
+ # @return [Integer]
49
+ def total=(number)
50
+ @total = number
51
+ end
52
+
53
+ # Returns the total number of items or nil in case no page was requested
54
+ #
55
+ # @return [Integer, nil]
56
+ #
57
+ # @example
58
+ # data = []
59
+ # number = 0
60
+ # do
61
+ # data << ZanoxPublisher::AdSpace.page(number)
62
+ # number += 1
63
+ # end while data.size < ZanoxPublisher::AdSpace.total
64
+ def total
65
+ @total
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,57 @@
1
+ module ZanoxPublisher
2
+ # General category class
3
+ #
4
+ # Legacy name category is for program and admedium
5
+ #
6
+ # NOTE: Later create enumerable class Categories to allow .include? on result from API
7
+ #
8
+ # @param [Integer] id The identifer of the category
9
+ # @param [String] name The name of the category
10
+ class Category
11
+ class << self
12
+ # Fetch all categories from Zanox API Response
13
+ #
14
+ # @param data [Array] the value of the 'categories' element
15
+ #
16
+ # @return [Array<Category>, nil]
17
+ def fetch(data = nil)
18
+ # To support API of picking categories of hash with [] notation
19
+ return nil if data.nil?
20
+ categories = data.first
21
+ # In case the array is empty first will return a nil
22
+ return nil if categories.nil?
23
+ categories = categories['category']
24
+ # In case the second level is missing the hash [] notation will nil
25
+ return nil if categories.nil?
26
+ # In case just one category is in the list it must be converted back to an array
27
+ categories = [categories] if categories.is_a? Hash
28
+
29
+ # We got the array of category hash's
30
+ retval = []
31
+
32
+ categories.each do |category|
33
+ retval << self.new(category)
34
+ end
35
+
36
+ retval
37
+ end
38
+ end
39
+ attr_reader :id, :name
40
+
41
+ def initialize(data = {})
42
+ @id = data.fetch('@id').to_i
43
+ @name = data.fetch('$', nil)
44
+ end
45
+
46
+ def to_s
47
+ @name
48
+ end
49
+
50
+ # Returns the category ID as integer representation
51
+ #
52
+ # @return [Integer]
53
+ def to_i
54
+ @id
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,291 @@
1
+ require 'httparty'
2
+ require 'base64'
3
+ require 'openssl'
4
+
5
+ module ZanoxPublisher
6
+ # Represents a Zanox Product API error. Contains specific data about the error.
7
+ class ZanoxError < StandardError
8
+ attr_reader :data
9
+
10
+ def initialize(data)
11
+ @data = data
12
+
13
+ # should contain Code, Message, and Reason
14
+ code = data['code'].to_s
15
+ message = data['message'].to_s
16
+ reason = data['reason'].to_s
17
+ super "The Zanox Product API responded with the following error message: #{message} Error reason: #{reason} [code: #{code}]"
18
+ end
19
+ end
20
+
21
+ # Raised for HTTP response codes of 400...500
22
+ class ClientError < StandardError; end
23
+ # Raised for HTTP response codes of 500...600
24
+ class ServerError < StandardError; end
25
+ # Raised for HTTP response code of 400
26
+ class BadRequest < ZanoxError; end
27
+ # Raised when authentication information is missing
28
+ class AuthenticationError < StandardError; end
29
+ # Raised when authentication fails with HTTP response code of 403
30
+ class Unauthorized < ZanoxError; end
31
+ # Raised for HTTP response code of 404
32
+ class NotFound < ClientError; end
33
+
34
+ # Raw connection to the Zanox API
35
+ #
36
+ # @attr [String] relative_path The default relative path used for a request
37
+ class Connection
38
+ include HTTParty
39
+
40
+ API_URI = 'https://api.zanox.com'
41
+ DATA_FORMAT = 'json'
42
+ API_VERSION = '2011-03-01'
43
+
44
+ base_uri "#{API_URI}/#{DATA_FORMAT}/#{API_VERSION}"
45
+
46
+ USER_AGENT_STRING = "ZanoxPublisher/#{VERSION} (ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}; #{RUBY_PLATFORM})"
47
+
48
+ attr_accessor :relative_path
49
+
50
+ # Initializes a new connection instance of ZanoxPublisher.
51
+ # It requires authentication information to access the Publisher API.
52
+ # The relative path is used as the default for HTTP method calls.
53
+ #
54
+ # The connect ID and secret key can be passed as parameters,
55
+ # else the ZanoxPublisher::authenticate information is taken.
56
+ #
57
+ # @param relative_path [String] The default relative path of the resource
58
+ # @param connect_id [String] The connect ID of your account for authentication
59
+ # @param secret_key [String] The secret key of your account for authentication
60
+ #
61
+ # @example
62
+ # connection = ZanoxPublisher::Connection.new("/profiles", "<your_client_id>", "<your_client_secret>") #=> #<Connection ...>
63
+ # connection.get #=> #<HTTParty::Response ...>
64
+ #
65
+ # @example
66
+ # connection = ZanoxPublisher::Connection.new #=> #<Connection ...>
67
+ # connection.get('/profiles') #=> #<Hash::Response ...>
68
+ #
69
+ def initialize(relative_path = '', connect_id = ZanoxPublisher.connect_id, secret_key = ZanoxPublisher.secret_key)
70
+ @connect_id, @secret_key = connect_id, secret_key
71
+ @relative_path = relative_path
72
+ @connection = self.class
73
+ end
74
+
75
+ # Sends a GET request for a public resource - auth with connect ID
76
+ #
77
+ # For more information on authentication see {https://developer.zanox.com/web/guest/authentication/zanox-oauth/oauth-rest}
78
+ #
79
+ # @param relative_path [String] The relative path of the API resource
80
+ # @param params [Hash] The HTTParty params argument
81
+ #
82
+ # @return [Hash]
83
+ #
84
+ # @example
85
+ # connection = ZanoxPublisher::Connection.new #=> #<Connection ...>
86
+ # connection.get('/path') #=> #<Hash::Response ...>
87
+ def get(relative_path = @relative_path, params = {})
88
+ handle_response connection.get(relative_path, public_auth(params))
89
+ end
90
+
91
+ # Sends a POST request for a public resource - auth with connect ID
92
+ #
93
+ # For more information on authentication see {https://developer.zanox.com/web/guest/authentication/zanox-oauth/oauth-rest}
94
+ #
95
+ # @param relative_path [String] The relative path of the API resource
96
+ # @param params [Hash] The HTTParty params argument
97
+ #
98
+ # @return [Hash]
99
+ #
100
+ # @example
101
+ # connection = ZanoxPublisher::Connection.new #=> #<Connection ...>
102
+ # connection.post('/path') #=> #<Hash::Response ...>
103
+ def post(relative_path = @relative_path, params = {})
104
+ handle_response connection.post(relative_path, public_auth(params))
105
+ end
106
+
107
+ # Sends a PUT request for a public resource - auth with connect ID
108
+ #
109
+ # For more information on authentication see {https://developer.zanox.com/web/guest/authentication/zanox-oauth/oauth-rest}
110
+ #
111
+ # @param relative_path [String] The relative path of the API resource
112
+ # @param params [Hash] The HTTParty params argument
113
+ #
114
+ # @return [Hash]
115
+ #
116
+ # @example
117
+ # connection = ZanoxPublisher::Connection.new #=> #<Connection ...>
118
+ # connection.put('/path') #=> #<Hash::Response ...>
119
+ def put(relative_path = @relative_path, params = {})
120
+ handle_response connection.put(relative_path, public_auth(params))
121
+ end
122
+
123
+ # Sends a DELETE request for a public resource - auth with connect ID
124
+ #
125
+ # For more information on authentication see {https://developer.zanox.com/web/guest/authentication/zanox-oauth/oauth-rest}
126
+ #
127
+ # @param relative_path [String] The relative path of the API resource
128
+ # @param params [Hash] The HTTParty params argument
129
+ #
130
+ # @return [Hash]
131
+ #
132
+ # @example
133
+ # connection = ZanoxPublisher::Connection.new #=> #<Connection ...>
134
+ # connection.delete('/path') #=> #<Hash::Response ...>
135
+ def delete(relative_path = @relative_path, params = {})
136
+ handle_response connection.delete(relative_path, public_auth(params))
137
+ end
138
+
139
+ # Sends a GET request for a private resource - auth with signature
140
+ #
141
+ # For more information on authentication see {https://developer.zanox.com/web/guest/authentication/zanox-oauth/oauth-rest}
142
+ #
143
+ # @param relative_path [String] The relative path of the API resource
144
+ # @param params [Hash] The HTTParty params argument
145
+ #
146
+ # @return [Hash]
147
+ #
148
+ # @example
149
+ # connection = ZanoxPublisher::Connection.new #=> #<Connection ...>
150
+ # connection.signature_get('/path') #=> #<Hash::Response ...>
151
+ def signature_get(relative_path = @relative_path, params = {})
152
+ handle_response connection.get(relative_path, private_auth('GET', relative_path, params))
153
+ end
154
+
155
+ # Sends a POST request for a private resource - auth with signature
156
+ #
157
+ # For more information on authentication see {https://developer.zanox.com/web/guest/authentication/zanox-oauth/oauth-rest}
158
+ #
159
+ # @param relative_path [String] The relative path of the API resource
160
+ # @param params [Hash] The HTTParty params argument
161
+ #
162
+ # @return [Hash]
163
+ #
164
+ # @example
165
+ # connection = ZanoxPublisher::Connection.new #=> #<Connection ...>
166
+ # connection.signature_post('/path') #=> #<Hash::Response ...>
167
+ def signature_post(relative_path = @relative_path, params = {})
168
+ handle_response connection.post(relative_path, private_auth('POST', relative_path, params))
169
+ end
170
+
171
+ # Sends a PUT request for a private resource - auth with signature
172
+ #
173
+ # For more information on authentication see {https://developer.zanox.com/web/guest/authentication/zanox-oauth/oauth-rest}
174
+ #
175
+ # @param relative_path [String] The relative path of the API resource
176
+ # @param params [Hash] The HTTParty params argument
177
+ #
178
+ # @return [Hash]
179
+ #
180
+ # @example
181
+ # connection = ZanoxPublisher::Connection.new #=> #<Connection ...>
182
+ # connection.signature_put('/path') #=> #<Hash::Response ...>
183
+ def signature_put(relative_path = @relative_path, params = {})
184
+ handle_response connection.put(relative_path, private_auth('PUT', relative_path, params))
185
+ end
186
+
187
+ # Sends a DELETE request for a private resource - auth with signature
188
+ #
189
+ # For more information on authentication see {https://developer.zanox.com/web/guest/authentication/zanox-oauth/oauth-rest}
190
+ #
191
+ # @param relative_path [String] The relative path of the API resource
192
+ # @param params [Hash] The HTTParty params argument
193
+ #
194
+ # @return [Hash]
195
+ #
196
+ # @example
197
+ # connection = ZanoxPublisher::Connection.new #=> #<Connection ...>
198
+ # connection.signature_delete('/path') #=> #<Hash::Response ...>
199
+ def signature_delete(relative_path = @relative_path, params = {})
200
+ handle_response connection.delete(relative_path, private_auth('DELETE', relative_path, params))
201
+ end
202
+
203
+ private
204
+
205
+ attr_reader :connection
206
+
207
+ # Internal routine to handle the HTTParty::Response
208
+ def handle_response(response) # :nodoc:
209
+ case response.code
210
+ when 400
211
+ #IN CASE WE WANT MORE PRECISE ERROR NAMES
212
+ #data = response.parsed_response
213
+ #case data['code']
214
+ #when 230
215
+ # raise ParameterDataInvalid.new data
216
+ #else
217
+ # raise BadRequest.new data
218
+ #end
219
+ raise BadRequest.new(response.parsed_response)
220
+ when 403
221
+ raise Unauthorized.new(response.parsed_response)
222
+ when 404
223
+ raise NotFound.new
224
+ when 400...500
225
+ raise ClientError.new
226
+ when 500...600
227
+ raise ServerError.new
228
+ else
229
+ response.parsed_response
230
+ end
231
+ end
232
+
233
+ # Authentication header for public resources of the Zanox API
234
+ # Public resources - auth with connection ID.
235
+ #
236
+ # For details access the guide found {https://developer.zanox.com/web/guest/authentication/zanox-oauth/oauth-rest here}.
237
+ def public_auth(params)
238
+ raise AuthenticationError, 'Please provide your connect ID.' if @connect_id.nil?
239
+
240
+ auth = { 'Authorization' => "ZXWS #{@connect_id}" }
241
+
242
+ if params.has_key? :headers
243
+ params[:headers].merge(auth)
244
+ else
245
+ params[:headers] = auth
246
+ end
247
+
248
+ params
249
+ end
250
+
251
+ # Authentication header for private resources of the Zanox API
252
+ # Private resources - auth with signature.
253
+ #
254
+ # For details access the guide found {https://developer.zanox.com/web/guest/authentication/zanox-oauth/oauth-rest here}.
255
+ # Signature = Base64( HMAC-SHA1( UTF-8-Encoding-Of( StringToSign ) ) );
256
+ # StringToSign = HTTP-Verb + URI + timestamp + nonce
257
+ # HTTP Verb - GET, POST, PUT or DELETE;
258
+ # URI - exclude return format and API version date, include path parameters http://api.zanox.com/json/2011-03-01 -> /reports/sales/date/2013-07-20
259
+ # Timestamp - in GMT, format "EEE, dd MMM yyyy HH:mm:ss";
260
+ # Nonce - unique random string, generated at the time of request, valid once, 20 or more characters
261
+ def private_auth(verb, relative_path, params)
262
+ raise AuthenticationError, 'Please provide your connect ID.' if @connect_id.nil?
263
+ raise AuthenticationError, 'Please provide your secret key.' if @secret_key.nil?
264
+
265
+ # API Method: GET Sales for the date 2013-07-20
266
+ # 1. Generate nonce and timestamp
267
+ timestamp = Time.new.gmtime.strftime('%a, %e %b %Y %T GMT').to_s
268
+ # %e is with 0 padding so 06 for day 6 else use %d
269
+ #timestamp = Time.new.gmtime.strftime('%a, %d %b %Y %T GMT').to_s
270
+ nonce = OpenSSL::Digest::MD5.hexdigest((Time.new.usec + rand()).to_s)
271
+ # 2. Concatinate HTTP Verb, URI, timestamp and nonce to create StringToSign
272
+ string_to_sign = "#{verb}#{relative_path}#{timestamp}#{nonce}"
273
+ # 3. Hash the StringToSign using the secret key as HMAC parameter
274
+ signature = Base64.encode64("#{OpenSSL::HMAC.digest('sha1', @secret_key, string_to_sign)}").chomp
275
+ # 4. Add information to request headers
276
+ auth = {
277
+ 'Authorization' => "ZXWS #{@connect_id}:#{signature}",
278
+ 'Date' => timestamp,
279
+ 'nonce' => nonce
280
+ }
281
+
282
+ if params.has_key? :headers
283
+ params[:headers].merge(auth)
284
+ else
285
+ params[:headers] = auth
286
+ end
287
+
288
+ params
289
+ end
290
+ end
291
+ end
@@ -0,0 +1,135 @@
1
+ module ZanoxPublisher
2
+ # Exclusive incentives - Get coupons and other incentives
3
+ #
4
+ # The Zanox API cannot retrieve both exclusive and non-exclusive incentives, so each has its own class.
5
+ class ExclusiveIncentive < IncentiveBase
6
+ RESOURCE_PATH = '/incentives/exclusive'
7
+
8
+ # Set the exclusive attribute
9
+ @@exclusive = true
10
+
11
+ class << self
12
+ # Retrieves all incentive's dependent on search parameters.
13
+ #
14
+ # This is equivalent to the Zanox API method SearchExclusiveIncentives.
15
+ # The method documentation can be found under {https://developer.zanox.com/web/guest/publisher-api-2011/get-incentives-exclusive}.
16
+ #
17
+ # Authentication: Requires signature.
18
+ #
19
+ # This can require multiple requests, as internally every page is pulled.
20
+ # The ZanoxPublisher::AdMedium.page function can be used to better control the requests made.
21
+ #
22
+ # @param program [Program, Integer] limits results to a particular program ID.
23
+ # @param adspace [AdSpace, Integer] limits results to incentives that have tracking links associated with this AdSpace.
24
+ # @param incentive_type [String] limits results to one of the following incentive types (API equivalent is incentiveType).
25
+ # @param incentiveType [String] limits results to one of the following incentive types (API name).
26
+ # @param region [String] limits results to a region.
27
+ #
28
+ # @return [Array<ExclusiveIncentive>]
29
+ def all(options = {})
30
+ retval = []
31
+ current_page = 0
32
+ options.merge!({ per_page: maximum_per_page })
33
+
34
+ begin
35
+ retval += self.page(current_page, options)
36
+ current_page += 1
37
+ end while ExclusiveIncentive.total > retval.size
38
+
39
+ retval
40
+ end
41
+
42
+ # Retrieves a list of exclusive incentiveItems dependent on search parameter.
43
+ #
44
+ # This is equivalent to the Zanox API method SearchExclusiveIncentives.
45
+ # The method documentation can be found under {https://developer.zanox.com/web/guest/publisher-api-2011/get-incentives-exclusive}.
46
+ #
47
+ # Authentication: Requires signature.
48
+ #
49
+ # @param page [Integer] the page position.
50
+ # @param per_page [Integer] number of items in the result set (API equivalent is items).
51
+ # @param items [Integer] number of items in the result set (API name).
52
+ # @param program [Program, Integer] limits results to a particular program ID.
53
+ # @param adspace [AdSpace, Integer] limits results to incentives that have tracking links associated with this AdSpace.
54
+ # @param incentive_type [String] limits results to one of the following incentive types (API equivalent is incentiveType).
55
+ # @param incentiveType [String] limits results to one of the following incentive types (API name).
56
+ # @param region [String] limits results to a region.
57
+ #
58
+ # @return [Array<ExclusiveIncentive>]
59
+ def page(page = 0, options = {})
60
+ params = { query: { page: page } }
61
+
62
+ per_page = nil
63
+ per_page = options[:per_page] if per_page.nil?
64
+ per_page = options[:items] if per_page.nil?
65
+ per_page = AdMedium.per_page if per_page.nil?
66
+ params[:query].merge!({ items: per_page })
67
+
68
+ program = options[:program]
69
+ program = program.to_i unless program.nil?
70
+
71
+ adspace = options[:adspace]
72
+ adspace = adspace.to_i unless adspace.nil?
73
+
74
+ incentive_type = options[:incentive_type]
75
+ incentive_type = options[:incentiveType] if incentive_type.nil?
76
+ incentive_type = nil unless @@incentive_types.include? incentive_type
77
+
78
+ region = options[:region]
79
+
80
+ # Build the query on hand of the options received
81
+ params[:query].merge!({ program: program }) unless program.nil?
82
+ params[:query].merge!({ adspace: adspace }) unless adspace.nil?
83
+ params[:query].merge!({ incentiveType: incentive_type }) unless incentive_type.nil?
84
+ params[:query].merge!({ region: region }) unless region.nil?
85
+
86
+ retval = []
87
+
88
+ response = self.connection.signature_get(RESOURCE_PATH, params)
89
+
90
+ ExclusiveIncentive.total = response.fetch('total')
91
+
92
+ incentives = []
93
+ incentives = response.fetch('incentiveItems', {}).fetch('incentiveItem', []) if ExclusiveIncentive.total > 0
94
+ incentives = [incentives] unless incentives.is_a? Array
95
+
96
+ incentives.each do |incentive|
97
+ retval << ExclusiveIncentive.new(incentive, @@exclusive)
98
+ end
99
+
100
+ retval
101
+ end
102
+
103
+ # Returns a single incentiveItem, as queried by its ID.
104
+ #
105
+ # This is equivalent to the Zanox API method GetExclusiveIncentive.
106
+ # The method documentation can be found under {https://developer.zanox.com/web/guest/publisher-api-2011/get-incentives-exclusive-incentive}.
107
+ #
108
+ # Authentication: Requires signature.
109
+ #
110
+ # @param id [Integer] the ID of the adspace you want to get.
111
+ # @param adspace [AdSpace, Integer] if you would like tracking links for only one of your publisher ad spaces, pass its ID in this parameter.
112
+ #
113
+ # @return [<ExclusiveIncentive>]
114
+ def find(id, options = {})
115
+ params = {}
116
+
117
+ adspace = options[:adspace]
118
+ adspace = adspace.to_i unless adspace.nil?
119
+
120
+ params = { query: { adspace: adspace } } unless adspace.nil?
121
+
122
+ response = self.connection.signature_get(RESOURCE_PATH + "/incentive/#{id.to_i}", params)
123
+
124
+ ExclusiveIncentive.new(response.fetch('incentiveItem'), @@exclusive)
125
+ end
126
+
127
+ # A connection instance with ExclusiveIncentives' relative_path
128
+ #
129
+ # @return [Connection]
130
+ def connection
131
+ @connection ||= Connection.new(RESOURCE_PATH)
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,19 @@
1
+ module ZanoxPublisher
2
+ # Wrapper for the format response from Zanox API
3
+ class Format
4
+ attr_reader :id, :name
5
+
6
+ def initialize(data = {})
7
+ @id = data.fetch('@id').to_i
8
+ @name = data.fetch('$')
9
+ end
10
+
11
+ def to_s
12
+ @name
13
+ end
14
+
15
+ def to_i
16
+ @id
17
+ end
18
+ end
19
+ end