asin 0.5.0 → 0.5.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.
@@ -3,6 +3,7 @@
3
3
  * move client to own file
4
4
  * use autoload
5
5
  * support for Hashie::Rash
6
+ * new method browse_node
6
7
 
7
8
  == 0.4.0
8
9
 
@@ -70,10 +70,6 @@ But you can also use the +instance+ method to get a proxy-object:
70
70
 
71
71
  There is an additional set of methods to support AWS cart operations:
72
72
 
73
- #just require
74
- require 'asin'
75
-
76
- # create an ASIN client
77
73
  client = ASIN::Client.instance
78
74
 
79
75
  # create a cart with an item
@@ -101,14 +97,26 @@ There is an additional set of methods to support AWS cart operations:
101
97
  cart.saved_items
102
98
  => [<#Hashie::Mash ASIN="1430218150" CartItemId="U3G241HVLLB8N6" ... >]
103
99
 
104
- == Item / Cart Response
100
+ It's also possible to access browse nodes:
101
+
102
+ client = ASIN::Client.instance
103
+
104
+ # create a cart with an item
105
+ node = client.browse_node('163357', :ResponseGroup => :TopSellers)
106
+ node.node_id
107
+ => '163357'
108
+ node.name
109
+ => 'Comedy'
110
+
111
+ == Response Configuration
105
112
 
106
113
  ASIN is customizable in the way it returns Responses from Amazon.
107
- By default it will return +SimpleItem+ or +SimpleCart+ instances,
114
+ By default it will return +SimpleItem+, +SimpleCart+ or +SimpleNode+ instances,
108
115
  but you can override this behavior for using your custom Classes:
109
116
 
110
117
  client.configure :item_type => YourItemClass
111
118
  client.configure :cart_type => YourCartClass
119
+ client.configure :node_type => YourNodeClass
112
120
 
113
121
  You can also use built-in +:raw+, +:mash+ or +:rash+ types.
114
122
  Since +rash+ is an additional library, you need to add it to your gemfile if you want to use it:
@@ -1,7 +1,8 @@
1
1
  module ASIN
2
- end
3
- ASIN.autoload :Client, 'asin/client'
4
- ASIN.autoload :SimpleItem, 'asin/simple_item'
5
- ASIN.autoload :SimpleCart, 'asin/simple_cart'
6
- ASIN.autoload :Version, 'asin/version'
7
- ASIN.autoload :Configuration, 'asin/configuration'
2
+ autoload :Client, 'asin/client'
3
+ autoload :SimpleItem, 'asin/simple_item'
4
+ autoload :SimpleCart, 'asin/simple_cart'
5
+ autoload :SimpleNode, 'asin/simple_node'
6
+ autoload :Version, 'asin/version'
7
+ autoload :Configuration, 'asin/configuration'
8
+ end
@@ -47,7 +47,7 @@ require 'base64'
47
47
  # == Further Configuration
48
48
  #
49
49
  # If you need more controll over the request that is sent to the
50
- # Amazon API (http://docs.amazonwebservices.com/AWSEcommerceService/4-0/),
50
+ # Amazon API (http://docs.amazonwebservices.com/AWSECommerceService/2010-11-01/DG/),
51
51
  # you can override some defaults or add additional query-parameters to the REST calls:
52
52
  #
53
53
  # configure :host => 'webservices.amazon.de'
@@ -82,6 +82,22 @@ require 'base64'
82
82
  # => true
83
83
  # => [<#Hashie::Mash ASIN="1430218150" CartItemId="U3G241HVLLB8N6" ... >]
84
84
  #
85
+ # == Nodes
86
+ #
87
+ # In order to browse Amazon nodes, you can use +browse_node+ method:
88
+ #
89
+ # node = browse_node('163357')
90
+ # node.node_id
91
+ # => '163357'
92
+ # node.name
93
+ # => 'Comedy'
94
+ # node.children
95
+ # node.ancestors
96
+ #
97
+ # you can configure the +:ResponseGroup+ option to your needs:
98
+ #
99
+ # node = browse_node('163357', :ResponseGroup => :TopSellers)
100
+ #
85
101
  module ASIN
86
102
  module Client
87
103
 
@@ -143,12 +159,12 @@ module ASIN
143
159
  #
144
160
  # search_keywords('nirvana', 'never mind', :SearchIndex => :Music)
145
161
  #
146
- # Have a look at the different search index values on the Amazon-Documentation[http://docs.amazonwebservices.com/AWSEcommerceService/4-0/]
162
+ # Have a look at the different search index values on the Amazon-Documentation[http://docs.amazonwebservices.com/AWSECommerceService/2010-11-01/DG/]
147
163
  #
148
164
  def search_keywords(*keywords)
149
165
  params = keywords.last.is_a?(Hash) ? keywords.pop : {:SearchIndex => :Books, :ResponseGroup => :Medium}
150
166
  response = call(params.merge(:Operation => :ItemSearch, :Keywords => keywords.join(' ')))
151
- (response['ItemSearchResponse']['Items']['Item'] || []).map {|item| handle_item(item)}
167
+ arrayfy(response['ItemSearchResponse']['Items']['Item']).map {|item| handle_item(item)}
152
168
  end
153
169
 
154
170
  # Performs an +ItemSearch+ REST call against the Amazon API.
@@ -163,11 +179,30 @@ module ASIN
163
179
  #
164
180
  # search(:Keywords => 'nirvana', :SearchIndex => :Music)
165
181
  #
166
- # Have a look at the different search index values on the Amazon-Documentation[http://docs.amazonwebservices.com/AWSEcommerceService/4-0/]
182
+ # Have a look at the different search index values on the Amazon-Documentation[http://docs.amazonwebservices.com/AWSECommerceService/2010-11-01/DG/]
167
183
  #
168
184
  def search(params={:SearchIndex => :Books, :ResponseGroup => :Medium})
169
185
  response = call(params.merge(:Operation => :ItemSearch))
170
- (response['ItemSearchResponse']['Items']['Item'] || []).map {|item| handle_item(item)}
186
+ arrayfy(response['ItemSearchResponse']['Items']['Item']).map {|item| handle_item(item)}
187
+ end
188
+
189
+ # Performs an +BrowseNodeLookup+ REST call against the Amazon API.
190
+ #
191
+ # Expects a Hash of search params where and returns a +SimpleNode+:
192
+ #
193
+ # node = browse_node '163357'
194
+ #
195
+ # ==== Options:
196
+ #
197
+ # Additional parameters for the API call like this:
198
+ #
199
+ # browse_node('163357', :ResponseGroup => :TopSellers)
200
+ #
201
+ # Have a look at the different browse node values on the Amazon-Documentation[http://docs.amazonwebservices.com/AWSECommerceService/2010-11-01/DG/]
202
+ #
203
+ def browse_node(node_id, params={:ResponseGroup => :BrowseNodeInfo})
204
+ response = call(params.merge(:Operation => :BrowseNodeLookup, :BrowseNodeId => node_id))
205
+ handle_type(response['BrowseNodeLookupResponse']['BrowseNodes']['BrowseNode'], Configuration.node_type)
171
206
  end
172
207
 
173
208
  # Performs an +CartCreate+ REST call against the Amazon API.
@@ -182,7 +217,7 @@ module ASIN
182
217
  #
183
218
  # create_cart({:asin => '1430218150', :quantity => 1}, {:asin => '1430216263', :quantity => 1, :action => :SaveForLater})
184
219
  #
185
- # Have a look at the different cart item operation values on the Amazon-Documentation[http://docs.amazonwebservices.com/AWSEcommerceService/4-0/]
220
+ # Have a look at the different cart item operation values on the Amazon-Documentation[http://docs.amazonwebservices.com/AWSECommerceService/2010-11-01/DG/]
186
221
  #
187
222
  def create_cart(*items)
188
223
  cart(:CartCreate, create_item_params(items))
@@ -210,7 +245,7 @@ module ASIN
210
245
  #
211
246
  # add_items(cart, {:asin => '1430218150', :quantity => 1}, {:asin => '1430216263', :quantity => 1, :action => :SaveForLater})
212
247
  #
213
- # Have a look at the different cart item operation values on the Amazon-Documentation[http://docs.amazonwebservices.com/AWSEcommerceService/4-0/]
248
+ # Have a look at the different cart item operation values on the Amazon-Documentation[http://docs.amazonwebservices.com/AWSECommerceService/2010-11-01/DG/]
214
249
  #
215
250
  def add_items(cart, *items)
216
251
  cart(:CartAdd, create_item_params(items).merge({:CartId => cart.cart_id, :HMAC => cart.hmac}))
@@ -228,7 +263,7 @@ module ASIN
228
263
  #
229
264
  # update_items(cart, {:cart_item_id => cart.items.first.CartItemId, :action => :SaveForLater}, {:cart_item_id => cart.items.first.CartItemId, :quantity => 7})
230
265
  #
231
- # Have a look at the different cart item operation values on the Amazon-Documentation[http://docs.amazonwebservices.com/AWSEcommerceService/4-0/]
266
+ # Have a look at the different cart item operation values on the Amazon-Documentation[http://docs.amazonwebservices.com/AWSECommerceService/2010-11-01/DG/]
232
267
  #
233
268
  def update_items(cart, *items)
234
269
  cart(:CartModify, create_item_params(items).merge({:CartId => cart.cart_id, :HMAC => cart.hmac}))
@@ -245,6 +280,11 @@ module ASIN
245
280
  end
246
281
 
247
282
  private()
283
+
284
+ def arrayfy(item)
285
+ return [] unless item
286
+ item.is_a?(Array) ? item : [item]
287
+ end
248
288
 
249
289
  def handle_item(item)
250
290
  handle_type(item, Configuration.item_type)
@@ -319,6 +359,10 @@ module ASIN
319
359
  # nice tutorial http://cloudcarpenters.com/blog/amazon_products_api_request_signing/
320
360
  params[:Service] = :AWSECommerceService
321
361
  params[:AWSAccessKeyId] = Configuration.key
362
+
363
+ params[:Version] = Configuration.version unless Configuration.version.empty?
364
+ params[:AssociateTag] = Configuration.associate_tag unless Configuration.associate_tag.empty?
365
+
322
366
  # utc timestamp needed for signing
323
367
  params[:Timestamp] = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ')
324
368
 
@@ -6,7 +6,8 @@ module ASIN
6
6
  class << self
7
7
 
8
8
  attr_accessor :secret, :key, :host, :logger
9
- attr_accessor :item_type, :cart_type
9
+ attr_accessor :item_type, :cart_type, :node_type
10
+ attr_accessor :version, :associate_tag
10
11
 
11
12
  # Rails initializer configuration.
12
13
  #
@@ -37,6 +38,9 @@ module ASIN
37
38
  # [logger] a different logger than logging to STDERR (nil for no logging)
38
39
  # [item_type] a different class for SimpleItem, use :mash / :rash for Hashie::Mash / Hashie::Rash or :raw for a plain hash
39
40
  # [cart_type] a different class for SimpleCart, use :mash / :rash for Hashie::Mash / Hashie::Rash or :raw for a plain hash
41
+ # [node_type] a different class for SimpleNode, use :mash / :rash for Hashie::Mash / Hashie::Rash or :raw for a plain hash
42
+ # [version] a custom version of the API calls. Default is 2010-11-01
43
+ # [associate_tag] your Amazon associate tag. Default is blank.
40
44
  #
41
45
  def configure(options={})
42
46
  init_config
@@ -69,13 +73,16 @@ module ASIN
69
73
 
70
74
  def init_config(force=false)
71
75
  return if @init && !force
72
- @init = true
73
- @secret = ''
74
- @key = ''
75
- @host = 'webservices.amazon.com'
76
- @logger = Logger.new(STDERR)
77
- @item_type = SimpleItem
78
- @cart_type = SimpleCart
76
+ @init = true
77
+ @secret = ''
78
+ @key = ''
79
+ @host = 'webservices.amazon.com'
80
+ @logger = Logger.new(STDERR)
81
+ @item_type = SimpleItem
82
+ @cart_type = SimpleCart
83
+ @node_type = SimpleNode
84
+ @version = '2010-11-01'
85
+ @associate_tag = ''
79
86
  end
80
87
  end
81
88
  end
@@ -0,0 +1,44 @@
1
+ require 'hashie'
2
+
3
+ module ASIN
4
+
5
+ # =SimpleNode
6
+ #
7
+ # The +SimpleNode+ class is a wrapper for the Amazon XML-REST-Response.
8
+ #
9
+ # A Hashie::Mash is used for the internal data representation and can be accessed over the +raw+ attribute.
10
+ #
11
+ class SimpleNode
12
+
13
+ attr_reader :raw
14
+
15
+ def initialize(hash)
16
+ @raw = Hashie::Mash.new(hash)
17
+ end
18
+
19
+ def name
20
+ @raw.Name
21
+ end
22
+
23
+ def node_id
24
+ @raw.BrowseNodeId
25
+ end
26
+
27
+ def children
28
+ return [] unless @raw.Children
29
+ @raw.Children.BrowseNode.is_a?(Array) ? @raw.Children.BrowseNode : [@raw.Children.BrowseNode]
30
+ end
31
+
32
+ def ancestors
33
+ return [] unless @raw.Ancestors
34
+ @raw.Ancestors.BrowseNode.is_a?(Array) ? @raw.Ancestors.BrowseNode : [@raw.Ancestors.BrowseNode]
35
+ end
36
+
37
+ def top_item_set
38
+ return [] unless @raw.TopItemSet
39
+ @raw.TopItemSet.TopItem.is_a?(Array) ? @raw.TopItemSet.TopItem : [@raw.TopItemSet.TopItem]
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -1,3 +1,3 @@
1
1
  module ASIN
2
- VERSION = "0.5.0"
2
+ VERSION = "0.5.1"
3
3
  end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ module ASIN
4
+ describe ASIN do
5
+ before do
6
+ ASIN::Configuration.reset
7
+ @helper = ASIN::Client.instance
8
+ @helper.configure :logger => nil
9
+
10
+ @secret = ENV['ASIN_SECRET']
11
+ @key = ENV['ASIN_KEY']
12
+ puts "configure #{@secret} and #{@key} for this test"
13
+ end
14
+
15
+ context "lookup and search" do
16
+ before do
17
+ @helper.configure :secret => @secret, :key => @key
18
+ end
19
+
20
+ it "should lookup a book" do
21
+ item = @helper.browse_node(ANY_BROWSE_NODE_ID)
22
+ item.node_id.should eql(ANY_BROWSE_NODE_ID)
23
+ item.name.should eql('Comedy')
24
+ end
25
+ end
26
+ end
27
+ end
@@ -2,7 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  module ASIN
4
4
  describe ASIN do
5
-
6
5
  before do
7
6
  ASIN::Configuration.reset
8
7
  @helper = ASIN::Client.instance
@@ -17,7 +16,7 @@ module ASIN
17
16
  context "cart" do
18
17
 
19
18
  it "should create a cart" do
20
- cart = @helper.create_cart({:asin => ANY_ASIN, :quantity => 1}, {:asin => OTHER_ASIN, :quantity => 2})
19
+ cart = @helper.create_cart({:asin => ANY_ASIN, :quantity => 1}, {:asin => ANY_OTHER_ASIN, :quantity => 2})
21
20
  cart.valid?.should be(true)
22
21
  cart.empty?.should be(false)
23
22
  end
@@ -47,7 +46,7 @@ module ASIN
47
46
  end
48
47
 
49
48
  it "should add items to a cart" do
50
- cart = @helper.add_items(@cart, {:asin => OTHER_ASIN, :quantity => 2})
49
+ cart = @helper.add_items(@cart, {:asin => ANY_OTHER_ASIN, :quantity => 2})
51
50
  cart.valid?.should be(true)
52
51
  cart.empty?.should be(false)
53
52
  cart.items.should have(2).things
@@ -103,7 +103,12 @@ module ASIN
103
103
  @helper.lookup(ANY_ASIN).item_attributes.title.should_not be_nil
104
104
  end
105
105
 
106
- it "should search_keywords a book with fulltext" do
106
+ it "should search_keywords and handle a single result" do
107
+ items = @helper.search_keywords('0471317519')
108
+ items.first.title.should =~ /A Self-Teaching Guide/
109
+ end
110
+
111
+ it "should search_keywords book with fulltext" do
107
112
  items = @helper.search_keywords 'Learn', 'Objective-C'
108
113
  items.should have(10).things
109
114
 
@@ -112,7 +117,7 @@ module ASIN
112
117
 
113
118
  it "should search_keywords never mind music" do
114
119
  items = @helper.search_keywords 'nirvana', 'never mind', :SearchIndex => :Music
115
- items.should have(9).things
120
+ items.should have(10).things
116
121
 
117
122
  items.first.title.should =~ /Nevermind/
118
123
  end
@@ -3,8 +3,9 @@ require 'rspec'
3
3
  require 'asin'
4
4
  require 'pp'
5
5
 
6
- ANY_ASIN = '1430218150'
7
- OTHER_ASIN = '1430216263'
6
+ ANY_ASIN = '1430218150'
7
+ ANY_OTHER_ASIN = '1430216263'
8
+ ANY_BROWSE_NODE_ID = '599826'
8
9
 
9
10
  RSpec.configure do |c|
10
11
  c.mock_with :rspec
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-07-07 00:00:00.000000000 +02:00
12
+ date: 2011-08-03 00:00:00.000000000 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: crack
17
- requirement: &2153571760 !ruby/object:Gem::Requirement
17
+ requirement: &2153681520 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 0.1.8
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *2153571760
25
+ version_requirements: *2153681520
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: hashie
28
- requirement: &2153571260 !ruby/object:Gem::Requirement
28
+ requirement: &2153681020 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ~>
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 1.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *2153571260
36
+ version_requirements: *2153681020
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: httpi
39
- requirement: &2153570800 !ruby/object:Gem::Requirement
39
+ requirement: &2153680560 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: 0.9.2
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *2153570800
47
+ version_requirements: *2153680560
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: httpclient
50
- requirement: &2153570340 !ruby/object:Gem::Requirement
50
+ requirement: &2153680100 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ~>
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: 2.2.0.2
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *2153570340
58
+ version_requirements: *2153680100
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: rash
61
- requirement: &2168479800 !ruby/object:Gem::Requirement
61
+ requirement: &2153679640 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ~>
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: 0.3.0
67
67
  type: :development
68
68
  prerelease: false
69
- version_requirements: *2168479800
69
+ version_requirements: *2153679640
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: rspec
72
- requirement: &2168479340 !ruby/object:Gem::Requirement
72
+ requirement: &2153679180 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ~>
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: 2.6.0
78
78
  type: :development
79
79
  prerelease: false
80
- version_requirements: *2168479340
80
+ version_requirements: *2153679180
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: fuubar
83
- requirement: &2168478880 !ruby/object:Gem::Requirement
83
+ requirement: &2153678720 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ~>
@@ -88,7 +88,7 @@ dependencies:
88
88
  version: 0.0.4
89
89
  type: :development
90
90
  prerelease: false
91
- version_requirements: *2168478880
91
+ version_requirements: *2153678720
92
92
  description: Amazon Simple INterface.
93
93
  email:
94
94
  - phoetmail@googlemail.com
@@ -109,9 +109,11 @@ files:
109
109
  - lib/asin/configuration.rb
110
110
  - lib/asin/simple_cart.rb
111
111
  - lib/asin/simple_item.rb
112
+ - lib/asin/simple_node.rb
112
113
  - lib/asin/version.rb
113
114
  - rakefile.rb
114
115
  - spec/asin.yml
116
+ - spec/browse_node_spec.rb
115
117
  - spec/cart_spec.rb
116
118
  - spec/search_spec.rb
117
119
  - spec/spec_helper.rb
@@ -142,6 +144,7 @@ specification_version: 3
142
144
  summary: Simple interface to AWS Lookup, Search and Cart operations.
143
145
  test_files:
144
146
  - spec/asin.yml
147
+ - spec/browse_node_spec.rb
145
148
  - spec/cart_spec.rb
146
149
  - spec/search_spec.rb
147
150
  - spec/spec_helper.rb