recs4 0.0.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.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 kinumi
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a
4
+ copy of this software and associated documentation files (the "Software"
5
+ ), to deal in the Software without restriction, including without
6
+ limitation the rights to use, copy, modify, merge, publish, distribute,
7
+ sublicense, and/or sell copies of the Software, and to permit persons
8
+ to whom the Software is furnished to do so, subject to the following
9
+ conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included
12
+ in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,12 @@
1
+ README.txt
2
+ LICENSE.txt
3
+ Manifest.txt
4
+ Rakefile
5
+ setup.rb
6
+ lib/recs4.rb
7
+ lib/recs4/operation.rb
8
+ lib/recs4/version.rb
9
+ lib/recs4/xml/element.rb
10
+ lib/recs4/xml/elements.rb
11
+ test/test_helper.rb
12
+ test/jp_recs4_test.rb
@@ -0,0 +1,47 @@
1
+ == RECS4 is
2
+
3
+ An interface library to use
4
+ the Amazon E-Commerce Service 4.0 (ECS4.0) API on Ruby.
5
+
6
+
7
+ == Example to use
8
+
9
+ o = RECS4::Operation.new("Your AWSAccessKeyId", :locale => "jp")
10
+
11
+ # ItemLookup Operation
12
+ r = o.item_lookup("some asin", :response_group => "Large")
13
+ # Get element value
14
+ r[:items][:item][:asin].text #=> "some asin"
15
+ # Get attribute value
16
+ r[:items][:item][:item_attributes][:creator].a("Role") #=> "Artist"
17
+
18
+ # ItemSearch Operation
19
+ r = o.item_search("keywords")
20
+ # Get total pages
21
+ r[:items][:total_pages].text.to_i
22
+ # Get All items
23
+ r[:items][:item].each do |item|
24
+ item[:item_attributes][:artist].text
25
+ end
26
+
27
+
28
+ == License
29
+
30
+ See LICENSE
31
+
32
+
33
+ == Report bugs
34
+
35
+ https://rubyforge.org/projects/recs4/
36
+
37
+
38
+ == SVN repository
39
+
40
+ http://www.looselife.org/svn/ruby/lib/recs4/trunk/
41
+
42
+
43
+ == Developper
44
+
45
+ * kinumi
46
+ * kinumi@looselife.org
47
+ * http://www.looselife.org/
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'fileutils'
10
+ require 'hoe'
11
+ include FileUtils
12
+ require File.join(File.dirname(__FILE__), 'lib', 'recs4', 'version')
13
+
14
+ AUTHOR = "kinumi" # can also be an array of Authors
15
+ EMAIL = "kinumi@looselife.org"
16
+ DESCRIPTION = "An interface library to use the Amazon E-Commerce Service 4.0 (ECS4.0) API on Ruby."
17
+ GEM_NAME = "recs4" # what ppl will type to install your gem
18
+ RUBYFORGE_PROJECT = "recs4" # The unix name for your project
19
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
20
+ RELEASE_TYPES = %w( gem ) # can use: gem, tar, zip
21
+
22
+
23
+ NAME = "recs4"
24
+ REV = File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
25
+ # VERS = ENV['VERSION'] || (RECS4::VERSION::STRING + (REV ? ".#{REV}" : ""))
26
+ ENV['VERSION'] = (RECS4::VERSION::STRING + (REV ? ".#{REV}" : ""))
27
+ VERS = ENV['VERSION']
28
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config']
29
+ RDOC_OPTS = [
30
+ "--quiet",
31
+ "--title",
32
+ "recs4 documentation",
33
+ "--opname",
34
+ "index.html",
35
+ "--line-numbers",
36
+ "--main",
37
+ "README",
38
+ "--inline-source"
39
+ ]
40
+
41
+ # Generate all the Rake tasks
42
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
43
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
44
+ p.author = AUTHOR
45
+ p.description = DESCRIPTION
46
+ p.email = EMAIL
47
+ p.summary = DESCRIPTION
48
+ p.url = HOMEPATH
49
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
50
+ p.test_globs = ["test/**/*_test.rb"]
51
+ p.clean_globs = CLEAN #An array of file patterns to delete on clean.
52
+
53
+ # == Optional
54
+ #p.changes - A description of the release's latest changes.
55
+ #p.extra_deps - An array of rubygem dependencies.
56
+ #p.spec_extras - A hash of extra values to set in the gemspec.
57
+ end
@@ -0,0 +1,2 @@
1
+ require "recs4/version"
2
+ require "recs4/operation"
@@ -0,0 +1,385 @@
1
+ require "uri"
2
+ require "open-uri"
3
+ require "kconv"
4
+ require "recs4/xml/element"
5
+
6
+ module RECS4 #:nodoc:
7
+ LOCALES = [
8
+ "ca",
9
+ "de",
10
+ "fr",
11
+ "jp",
12
+ "uk",
13
+ "us",
14
+ ]
15
+ DEFAULT_LOCALE = "us"
16
+
17
+ WS_URLS = {
18
+ "ca" => "http://webservices.amazon.ca/onca/xml?Service=AWSECommerceService",
19
+ "de" => "http://webservices.amazon.de/onca/xml?Service=AWSECommerceService",
20
+ "fr" => "http://webservices.amazon.fr/onca/xml?Service=AWSECommerceService",
21
+ "jp" => "http://webservices.amazon.co.jp/onca/xml?Service=AWSECommerceService",
22
+ "uk" => "http://webservices.amazon.co.uk/onca/xml?Service=AWSECommerceService",
23
+ "us" => "http://webservices.amazon.com/onca/xml?Service=AWSECommerceService",
24
+ }
25
+
26
+ # All operations of ECS4.0
27
+ OPERATIONS = {
28
+ :browse_node_lookup => "BrowseNodeLookup",
29
+ :cart_add => "CartAdd",
30
+ :cart_clear => "CartClear",
31
+ :cart_create => "CartCreate",
32
+ :cart_get => "CartGet",
33
+ :cart_modify => "CartModify",
34
+ :customer_content_lookup => "CustomerContentLookup",
35
+ :customer_content_search => "CustomerContentSearch",
36
+ :help => "Help",
37
+ :item_lookup => "ItemLookup",
38
+ :item_search => "ItemSearch",
39
+ :list_lookup => "ListLookup",
40
+ :list_search => "ListSearch",
41
+ :seller_listing_lookup => "SellerListingLookup",
42
+ :seller_listing_search => "SellerListingSearch",
43
+ :seller_lookup => "SellerLookup",
44
+ :similarity_lookup => "SimilarityLookup",
45
+ :transaction_lookup => "TransactionLookup",
46
+ }
47
+
48
+ # Common parameters of all operations
49
+ GLOBAL_PARAMS = {
50
+ :locale => "Locale",
51
+ :associate_tag => "AssociateTag",
52
+ :version => "Version",
53
+ }
54
+
55
+ # Parameters of ItemLookup
56
+ ITEM_LOOKUP_PARAMS = {
57
+ :item_id => "ItemId",
58
+ :id_type => "IdType",
59
+ :search_index => "SearchIndex",
60
+ :merchant_id => "MerchantId",
61
+ :condition => "Condition",
62
+ :delivery_method => "DeliveryMethod",
63
+ :ispu_postal_code => "ISPUPostalCode",
64
+ :offer_page => "OfferPage",
65
+ :review_page => "ReviewPage",
66
+ :variation_page => "VariationPage",
67
+ :response_group => "ResponseGroup",
68
+ }
69
+
70
+ # Parameters of ItemSearch
71
+ ITEM_SEARCH_PARAMS = {
72
+ :availability => "Availability",
73
+ :review_sort => "ReviewSort",
74
+ :search_index => "SearchIndex",
75
+ :keywords => "Keywords",
76
+ :title => "Title",
77
+ :power => "Power",
78
+ :browse_node => "BrowseNode",
79
+ :artist => "Artist",
80
+ :author => "Author",
81
+ :actor => "Actor",
82
+ :director => "Director",
83
+ :audience_rating => "AudienceRating",
84
+ :manufacturer => "Manufacturer",
85
+ :music_label => "MusicLabel",
86
+ :composer => "Composer",
87
+ :publisher => "Publisher",
88
+ :brand => "Brand",
89
+ :conductor => "Conductor",
90
+ :orchestra => "Orchestra",
91
+ :text_stream => "TextStream",
92
+ :item_page => "ItemPage",
93
+ :sort => "Sort",
94
+ :city => "City",
95
+ :cuisine => "Cuisine",
96
+ :neighborhood => "Neighborhood",
97
+ :minimum_price => "MinimumPrice",
98
+ :maximum_price => "MaximumPrice",
99
+ :merchantid => "MerchantId",
100
+ :condition => "Condition",
101
+ :delivery_method => "DeliveryMethod",
102
+ :response_group => "ResponseGroup",
103
+ }
104
+
105
+ # Parameter of BrowseNodeLookup
106
+ BROWSE_NODE_LOOKUP_PARAMS = {
107
+ :browse_node_id => "BrowseNodeId",
108
+ :response_group => "ResponseGroup",
109
+ }
110
+
111
+ # All parameters
112
+ ALL_PARAMS = {}
113
+ ALL_PARAMS.merge! GLOBAL_PARAMS
114
+ ALL_PARAMS.merge! ITEM_LOOKUP_PARAMS
115
+ ALL_PARAMS.merge! ITEM_SEARCH_PARAMS
116
+ ALL_PARAMS.merge! BROWSE_NODE_LOOKUP_PARAMS
117
+
118
+ #
119
+ # This class wraps the Amazon ECS4.0 API
120
+ #
121
+ # Using REST request internally.
122
+ #
123
+ # Example to use:
124
+ #
125
+ # o = RECS4::Operation.new("Your AWSAccessKeyId", :locale => "jp")
126
+ #
127
+ # # ItemLookup Operation
128
+ # r = o.item_lookup("some asin", :response_group => "Large")
129
+ # # Get element value
130
+ # r[:items][:item][:asin].text #=> "some asin"
131
+ # # Get attribute value
132
+ # r[:items][:item][:item_attributes][:creator].a("Role") #=> "Artist"
133
+ #
134
+ # # ItemSearch Operation
135
+ # r = o.item_search("keywords")
136
+ # # Get total pages
137
+ # r[:items][:total_pages].text.to_i
138
+ # # Get All items
139
+ # r[:items][:item].each do |item|
140
+ # item[:item_attributes][:artist].text
141
+ # end
142
+ #
143
+ class Operation
144
+ #
145
+ # Available options: Look RECS4::GLOBAL_PARAMS
146
+ #
147
+ # "Locale" parameter is required in ECS4.0 API.
148
+ # But :locale option can be skipped in RECS4.
149
+ # DEFAULT_LOCALE is used.
150
+ #
151
+ def initialize(aws_access_key_id, options = {})
152
+ @aws_access_key_id = aws_access_key_id
153
+ @options = {}
154
+ GLOBAL_PARAMS.each_key do |key|
155
+ @options[key] = options[key]
156
+ end
157
+ unless @options.keys.include?(:locale)
158
+ @options[:locale] = DEFAULT_LOCALE
159
+ end
160
+ @element_names = {}
161
+ end
162
+
163
+ #
164
+ # Available options: Look RECS4::ITEM_LOOKUP_PARAMS
165
+ #
166
+ def item_lookup(item_id, options = {})
167
+ unless has_valid_item_lookup_query(item_id, options)
168
+ return nil
169
+ end
170
+ url = item_lookup_url(item_id, options)
171
+ response_xml = get_response(url)
172
+ parsed_xml = REXML::Document.new(response_xml)
173
+ return RECS4::XML::Element.new(parsed_xml.root)
174
+ end
175
+
176
+ #
177
+ # Available options: Look RECS4::ITEM_SEARCH_PARAMS
178
+ #
179
+ # "keywords" can be nil.
180
+ # If "keywords" is nil, other options for searching must not be nil.
181
+ # For example, :artist, :author, and so on.
182
+ #
183
+ def item_search(keywords, options = {})
184
+ unless options[:search_index]
185
+ options[:search_index] = "Blended"
186
+ end
187
+ unless has_valid_item_search_query(keywords, options)
188
+ return nil
189
+ end
190
+ url = item_search_url(keywords, options)
191
+ response_xml = get_response(url)
192
+ parsed_xml = REXML::Document.new(response_xml)
193
+ return RECS4::XML::Element.new(parsed_xml.root)
194
+ end
195
+
196
+ #
197
+ # Available options: Look BROWSE_NODE_LOOKUP_PARAMS
198
+ #
199
+ def browse_node_lookup(browse_node_id, options = {})
200
+ unless has_valid_browse_node_lookup_query(browse_node_id, options)
201
+ return nil
202
+ end
203
+ url = browse_node_lookup_url(browse_node_id, options)
204
+ response_xml = get_response(url)
205
+ parsed_xml = REXML::Document.new(response_xml)
206
+ return RECS4::XML::Element.new(parsed_xml.root)
207
+ end
208
+
209
+ # Not implemented yet
210
+ def cart_add
211
+ end
212
+ # Not implemented yet
213
+ def cart_clear
214
+ end
215
+ # Not implemented yet
216
+ def cart_get
217
+ end
218
+ # Not implemented yet
219
+ def cart_modify
220
+ end
221
+ # Not implemented yet
222
+ def customer_controller_lookup
223
+ end
224
+ # Not implemented yet
225
+ def customer_controller_search
226
+ end
227
+ # Not implemented yet
228
+ def help
229
+ end
230
+ # Not implemented yet
231
+ def list_lookup
232
+ end
233
+ # Not implemented yet
234
+ def list_search
235
+ end
236
+ # Not implemented yet
237
+ def seller_listing_lookup
238
+ end
239
+ # Not implemented yet
240
+ def seller_listing_search
241
+ end
242
+ # Not implemented yet
243
+ def seller_lookup
244
+ end
245
+ # Not implemented yet
246
+ def similarity_lookup
247
+ end
248
+ # Not implemented yet
249
+ def transaction_lookup
250
+ end
251
+
252
+ private
253
+ #
254
+ # Get HTTP response
255
+ #
256
+ def get_response(url)
257
+ return open(url).read
258
+ end
259
+
260
+ #
261
+ # Generate a Operation URL
262
+ #
263
+ def operation_url(operation, params = {})
264
+ url = WS_URLS[@options[:locale]].dup
265
+ url << "&AWSAccessKeyId=#{@aws_access_key_id}"
266
+ url << "&Operation=#{OPERATIONS[operation]}"
267
+ ALL_PARAMS.each_key do |key|
268
+ if params[key]
269
+ url << "&#{ALL_PARAMS[key]}=#{params[key]}"
270
+ end
271
+ end
272
+ return URI.escape(url.toutf8)
273
+ end
274
+
275
+ #
276
+ # Generate a ItemLookup operation URL
277
+ #
278
+ def item_lookup_url(item_id, options = {})
279
+ params = {
280
+ :item_id => item_id
281
+ }
282
+ GLOBAL_PARAMS.each_key do |key|
283
+ if options[key]
284
+ params[key] = options[key]
285
+ end
286
+ end
287
+ ITEM_LOOKUP_PARAMS.each_key do |key|
288
+ if options[key]
289
+ params[key] = options[key]
290
+ end
291
+ end
292
+ return operation_url(:item_lookup, params)
293
+ end
294
+
295
+ #
296
+ # Generate a ItemSearch operation URL
297
+ #
298
+ def item_search_url(keywords, options = {})
299
+ params = {}
300
+ if keywords
301
+ params[:keywords] = keywords
302
+ end
303
+ GLOBAL_PARAMS.each_key do |key|
304
+ if options[key]
305
+ params[key] = options[key]
306
+ end
307
+ end
308
+ ITEM_SEARCH_PARAMS.each_key do |key|
309
+ if options[key]
310
+ params[key] = options[key]
311
+ end
312
+ end
313
+ return operation_url(:item_search, params)
314
+ end
315
+
316
+ #
317
+ # Generate a BrowseNodeLookup operation URL
318
+ #
319
+ def browse_node_lookup_url(browse_node_id, options = {})
320
+ params = {
321
+ :browse_node_id => browse_node_id
322
+ }
323
+ GLOBAL_PARAMS.each_key do |key|
324
+ if options[key]
325
+ params[key] = options[key]
326
+ end
327
+ end
328
+ BROWSE_NODE_LOOKUP_PARAMS.each_key do |key|
329
+ if options[key]
330
+ params[key] = options[key]
331
+ end
332
+ end
333
+ return operation_url(:browse_node_lookup, params)
334
+ end
335
+
336
+ def has_valid_item_lookup_query(item_id, options ={})
337
+ # ItemId is required
338
+ unless item_id
339
+ return false
340
+ end
341
+ return true
342
+ end
343
+
344
+ def has_valid_item_search_query(keywords, options = {})
345
+ # SearchIndex is required
346
+ unless options[:search_index]
347
+ return false
348
+ end
349
+ # At least one of the parameter to search
350
+ search_word_enabled = nil
351
+ unless keywords
352
+ [
353
+ :title,
354
+ :browse_node,
355
+ :power,
356
+ :artist,
357
+ :author,
358
+ :actor,
359
+ :director,
360
+ :manufacturer,
361
+ :music_label,
362
+ :composer,
363
+ :publisher,
364
+ :brand,
365
+ :conductor,
366
+ :orchestra
367
+ ].each do |key|
368
+ search_word_enabled ||= options[key]
369
+ end
370
+ unless search_word_enabled
371
+ return false
372
+ end
373
+ end
374
+ return true
375
+ end
376
+
377
+ def has_valid_browse_node_lookup_query(browse_node_id, options ={})
378
+ # BrowseNode is required
379
+ unless browse_node_id
380
+ return false
381
+ end
382
+ return true
383
+ end
384
+ end
385
+ end