asin 0.7.0 → 0.8.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 (46) hide show
  1. data/.travis.yml +4 -6
  2. data/CHANGELOG.rdoc +10 -0
  3. data/Gemfile.lock +36 -26
  4. data/README.rdoc +11 -9
  5. data/asin.gemspec +13 -11
  6. data/lib/asin/client.rb +27 -7
  7. data/lib/asin/configuration.rb +52 -100
  8. data/lib/asin/version.rb +1 -1
  9. data/rakefile.rb +1 -7
  10. data/spec/browse_node_spec.rb +1 -3
  11. data/spec/cart_spec.rb +26 -36
  12. data/spec/cassettes/asin/asin_cart_with_an_existing_cart_should_add_items_to_a_cart.yml +68 -0
  13. data/spec/cassettes/asin/asin_cart_with_an_existing_cart_should_clear_a_cart.yml +66 -0
  14. data/spec/cassettes/asin/asin_cart_with_an_existing_cart_should_get_a_cart.yml +67 -0
  15. data/spec/cassettes/asin/asin_cart_with_an_existing_cart_should_update_a_cart.yml +70 -0
  16. data/spec/cassettes/{browse_node_599826.yml → asin/browse_node_should_lookup_a_browse_node.yml} +8 -8
  17. data/spec/cassettes/asin/cart_should_create_a_cart.yml +36 -0
  18. data/spec/cassettes/{lookup_1430218150_item_class.yml → asin/lookup_and_search_should_have_metadata.yml} +39 -21
  19. data/spec/cassettes/{lookup_1430218150.yml → asin/lookup_and_search_should_lookup_a_book.yml} +39 -21
  20. data/spec/cassettes/{lookup_multiple_asins.yml → asin/lookup_and_search_should_lookup_multiple_books.yml} +89 -71
  21. data/spec/cassettes/{lookup_1430218150_small_and_alternateversions.yml → asin/lookup_and_search_should_lookup_multiple_response_groups.yml} +7 -7
  22. data/spec/cassettes/{lookup_1430218150_rash.yml → asin/lookup_and_search_should_return_a_custom_item_class.yml} +39 -21
  23. data/spec/cassettes/{lookup_1430218150_medium.yml → asin/lookup_and_search_should_return_a_mash_value.yml} +39 -21
  24. data/spec/cassettes/{lookup_1430218150_mash.yml → asin/lookup_and_search_should_return_a_rash_value.yml} +39 -21
  25. data/spec/cassettes/asin/lookup_and_search_should_return_a_raw_value.yml +81 -0
  26. data/spec/cassettes/asin/lookup_and_search_should_search_keywords_a_book_with_fulltext.yml +538 -0
  27. data/spec/cassettes/{search_keywords_single_result.yml → asin/lookup_and_search_should_search_keywords_and_handle_a_single_result.yml} +19 -19
  28. data/spec/cassettes/{search_keywords_index_music.yml → asin/lookup_and_search_should_search_keywords_never_mind_music.yml} +62 -59
  29. data/spec/cassettes/asin/lookup_and_search_should_search_music.yml +37 -0
  30. data/spec/cassettes/{search_keywords_key_index_music.yml → asin/lookup_and_search_should_search_never_mind_music.yml} +76 -67
  31. data/spec/cassettes/asin/similarity_should_find_similar_items.yml +618 -0
  32. data/spec/cassettes/asin/similarity_should_find_similar_items_for_multiple_asins_and_different_config.yml +58 -0
  33. data/spec/cassettes/asin/similarity_should_lookup_for_similar_items.yml +618 -0
  34. data/spec/config_spec.rb +2 -7
  35. data/spec/search_spec.rb +60 -87
  36. data/spec/similarity_spec.rb +23 -0
  37. data/spec/spec_helper.rb +19 -6
  38. metadata +158 -137
  39. data/spec/cassettes/add_items1430216263.yml +0 -67
  40. data/spec/cassettes/clear_cart.yml +0 -65
  41. data/spec/cassettes/create_cart_with_asin_1430218150_and_other_asin_1430216263.yml +0 -36
  42. data/spec/cassettes/get_cart.yml +0 -67
  43. data/spec/cassettes/lookup_1430218150_raw.yml +0 -63
  44. data/spec/cassettes/search_index_music.yml +0 -32
  45. data/spec/cassettes/search_keywords.yml +0 -479
  46. data/spec/cassettes/update_items.yml +0 -70
