asin 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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