vacuum 0.1.3 → 0.2.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +69 -27
- data/lib/vacuum/endpoint/base.rb +58 -0
- data/lib/vacuum/endpoint/mws.rb +59 -0
- data/lib/vacuum/endpoint/product_advertising.rb +34 -0
- data/lib/vacuum/mws.rb +8 -0
- data/lib/vacuum/product_advertising.rb +7 -0
- data/lib/vacuum/request/base.rb +96 -0
- data/lib/vacuum/request/mws.rb +24 -0
- data/lib/vacuum/request/product_advertising.rb +90 -0
- data/lib/vacuum/request/signature/authentication.rb +32 -0
- data/lib/vacuum/request/signature/builder.rb +70 -0
- data/lib/vacuum/request/utils.rb +24 -0
- data/lib/vacuum/response/base.rb +57 -0
- data/lib/vacuum/response/mws.rb +7 -0
- data/lib/vacuum/response/product_advertising.rb +19 -0
- data/lib/vacuum/response/utils.rb +48 -0
- data/lib/vacuum/version.rb +1 -1
- data/lib/vacuum.rb +31 -11
- data/spec/fixtures/{http_response → product_advertising} +0 -0
- data/spec/spec_helper.rb +5 -4
- data/spec/support/shared_examples/endpoint.rb +43 -0
- data/spec/support/shared_examples/request.rb +95 -0
- data/spec/support/shared_examples/response.rb +51 -0
- data/spec/vacuum/endpoint/base_spec.rb +19 -0
- data/spec/vacuum/endpoint/mws_spec.rb +47 -0
- data/spec/vacuum/endpoint/product_advertising_spec.rb +25 -0
- data/spec/vacuum/request/base_spec.rb +22 -0
- data/spec/vacuum/request/mws_spec.rb +26 -0
- data/spec/vacuum/request/product_advertising_spec.rb +104 -0
- data/spec/vacuum/request/signature/authentication_spec.rb +30 -0
- data/spec/vacuum/request/signature/builder_spec.rb +76 -0
- data/spec/vacuum/request/utils_spec.rb +23 -0
- data/spec/vacuum/response/base_spec.rb +38 -0
- data/spec/vacuum/response/product_advertising_spec.rb +57 -0
- data/spec/vacuum/response/utils_spec.rb +42 -0
- metadata +107 -21
- data/lib/vacuum/em.rb +0 -21
- data/lib/vacuum/request.rb +0 -119
- data/lib/vacuum/response.rb +0 -63
- data/spec/vacuum/request_spec.rb +0 -130
- data/spec/vacuum/response_spec.rb +0 -80
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Vacuum
|
4
|
+
module Request
|
5
|
+
module Signature
|
6
|
+
describe Builder do
|
7
|
+
let :url do
|
8
|
+
Addressable::URI.parse 'http://example.com/foo?bar=1'
|
9
|
+
end
|
10
|
+
|
11
|
+
let :builder do
|
12
|
+
described_class.new env, 'secret'
|
13
|
+
end
|
14
|
+
|
15
|
+
let :env do
|
16
|
+
{ :method => :get, :url => url }
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#method' do
|
20
|
+
it 'returns an HTTP method' do
|
21
|
+
builder.method.should eql 'GET'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#sign' do
|
26
|
+
it 'signs the request' do
|
27
|
+
builder.sign
|
28
|
+
builder.url.query.should include 'Signature='
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#signature' do
|
33
|
+
after do
|
34
|
+
builder.signature
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'generates an HMAC-SHA signature' do
|
38
|
+
OpenSSL::HMAC.should_receive(:digest).and_return 'secret'
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'base64-encodes generated signature' do
|
42
|
+
Base64.should_receive(:encode64).and_return 'a string'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#sort_query' do
|
47
|
+
it 'sorts query values' do
|
48
|
+
url.query = 'baz=0&bar=1'
|
49
|
+
builder.sort_query
|
50
|
+
builder.url.query.should eql 'bar=1&baz=0'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#string_to_sign' do
|
55
|
+
it 'concatenates the request method, host, path, and query' do
|
56
|
+
expected_string = %w(GET example.com /foo bar=1).join "\n"
|
57
|
+
builder.string_to_sign.should eql expected_string
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#timestamp' do
|
62
|
+
it 'timestamps the request' do
|
63
|
+
builder.timestamp
|
64
|
+
builder.url.query.should include 'Timestamp='
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#url' do
|
69
|
+
it 'returns the request URL' do
|
70
|
+
builder.url.should be_an Addressable::URI
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Vacuum
|
4
|
+
module Request
|
5
|
+
describe Utils do
|
6
|
+
describe '.camelize' do
|
7
|
+
it 'camelizes an underscored String' do
|
8
|
+
Utils.camelize('foo_bar').should eql 'FooBar'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.encode' do
|
13
|
+
it 'encodes reserved characters' do
|
14
|
+
Utils.encode(',').should eql '%2C'
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'does not encode unreserved characters' do
|
18
|
+
Utils.encode('~').should eql '~'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Vacuum
|
4
|
+
module Response
|
5
|
+
describe Base do
|
6
|
+
let(:body) do
|
7
|
+
'<?xml version="1.0" ?>
|
8
|
+
<children>
|
9
|
+
<child>
|
10
|
+
<name>foo</name>
|
11
|
+
</child>
|
12
|
+
<child>
|
13
|
+
<name>bar</name>
|
14
|
+
</child>
|
15
|
+
</children>'.gsub />\s+</, '><'
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:response) do
|
19
|
+
described_class.new body, '200'
|
20
|
+
end
|
21
|
+
|
22
|
+
it_behaves_like 'a response'
|
23
|
+
|
24
|
+
describe '#find' do
|
25
|
+
it 'returns an array of matches' do
|
26
|
+
response.find('child').should_not be_empty
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'yields matches to a block' do
|
30
|
+
names = response.find('child') do |child|
|
31
|
+
child['name']
|
32
|
+
end
|
33
|
+
names.should =~ %w(foo bar)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Vacuum
|
4
|
+
module Response
|
5
|
+
describe ProductAdvertising do
|
6
|
+
let(:response) do
|
7
|
+
path = File.expand_path('../../../fixtures/product_advertising', __FILE__)
|
8
|
+
body = File.read path
|
9
|
+
|
10
|
+
described_class.new body, '200'
|
11
|
+
end
|
12
|
+
|
13
|
+
it_behaves_like 'a response'
|
14
|
+
|
15
|
+
context 'when Amazon returns errors' do
|
16
|
+
before do
|
17
|
+
response.body = <<-EOF.gsub!(/>\s+</, '><').strip!
|
18
|
+
<?xml version=\"1.0\" ?>
|
19
|
+
<Response xmlns="http://example.com">
|
20
|
+
<Errors>
|
21
|
+
<Error>foo</Error>
|
22
|
+
</Errors>
|
23
|
+
</Response>
|
24
|
+
EOF
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#errors' do
|
28
|
+
it 'returns an Array of errors' do
|
29
|
+
response.errors.should =~ ['foo']
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#has_errors?' do
|
35
|
+
context 'when response does not contain any errors' do
|
36
|
+
before do
|
37
|
+
response.stub!(:errors).and_return([])
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'returns false' do
|
41
|
+
response.should_not have_errors
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when response contains errors' do
|
46
|
+
before do
|
47
|
+
response.stub!(:errors).and_return([1])
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'returns true' do
|
51
|
+
response.should have_errors
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Vacuum
|
4
|
+
module Response
|
5
|
+
describe Utils do
|
6
|
+
describe '.xml_to_hash' do
|
7
|
+
let(:hash) do
|
8
|
+
str = <<-XML.gsub!(/>\s+</, '><').strip!
|
9
|
+
<?xml version=\"1.0\" ?>
|
10
|
+
<ItemAttributes>
|
11
|
+
<Title>Anti-Oedipus</Title>
|
12
|
+
<Author>Gilles Deleuze</Author>
|
13
|
+
<Author>Felix Guattari</Author>
|
14
|
+
<Creator Role="Translator">Robert Hurley</Creator>
|
15
|
+
</ItemAttributes>
|
16
|
+
XML
|
17
|
+
xml = Nokogiri::XML.parse str
|
18
|
+
|
19
|
+
Utils.xml_to_hash xml
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns a hash' do
|
23
|
+
hash.should be_an_instance_of Hash
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'handles only childs' do
|
27
|
+
hash['Title'].should eql 'Anti-Oedipus'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'handles arrays' do
|
31
|
+
hash['Author'].should be_a Array
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'handles attributes' do
|
35
|
+
node = hash['Creator']
|
36
|
+
node['Role'].should eql 'Translator'
|
37
|
+
node['__content__'].should eql 'Robert Hurley'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
metadata
CHANGED
@@ -1,46 +1,119 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vacuum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.0.pre
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Hakan Ensari
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
16
|
-
requirement: &
|
15
|
+
name: rake
|
16
|
+
requirement: &70296598618460 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: '
|
21
|
+
version: '0.9'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70296598618460
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &70296598617960 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.9'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70296598617960
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: addressable
|
38
|
+
requirement: &70296598617500 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '2.2'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70296598617500
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: faraday
|
49
|
+
requirement: &70296598617040 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.7.6
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70296598617040
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: nokogiri
|
60
|
+
requirement: &70296598616580 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '1.5'
|
22
66
|
type: :runtime
|
23
67
|
prerelease: false
|
24
|
-
version_requirements: *
|
25
|
-
description: Vacuum is a
|
68
|
+
version_requirements: *70296598616580
|
69
|
+
description: ! 'Vacuum is a wrapper to various Amazon Web Services (AWS) APIs, including
|
70
|
+
|
71
|
+
Product Advertising and Marketplace Web Services (MWS).
|
72
|
+
|
73
|
+
'
|
26
74
|
email:
|
27
75
|
- hakan.ensari@papercavalier.com
|
28
76
|
executables: []
|
29
77
|
extensions: []
|
30
78
|
extra_rdoc_files: []
|
31
79
|
files:
|
32
|
-
- lib/vacuum/
|
33
|
-
- lib/vacuum/
|
34
|
-
- lib/vacuum/
|
80
|
+
- lib/vacuum/endpoint/base.rb
|
81
|
+
- lib/vacuum/endpoint/mws.rb
|
82
|
+
- lib/vacuum/endpoint/product_advertising.rb
|
83
|
+
- lib/vacuum/mws.rb
|
84
|
+
- lib/vacuum/product_advertising.rb
|
85
|
+
- lib/vacuum/request/base.rb
|
86
|
+
- lib/vacuum/request/mws.rb
|
87
|
+
- lib/vacuum/request/product_advertising.rb
|
88
|
+
- lib/vacuum/request/signature/authentication.rb
|
89
|
+
- lib/vacuum/request/signature/builder.rb
|
90
|
+
- lib/vacuum/request/utils.rb
|
91
|
+
- lib/vacuum/response/base.rb
|
92
|
+
- lib/vacuum/response/mws.rb
|
93
|
+
- lib/vacuum/response/product_advertising.rb
|
94
|
+
- lib/vacuum/response/utils.rb
|
35
95
|
- lib/vacuum/version.rb
|
36
96
|
- lib/vacuum.rb
|
37
97
|
- LICENSE
|
38
98
|
- README.md
|
39
|
-
- spec/fixtures/
|
99
|
+
- spec/fixtures/product_advertising
|
40
100
|
- spec/spec_helper.rb
|
41
|
-
- spec/
|
42
|
-
- spec/
|
43
|
-
|
101
|
+
- spec/support/shared_examples/endpoint.rb
|
102
|
+
- spec/support/shared_examples/request.rb
|
103
|
+
- spec/support/shared_examples/response.rb
|
104
|
+
- spec/vacuum/endpoint/base_spec.rb
|
105
|
+
- spec/vacuum/endpoint/mws_spec.rb
|
106
|
+
- spec/vacuum/endpoint/product_advertising_spec.rb
|
107
|
+
- spec/vacuum/request/base_spec.rb
|
108
|
+
- spec/vacuum/request/mws_spec.rb
|
109
|
+
- spec/vacuum/request/product_advertising_spec.rb
|
110
|
+
- spec/vacuum/request/signature/authentication_spec.rb
|
111
|
+
- spec/vacuum/request/signature/builder_spec.rb
|
112
|
+
- spec/vacuum/request/utils_spec.rb
|
113
|
+
- spec/vacuum/response/base_spec.rb
|
114
|
+
- spec/vacuum/response/product_advertising_spec.rb
|
115
|
+
- spec/vacuum/response/utils_spec.rb
|
116
|
+
homepage: https://github.com/hakanensari/vacuum
|
44
117
|
licenses: []
|
45
118
|
post_install_message:
|
46
119
|
rdoc_options: []
|
@@ -55,17 +128,30 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
55
128
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
129
|
none: false
|
57
130
|
requirements:
|
58
|
-
- - ! '
|
131
|
+
- - ! '>'
|
59
132
|
- !ruby/object:Gem::Version
|
60
|
-
version:
|
133
|
+
version: 1.3.1
|
61
134
|
requirements: []
|
62
135
|
rubyforge_project:
|
63
136
|
rubygems_version: 1.8.11
|
64
137
|
signing_key:
|
65
138
|
specification_version: 3
|
66
|
-
summary: A
|
139
|
+
summary: A wrapper to various Amazon Web Services APIs
|
67
140
|
test_files:
|
68
|
-
- spec/fixtures/
|
141
|
+
- spec/fixtures/product_advertising
|
69
142
|
- spec/spec_helper.rb
|
70
|
-
- spec/
|
71
|
-
- spec/
|
143
|
+
- spec/support/shared_examples/endpoint.rb
|
144
|
+
- spec/support/shared_examples/request.rb
|
145
|
+
- spec/support/shared_examples/response.rb
|
146
|
+
- spec/vacuum/endpoint/base_spec.rb
|
147
|
+
- spec/vacuum/endpoint/mws_spec.rb
|
148
|
+
- spec/vacuum/endpoint/product_advertising_spec.rb
|
149
|
+
- spec/vacuum/request/base_spec.rb
|
150
|
+
- spec/vacuum/request/mws_spec.rb
|
151
|
+
- spec/vacuum/request/product_advertising_spec.rb
|
152
|
+
- spec/vacuum/request/signature/authentication_spec.rb
|
153
|
+
- spec/vacuum/request/signature/builder_spec.rb
|
154
|
+
- spec/vacuum/request/utils_spec.rb
|
155
|
+
- spec/vacuum/response/base_spec.rb
|
156
|
+
- spec/vacuum/response/product_advertising_spec.rb
|
157
|
+
- spec/vacuum/response/utils_spec.rb
|
data/lib/vacuum/em.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'vacuum'
|
2
|
-
require 'em-http-request'
|
3
|
-
|
4
|
-
module Vacuum
|
5
|
-
class Request
|
6
|
-
# Performs an async request.
|
7
|
-
#
|
8
|
-
# @param err [Proc] A callback to be executed if request fails
|
9
|
-
# @yield Passes response to given block
|
10
|
-
def aget(err = nil, &blk)
|
11
|
-
http = EM::HttpRequest.new(url).get
|
12
|
-
# @todo Consider using a SAX parser that can work on the chunks as they
|
13
|
-
# come in?
|
14
|
-
# http.stream { |chunk| parse chunk }
|
15
|
-
http.callback do
|
16
|
-
yield Response.new http.response, http.response_header.status
|
17
|
-
end
|
18
|
-
http.errback &err if err
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
data/lib/vacuum/request.rb
DELETED
@@ -1,119 +0,0 @@
|
|
1
|
-
module Vacuum
|
2
|
-
# A wrapper around the request to the Amazon Product Advertising API.
|
3
|
-
class Request
|
4
|
-
# The latest Amazon API version.
|
5
|
-
CURRENT_API_VERSION = '2011-08-01'
|
6
|
-
|
7
|
-
# A list of Amazon endpoints.
|
8
|
-
HOSTS = {
|
9
|
-
:ca => 'ecs.amazonaws.ca',
|
10
|
-
:cn => 'webservices.amazon.cn',
|
11
|
-
:de => 'ecs.amazonaws.de',
|
12
|
-
:es => 'webservices.amazon.es',
|
13
|
-
:fr => 'ecs.amazonaws.fr',
|
14
|
-
:it => 'webservices.amazon.it',
|
15
|
-
:jp => 'ecs.amazonaws.jp',
|
16
|
-
:uk => 'ecs.amazonaws.co.uk',
|
17
|
-
:us => 'ecs.amazonaws.com'
|
18
|
-
}
|
19
|
-
|
20
|
-
# Creates a new request for given locale and credentials.
|
21
|
-
#
|
22
|
-
# @param [Hash] options
|
23
|
-
# @option opts [#to_sym] :locale An Amazon locale
|
24
|
-
# @option opts [String] :key An Amazon AWS access key ID
|
25
|
-
# @option opts [String] :secret An Amazon AWS access secret key
|
26
|
-
# @option opts [String] :tag An Amazon Associate tag
|
27
|
-
# @raise [MissingKey] An Amazon AWS access key ID was not given
|
28
|
-
# @raise [MissingSecret] An Amazon AWS secret key was not given
|
29
|
-
# @raise [MissingTag] An Amazon Associate tag was not given
|
30
|
-
# @return [self]
|
31
|
-
def initialize(options)
|
32
|
-
_reset!
|
33
|
-
|
34
|
-
locale = (options[:locale] || :us).to_sym
|
35
|
-
@host = HOSTS[locale] or raise BadLocale
|
36
|
-
@key = options[:key] or raise MissingKey
|
37
|
-
@secret = options[:secret] or raise MissingSecret
|
38
|
-
@tag = options[:tag] or raise MissingTag
|
39
|
-
end
|
40
|
-
|
41
|
-
# Merges given parameters into the request query.
|
42
|
-
#
|
43
|
-
# @param [Hash] hsh Pairs of keys and values
|
44
|
-
# @return [self]
|
45
|
-
def build(hsh)
|
46
|
-
hsh.each do |k, v|
|
47
|
-
@params[k] = v.is_a?(Array) ? v.join(',') : v.to_s
|
48
|
-
end
|
49
|
-
|
50
|
-
self
|
51
|
-
end
|
52
|
-
|
53
|
-
# Replaces the request query with given parameters.
|
54
|
-
#
|
55
|
-
# @see(#build)
|
56
|
-
def build!(hsh = {})
|
57
|
-
_reset!
|
58
|
-
build hsh
|
59
|
-
end
|
60
|
-
|
61
|
-
# Performs a request.
|
62
|
-
#
|
63
|
-
# @return [Vacuum::Response] A response
|
64
|
-
def get
|
65
|
-
res = Net::HTTP.get_response(url)
|
66
|
-
Response.new(res.body, res.code)
|
67
|
-
end
|
68
|
-
|
69
|
-
# @return [Hash] The parameters that make up the request query.
|
70
|
-
def params
|
71
|
-
_default_params.merge(@params)
|
72
|
-
end
|
73
|
-
|
74
|
-
# @return [URI::HTTP] The URL for the API request
|
75
|
-
def url
|
76
|
-
URI::HTTP.build :host => @host,
|
77
|
-
:path => '/onca/xml',
|
78
|
-
:query => _query_string
|
79
|
-
end
|
80
|
-
|
81
|
-
private
|
82
|
-
|
83
|
-
def _default_params
|
84
|
-
default = {
|
85
|
-
'AWSAccessKeyId' => @key,
|
86
|
-
'AssociateTag' => @tag,
|
87
|
-
'Service' => 'AWSECommerceService',
|
88
|
-
'Timestamp' => _timestamp,
|
89
|
-
'Version' => CURRENT_API_VERSION
|
90
|
-
}
|
91
|
-
end
|
92
|
-
|
93
|
-
def _escape(value)
|
94
|
-
value.gsub(/([^a-zA-Z0-9_.~-]+)/) do
|
95
|
-
'%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def _query_string
|
100
|
-
qs = params.sort.map { |k, v| "#{k}=" + _escape(v) }.join('&')
|
101
|
-
|
102
|
-
# Sign query string.
|
103
|
-
dig = OpenSSL::Digest::Digest.new 'sha256'
|
104
|
-
req = ['GET', @host, '/onca/xml', qs]
|
105
|
-
hmac = OpenSSL::HMAC.digest dig, @secret, req.join("\n")
|
106
|
-
sig = _escape [hmac].pack('m').chomp
|
107
|
-
|
108
|
-
"#{qs}&Signature=#{sig}"
|
109
|
-
end
|
110
|
-
|
111
|
-
def _reset!
|
112
|
-
@params = {}
|
113
|
-
end
|
114
|
-
|
115
|
-
def _timestamp
|
116
|
-
Time.now.utc.iso8601
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
data/lib/vacuum/response.rb
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
module Vacuum
|
2
|
-
# A wrapper around the API response.
|
3
|
-
class Response
|
4
|
-
|
5
|
-
# @return [String] body The response body
|
6
|
-
attr_accessor :body
|
7
|
-
|
8
|
-
# @return [Integer] code The HTTP status code of the response
|
9
|
-
attr_accessor :code
|
10
|
-
|
11
|
-
# Creates a new response.
|
12
|
-
#
|
13
|
-
# @param [String] body The response body
|
14
|
-
# @param [#to_i] code The HTTP status code of the response
|
15
|
-
def initialize(body, code)
|
16
|
-
@body = body
|
17
|
-
@code = code.to_i
|
18
|
-
end
|
19
|
-
|
20
|
-
# @return [Array] Errors in the response
|
21
|
-
def errors
|
22
|
-
find 'Error'
|
23
|
-
end
|
24
|
-
|
25
|
-
# Queries for a given attribute, yielding matching nodes to a block if
|
26
|
-
# given one.
|
27
|
-
#
|
28
|
-
# @param [String] Query attribute to be queried
|
29
|
-
# @yield Optionally passes matching nodes to a given block
|
30
|
-
# @return [Array] Matches
|
31
|
-
#
|
32
|
-
# @example
|
33
|
-
# items = res.find('Item')
|
34
|
-
# asins = res.find('Item') { |item| item['ASIN'] }
|
35
|
-
#
|
36
|
-
def find(query)
|
37
|
-
xml.xpath("//xmlns:#{query}").map do |node|
|
38
|
-
hsh = Knack.from_xml node
|
39
|
-
block_given? ? yield(hsh) : hsh
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# @return [true, false] Whether the response has errors
|
44
|
-
def has_errors?
|
45
|
-
errors.count > 0
|
46
|
-
end
|
47
|
-
|
48
|
-
# @return [Hash] A hash representation of the entire response.
|
49
|
-
def to_hash
|
50
|
-
Knack.from_xml xml
|
51
|
-
end
|
52
|
-
|
53
|
-
# @return [true, false] Whether the HTTP response is OK
|
54
|
-
def valid?
|
55
|
-
code == 200
|
56
|
-
end
|
57
|
-
|
58
|
-
# @return [Nokogiri::XML] the XML document
|
59
|
-
def xml
|
60
|
-
@xml ||= Nokogiri::XML @body
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|