@@ -1,12 +1,10 @@
1
1
  script: "bundle exec rake"
2
2
  rvm:
3
- - 1.8.7
4
3
  - 1.9.2
5
- - rbx
6
- - rbx-2.0
7
- - ree
4
+ - 1.9.3
5
+ - jruby-19mode
6
+ - rbx-19mode
8
7
  - ruby-head
9
- - jruby
10
8
  branches:
11
9
  only:
12
- - develop
10
+ - develop
@@ -1,3 +1,13 @@
1
+ == 0.8.0
2
+
3
+ * use confiture for configuration
4
+ * implement SimilarityLookup
5
+
6
+ == 0.7.0
7
+
8
+ * jruby compatible
9
+ * loosen gem dependencies
10
+
1
11
  == 0.6.1
2
12
 
3
13
  * fix error when passing nil to config values
@@ -1,42 +1,51 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- asin (0.7.0)
5
- crack (~> 0.1)
6
- hashie (~> 1.0)
4
+ asin (0.8.0)
5
+ confiture (~> 0.1)
6
+ crack (~> 0.3)
7
+ hashie (~> 1.1)
7
8
  httpi (~> 0.9)
8
9
 
9
10
  GEM
10
11
  remote: http://rubygems.org/
11
12
  specs:
12
- addressable (2.2.6)
13
- crack (0.1.8)
13
+ addressable (2.2.8)
14
+ coderay (1.0.7)
15
+ confiture (0.1.2)
16
+ crack (0.3.1)
14
17
  diff-lcs (1.1.3)
15
18
  fuubar (0.0.6)
16
19
  rspec (~> 2.0)
17
20
  rspec-instafail (~> 0.1.8)
18
21
  ruby-progressbar (~> 0.0.10)
19
22
  hashie (1.1.0)
20
- httpclient (2.2.1)
21
- httpi (0.9.5)
23
+ httpclient (2.2.3)
24
+ httpi (0.9.7)
22
25
  rack
23
- rack (1.3.2)
24
- rake (0.9.2)
26
+ method_source (0.7.1)
27
+ pry (0.9.9.6)
28
+ coderay (~> 1.0.5)
29
+ method_source (~> 0.7.1)
30
+ slop (>= 2.4.4, < 3)
31
+ rack (1.4.1)
32
+ rake (0.9.2.2)
25
33
  rash (0.3.1)
26
34
  hashie (~> 1.1.0)
27
- rspec (2.6.0)
28
- rspec-core (~> 2.6.0)
29
- rspec-expectations (~> 2.6.0)
30
- rspec-mocks (~> 2.6.0)
31
- rspec-core (2.6.4)
32
- rspec-expectations (2.6.0)
35
+ rspec (2.7.0)
36
+ rspec-core (~> 2.7.0)
37
+ rspec-expectations (~> 2.7.0)
38
+ rspec-mocks (~> 2.7.0)
39
+ rspec-core (2.7.1)
40
+ rspec-expectations (2.7.0)
33
41
  diff-lcs (~> 1.1.2)
34
- rspec-instafail (0.1.8)
35
- rspec-mocks (2.6.0)
42
+ rspec-instafail (0.1.9)
43
+ rspec-mocks (2.7.0)
36
44
  ruby-progressbar (0.0.10)
45
+ slop (2.4.4)
37
46
  vcr (1.11.3)
