asin 0.5.0 → 0.5.1

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