38
- webmock (1.7.6)
39
- addressable (~> 2.2, > 2.2.5)
47
+ webmock (1.8.7)
48
+ addressable (>= 2.2.7)
40
49
  crack (>= 0.1.7)
41
50
 
42
51
  PLATFORMS
@@ -45,10 +54,11 @@ PLATFORMS
45
54
 
46
55
  DEPENDENCIES
47
56
  asin!
48
- fuubar (~> 0.0)
49
- httpclient (~> 2.2)
50
- rake (~> 0.9)
51
- rash (~> 0.3)
52
- rspec (~> 2.6)
53
- vcr (~> 1.10)
54
- webmock (~> 1.6)
57
+ fuubar (~> 0.0.5)
58
+ httpclient (~> 2.2.3)
59
+ pry (~> 0.9.9)
60
+ rake (~> 0.9.2.2)
61
+ rash (~> 0.3.1)
62
+ rspec (~> 2.7.0)
63
+ vcr (~> 1.11.3)
64
+ webmock (~> 1.8.7)
@@ -9,15 +9,7 @@ For more information on the REST calls, have a look at the whole Amazon E-Commer
9
9
 
10
10
  Have a look at the RDOC[http://rdoc.info/projects/phoet/asin] for this project, if you like browsing some docs.
11
11
 
12
- The gem runs smoothly with Rails 3 and is tested against these rubies:
13
-
14
- - 1.8.7
15
- - 1.9.2
16
- - rbx
17
- - rbx-2.0
18
- - ree
19
- - ruby-head
20
- - jruby
12
+ The gem runs smoothly with Rails 3 and is tested against multiple rubies. See +.travis.yml+ for details.
21
13
 
22
14
  == Installation
23
15
 
@@ -101,6 +93,9 @@ But you can also use the +instance+ method to get a proxy-object:
101
93
  # access the internal data representation (Hashie::Mash)
102
94
  item.raw.ItemAttributes.ListPrice.FormattedPrice
103
95
  => $39.99
96
+
97
+ # search for similar items like the one you already have
98
+ items = client.similar '1430218150'
104
99
 
105
100
  There is an additional set of methods to support AWS cart operations:
106
101
 
@@ -165,3 +160,10 @@ As a default HTTPI uses _httpclient_ so you should add that dependency to your p
165
160
 
166
161
  gem 'httpclient'
167
162
 
163
+
164
+ == License
165
+
166
+ "THE BEER-WARE LICENSE" (Revision 42):
167
+ ps@nofail.de[mailto:ps@nofail.de] wrote this file. As long as you retain this notice you
168
+ can do whatever you want with this stuff. If we meet some day, and you think
169
+ this stuff is worth it, you can buy me a beer in return Peter Schröder
@@ -19,18 +19,20 @@ Gem::Specification.new do |s|
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
20
  s.require_paths = ["lib"]
21
21
 
22
- s.add_dependency('crack', '~> 0.1')
23
- s.add_dependency('hashie', '~> 1.0')
24
- s.add_dependency('httpi', '~> 0.9')
22
+ s.add_dependency('crack', '~> 0.3')
23
+ s.add_dependency('hashie', '~> 1.1')
24
+ s.add_dependency('httpi', '~> 0.9')
25
+ s.add_dependency('confiture', '~> 0.1')
25
26
 
26
27
  s.add_runtime_dependency('jruby-openssl') if RUBY_PLATFORM == 'java'
27
28
 
28
- s.add_development_dependency('httpclient', '~> 2.2')
29
- s.add_development_dependency('rash', '~> 0.3')
30
-
31
- s.add_development_dependency('rake', '~> 0.9')
32
- s.add_development_dependency('vcr', '~> 1.10')
33
- s.add_development_dependency('webmock', '~> 1.6')
34
- s.add_development_dependency('rspec', '~> 2.6')
35
- s.add_development_dependency('fuubar', '~> 0.0')
29
+ s.add_development_dependency('httpclient', '~> 2.2.3')
30
+ s.add_development_dependency('rash', '~> 0.3.1')
31
+
32
+ s.add_development_dependency('rake', '~> 0.9.2.2')
33
+ s.add_development_dependency('vcr', '~> 1.11.3')
34
+ s.add_development_dependency('webmock', '~> 1.8.7')
35
+ s.add_development_dependency('rspec', '~> 2.7.0')
36
+ s.add_development_dependency('fuubar', '~> 0.0.5')
37
+ s.add_development_dependency('pry', '~> 0.9.9')
36
38
  end
@@ -179,7 +179,7 @@ module ASIN
179
179
 
180
180
  # Performs an +ItemSearch+ REST call against the Amazon API.
181
181
  #
182
- # Expects a Hash of search params where and returns a list of +SimpleItem+s:
182
+ # Expects a Hash of search params and returns a list of +SimpleItem+s:
183
183
  #
184
184
  # items = search :SearchIndex => :Music
185
185
  #
@@ -198,7 +198,7 @@ module ASIN
198
198
 
199
199
  # Performs an +BrowseNodeLookup+ REST call against the Amazon API.
200
200
  #
201
- # Expects a Hash of search params where and returns a +SimpleNode+:
201
+ # Expects a node-id and returns a +SimpleNode+:
202
202
  #
203
203
  # node = browse_node '163357'
204
204
  #
@@ -215,6 +215,26 @@ module ASIN
215
215
  handle_type(response['BrowseNodeLookupResponse']['BrowseNodes']['BrowseNode'], Configuration.node_type)
216
216
  end
217
217
 
218
+ # Performs an +SimilarityLookup+ REST call against the Amazon API.
219
+ #
220
+ # Expects one ore more asins and returns a list of +SimpleNode+s:
221
+ #
222
+ # node = browse_node '163357'
223
+ #
224
+ # ==== Options:
225
+ #
226
+ # Additional parameters for the API call like this:
227
+ #
228
+ # similar('1430218150', :SimilarityType => :Intersection, :ResponseGroup => :Small)
229
+ #
230
+ # Have a look at the optional config values on the Amazon-Documentation[http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/SimilarityLookup.html]
231
+ #
232
+ def similar(*asins)
233
+ params = asins.last.is_a?(Hash) ? asins.pop : {:SimilarityType => :Random, :ResponseGroup => :Medium}
234
+ response = call(params.merge(:Operation => :SimilarityLookup, :ItemId => asins.join(',')))
235
+ arrayfy(response['SimilarityLookupResponse']['Items']['Item']).map {|item| handle_item(item)}
236
+ end
237
+
218
238
  # Performs an +CartCreate+ REST call against the Amazon API.
219
239
  #
220
240
  # Expects one ore more item-hashes and returns a +SimpleCart+:
@@ -289,8 +309,8 @@ module ASIN
289
309
  cart(:CartClear, {:CartId => cart.cart_id, :HMAC => cart.hmac})
290
310
  end
291
311
 
292
- private()
293
-
312
+ private
313
+
294
314
  def arrayfy(item)
295
315
  return [] unless item
296
316
  item.is_a?(Array) ? item : [item]
@@ -339,7 +359,7 @@ module ASIN
339
359
  end
340
360
 
341
361
  def call(params)
342
- Configuration.validate_credentials!
362
+ Configuration.validate!
343
363
 
344
364
  log(:debug, "calling with params=#{params}")
345
365
  signed = create_signed_query_string(params)
@@ -371,7 +391,7 @@ module ASIN
371
391
  # utc timestamp needed for signing
372
392
  params[:Timestamp] = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ')
373
393
 
374
-
394
+
375
395
  query = create_query(params)
376
396
 
377
397
  # yeah, you really need to sign the get-request not the query
@@ -382,7 +402,7 @@ module ASIN
382
402
  signature = CGI.escape(Base64.encode64(hmac).chomp)
383
403
  "#{query}&Signature=#{signature}"
384
404
  end
385
-
405
+
386
406
  def create_query(params)
387
407
  params.map do |key, value|
388
408
  value = value.collect{|v| v.to_s.strip}.join(',') if value.is_a?(Array)
@@ -1,105 +1,57 @@
1
- require "yaml"
2
- require 'logger'
1
+ require "logger"
2
+ require "confiture"
3
3
 
4
4
  module ASIN
5
- class Configuration
6
- class << self
7
-
8
- attr_accessor :secret, :key, :host, :logger
9
- attr_accessor :item_type, :cart_type, :node_type
10
- attr_accessor :version, :associate_tag
11
-
12
- # Rails initializer configuration.
13
- #
14
- # Expects at least +secret+ and +key+ for the API call:
15
- #
16
- # ASIN::Configuration.configure do |config|
17
- # config.secret = 'your-secret'
18
- # config.key = 'your-key'
19
- # end
20
- #
21
- # With the latest version of the Product Advertising API you need to include your associate_tag[https://affiliate-program.amazon.com/gp/advertising/api/detail/api-changes.html].
22
- #
23
- # You may pass options as a hash as well:
24
- #
25
- # ASIN::Configuration.configure :secret => 'your-secret', :key => 'your-key'
26
- #
27
- # Or configure everything using YAML:
28
- #
29
- # ASIN::Configuration.configure :yaml => 'config/asin.yml'
30
- #
31
- # ASIN::Configuration.configure :yaml => 'config/asin.yml' do |config, yml|
32
- # config.key = yml[Rails.env]['aws_access_key']
33
- # end
34
- #
35
- # ==== Options:
36
- #
37
- # [secret] the API secret key (required)
38
- # [key] the API access key (required)
39
- # [associate_tag] your Amazon associate tag. Default is blank (required in latest API version)
40
- # [host] the host, which defaults to 'webservices.amazon.com'
41
- # [logger] a different logger than logging to STDERR (nil for no logging)
42
- # [version] a custom version of the API calls. Default is 2010-11-01
43
- # [item_type] a different class for SimpleItem, use :mash / :rash for Hashie::Mash / Hashie::Rash or :raw for a plain hash
44
- # [cart_type] a different class for SimpleCart, use :mash / :rash for Hashie::Mash / Hashie::Rash or :raw for a plain hash
45
- # [node_type] a different class for SimpleNode, use :mash / :rash for Hashie::Mash / Hashie::Rash or :raw for a plain hash
46
- #
47
- def configure(options={})
48
- init_config
49
- if yml_path = options[:yaml] || options[:yml]
50
- yml = File.open(yml_path) { |file| YAML.load(file) }
51
- if block_given?
52
- yield self, yml
53
- else
54
- yml.each do |key, value|
55
- send(:"#{key}=", value)
56
- end
57
- end
58
- elsif block_given?
59
- yield self
60
- else
61
- options.each do |key, value|
62
- send(:"#{key}=", value)
63
- end
64
- end
65
- self
66
- end
67
-
68
- # Checks if given credentials are valid and raises an error if not.
69
- #
70
- def validate_credentials!
71
- raise "you have to configure ASIN: 'configure :secret => 'your-secret', :key => 'your-key'" if blank?(:secret) || blank?(:key)
72
- [:host, :item_type, :cart_type, :node_type, :version, :associate_tag].each { |item| raise "nil is not a valid value for #{item}" unless self.send item }
73
- end
74
5
 
75
- # Resets configuration to defaults
76
- #
77
- def reset
78
- init_config(true)
79
- end
80
-
81
- # Check if a key is set
82
- #
83
- def blank?(key)
84
- val = self.send :key
85
- val.nil? || val.empty?
86
- end
87
-
88
- private()
89
-
90
- def init_config(force=false)
91
- return if @init && !force
92
- @init = true
93
- @secret = ''
94
- @key = ''
95
- @host = 'webservices.amazon.com'
96
- @logger = Logger.new(STDERR)
97
- @item_type = SimpleItem
98
- @cart_type = SimpleCart
99
- @node_type = SimpleNode
100
- @version = '2010-11-01'
101
- @associate_tag = ''
102
- end
103
- end
6
+ # Rails initializer configuration.
7
+ #
8
+ # Expects at least +secret+ and +key+ for the API call:
9
+ #
10
+ # ASIN::Configuration.configure do |config|
11
+ # config.secret = 'your-secret'
12
+ # config.key = 'your-key'
13
+ # end
14
+ #
15
+ # With the latest version of the Product Advertising API you need to include your associate_tag[https://affiliate-program.amazon.com/gp/advertising/api/detail/api-changes.html].
16
+ #
17
+ # You may pass options as a hash as well:
18
+ #
19
+ # ASIN::Configuration.configure :secret => 'your-secret', :key => 'your-key'
20
+ #
21
+ # Or configure everything using YAML:
22
+ #
23
+ # ASIN::Configuration.configure :yaml => 'config/asin.yml'
24
+ #
25
+ # ASIN::Configuration.configure :yaml => 'config/asin.yml' do |config, yml|
26
+ # config.key = yml[Rails.env]['aws_access_key']
27
+ # end
28
+ #
29
+ # ==== Options:
30
+ #
31
+ # [secret] the API secret key (required)
32
+ # [key] the API access key (required)
33
+ # [associate_tag] your Amazon associate tag. Default is blank (required in latest API version)
34
+ # [host] the host, which defaults to 'webservices.amazon.com'
35
+ # [logger] a different logger than logging to STDERR (nil for no logging)
36
+ # [version] a custom version of the API calls. Default is 2010-11-01
37
+ # [item_type] a different class for SimpleItem, use :mash / :rash for Hashie::Mash / Hashie::Rash or :raw for a plain hash
38
+ # [cart_type] a different class for SimpleCart, use :mash / :rash for Hashie::Mash / Hashie::Rash or :raw for a plain hash
39
+ # [node_type] a different class for SimpleNode, use :mash / :rash for Hashie::Mash / Hashie::Rash or :raw for a plain hash
40
+ #
41
+ class Configuration
42
+ include Confiture::Configuration
43
+ confiture_allowed_keys(:secret, :key, :host, :version, :associate_tag, :logger, :item_type, :cart_type, :node_type)
44
+ confiture_mandatory_keys(:secret, :key)
45
+ confiture_defaults({
46
+ :secret => '',
47
+ :key => '',
48
+ :host => 'webservices.amazon.com',
49
+ :version => '2010-11-01',
50
+ :associate_tag => '',
51
+ :logger => Logger.new(STDERR),
52
+ :item_type => SimpleItem,
53
+ :cart_type => SimpleCart,
54
+ :node_type => SimpleNode,
55
+ })
104
56
  end
105
57
  end
@@ -1,3 +1,3 @@
1
1
  module ASIN
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.0"
3
3
  end
@@ -1,6 +1,5 @@
1
1
  require "bundler"
2
- require "rake/rdoctask"
3
- require 'rspec/core/rake_task'
2
+ require "rspec/core/rake_task"
4
3
 
5
4
  Bundler::GemHelper.install_tasks
6
5
 
@@ -9,9 +8,4 @@ RSpec::Core::RakeTask.new do |t|
9
8
  t.pattern = 'spec/**/*_spec.rb'
10
9
  end
11
10
 
12
- Rake::RDocTask.new(:rdoc_dev) do |rd|
13
- rd.rdoc_files.include(File.readlines('.document').map(&:strip))
14
- rd.options + ['-a', '--line-numbers', '--charset=UTF-8']
15
- end
16
-
17
11
  task :default=>:spec