sucker 1.6.0 → 2.0.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/sucker/{hash.rb → hash_builder.rb} +3 -5
- data/lib/sucker/parameters.rb +20 -11
- data/lib/sucker/request.rb +24 -26
- data/lib/sucker/response.rb +4 -5
- data/lib/sucker/version.rb +1 -1
- data/spec/sucker/{hash_spec.rb → hash_builder_spec.rb} +5 -5
- data/spec/sucker/parameters_spec.rb +3 -7
- data/spec/sucker/request_spec.rb +3 -3
- data/spec/sucker/response_spec.rb +1 -1
- metadata +15 -11
@@ -1,7 +1,5 @@
|
|
1
1
|
module Sucker
|
2
|
-
|
3
|
-
# A monkey-patched Hash, safely stashed away in the Sucker namespace.
|
4
|
-
class Hash < ::Hash
|
2
|
+
module HashBuilder
|
5
3
|
class << self
|
6
4
|
|
7
5
|
# Builds a hash from a Nokogiri XML document.
|
@@ -14,9 +12,9 @@ module Sucker
|
|
14
12
|
def from_xml(xml)
|
15
13
|
case xml
|
16
14
|
when Nokogiri::XML::Document
|
17
|
-
|
15
|
+
from_xml(xml.root)
|
18
16
|
when Nokogiri::XML::Element
|
19
|
-
result_hash =
|
17
|
+
result_hash = {}
|
20
18
|
|
21
19
|
xml.attributes.each_pair do |key, attribute|
|
22
20
|
result_hash[key] = attribute.value
|
data/lib/sucker/parameters.rb
CHANGED
@@ -1,21 +1,30 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
1
3
|
module Sucker
|
2
|
-
class Parameters
|
4
|
+
class Parameters
|
5
|
+
extend Forwardable
|
6
|
+
|
3
7
|
CURRENT_API_VERSION = '2010-11-01'
|
4
8
|
|
9
|
+
def_delegators :@parameters, :[], :[]=, :merge!
|
10
|
+
|
5
11
|
def initialize
|
6
|
-
|
12
|
+
reset
|
7
13
|
end
|
8
14
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
15
|
+
# Creates a new hash to store parameters in.
|
16
|
+
def reset
|
17
|
+
@parameters = {
|
18
|
+
'Service' => 'AWSECommerceService',
|
19
|
+
'Version' => CURRENT_API_VERSION,
|
20
|
+
'Timestamp' => timestamp }
|
13
21
|
end
|
14
22
|
|
23
|
+
# Returns a normalized parameters hash.
|
24
|
+
#
|
15
25
|
# Ensures all keys and values are strings and camelizes former.
|
16
26
|
def normalize
|
17
|
-
inject({}) do |hash,
|
18
|
-
k, v = kv
|
27
|
+
@parameters.inject({}) do |hash, (k, v)|
|
19
28
|
v = v.is_a?(Array) ? v.join(',') : v.to_s
|
20
29
|
k = k.to_s.split('_').map {|w| w[0, 1] = w[0, 1].upcase; w }.join
|
21
30
|
hash[k] = v
|
@@ -26,8 +35,8 @@ module Sucker
|
|
26
35
|
|
27
36
|
private
|
28
37
|
|
29
|
-
|
30
|
-
|
31
|
-
|
38
|
+
def timestamp
|
39
|
+
Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ')
|
40
|
+
end
|
32
41
|
end
|
33
42
|
end
|
data/lib/sucker/request.rb
CHANGED
@@ -3,7 +3,6 @@ require 'openssl'
|
|
3
3
|
require 'sucker/parameters'
|
4
4
|
|
5
5
|
module Sucker
|
6
|
-
|
7
6
|
# A wrapper around the API request.
|
8
7
|
class Request
|
9
8
|
HOSTS = {
|
@@ -80,8 +79,7 @@ module Sucker
|
|
80
79
|
|
81
80
|
# Resets parameters and returns self.
|
82
81
|
def reset
|
83
|
-
parameters.
|
84
|
-
parameters.populate
|
82
|
+
parameters.reset
|
85
83
|
|
86
84
|
self
|
87
85
|
end
|
@@ -102,33 +100,33 @@ module Sucker
|
|
102
100
|
|
103
101
|
private
|
104
102
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
103
|
+
def build_query_string
|
104
|
+
parameters.
|
105
|
+
normalize.
|
106
|
+
merge({ 'AWSAccessKeyId' => key,
|
107
|
+
'AssociateTag' => associate_tag.to_s }).
|
108
|
+
sort.
|
109
|
+
map { |k, v| "#{k}=" + escape(v) }.
|
110
|
+
join('&')
|
111
|
+
end
|
114
112
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
113
|
+
def sign(query_string)
|
114
|
+
digest = OpenSSL::Digest::Digest.new('sha256')
|
115
|
+
url_string = ['GET', host, '/onca/xml', query_string].join("\n")
|
116
|
+
hmac = OpenSSL::HMAC.digest(digest, secret, url_string)
|
117
|
+
signature = escape([hmac].pack('m').chomp)
|
120
118
|
|
121
|
-
|
122
|
-
|
119
|
+
query_string + '&Signature=' + signature
|
120
|
+
end
|
123
121
|
|
124
|
-
|
125
|
-
|
126
|
-
|
122
|
+
def escape(value)
|
123
|
+
value.gsub(/([^a-zA-Z0-9_.~-]+)/) do
|
124
|
+
'%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
|
125
|
+
end
|
127
126
|
end
|
128
|
-
end
|
129
127
|
|
130
|
-
|
131
|
-
|
132
|
-
|
128
|
+
def host
|
129
|
+
HOSTS[locale.to_sym]
|
130
|
+
end
|
133
131
|
end
|
134
132
|
end
|
data/lib/sucker/response.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'nokogiri'
|
2
|
-
require 'sucker/
|
2
|
+
require 'sucker/hash_builder'
|
3
3
|
|
4
4
|
module Sucker
|
5
|
-
|
6
5
|
# A wrapper around the API response.
|
7
6
|
class Response
|
8
7
|
|
@@ -26,7 +25,7 @@ module Sucker
|
|
26
25
|
find(path).each { |match| block.call(match) }
|
27
26
|
end
|
28
27
|
|
29
|
-
#
|
28
|
+
# An array of errors in the response.
|
30
29
|
def errors
|
31
30
|
find('Error')
|
32
31
|
end
|
@@ -38,7 +37,7 @@ module Sucker
|
|
38
37
|
#
|
39
38
|
def find(attribute)
|
40
39
|
xml.xpath("//xmlns:#{attribute}").map do |element|
|
41
|
-
|
40
|
+
HashBuilder.from_xml(element)
|
42
41
|
end
|
43
42
|
end
|
44
43
|
alias_method :[], :find
|
@@ -59,7 +58,7 @@ module Sucker
|
|
59
58
|
|
60
59
|
# Parses the response into a simple hash.
|
61
60
|
def to_hash
|
62
|
-
|
61
|
+
HashBuilder.from_xml(xml)
|
63
62
|
end
|
64
63
|
|
65
64
|
# Checks if the HTTP response is OK.
|
data/lib/sucker/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
module Sucker
|
4
|
-
describe
|
4
|
+
describe HashBuilder do
|
5
5
|
let(:xml) do
|
6
6
|
xml = <<-XML
|
7
7
|
<?xml version=\"1.0\" ?>
|
@@ -18,19 +18,19 @@ module Sucker
|
|
18
18
|
|
19
19
|
describe '.from_xml' do
|
20
20
|
it 'returns a hash' do
|
21
|
-
|
21
|
+
HashBuilder.from_xml(xml).should be_an_instance_of Hash
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'handles only childs' do
|
25
|
-
|
25
|
+
HashBuilder.from_xml(xml)['Title'].should eql 'Anti-Oedipus'
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'handles arrays' do
|
29
|
-
|
29
|
+
HashBuilder.from_xml(xml)['Author'].should be_a Array
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'handles attributes' do
|
33
|
-
node =
|
33
|
+
node = HashBuilder.from_xml(xml)['Creator']
|
34
34
|
node['Role'].should eql 'Translator'
|
35
35
|
node['__content__'].should eql 'Robert Hurley'
|
36
36
|
end
|
@@ -6,21 +6,17 @@ module Sucker
|
|
6
6
|
Parameters.new
|
7
7
|
end
|
8
8
|
|
9
|
-
it "is a Hash" do
|
10
|
-
Parameters.ancestors.should include ::Hash
|
11
|
-
end
|
12
|
-
|
13
9
|
context "when initialized" do
|
14
10
|
it "sets `Service`" do
|
15
|
-
parameters.
|
11
|
+
parameters['Service'].should_not be_nil
|
16
12
|
end
|
17
13
|
|
18
14
|
it "sets `Version`" do
|
19
|
-
parameters.
|
15
|
+
parameters['Version'].should_not be_nil
|
20
16
|
end
|
21
17
|
|
22
18
|
it "set `Timestamp`" do
|
23
|
-
parameters.
|
19
|
+
parameters['Timestamp'].should_not be_nil
|
24
20
|
end
|
25
21
|
end
|
26
22
|
|
data/spec/sucker/request_spec.rb
CHANGED
@@ -31,12 +31,12 @@ module Sucker
|
|
31
31
|
end
|
32
32
|
|
33
33
|
describe "#reset" do
|
34
|
-
it "
|
34
|
+
it "resets parameters" do
|
35
35
|
request << { 'foo' => 'bar' }
|
36
36
|
request.reset
|
37
37
|
|
38
|
-
request.parameters
|
39
|
-
request.parameters
|
38
|
+
request.parameters['Service'].should_not be_nil
|
39
|
+
request.parameters['foo'].should be_nil
|
40
40
|
end
|
41
41
|
|
42
42
|
it "returns the request object" do
|
metadata
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sucker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
4
|
+
prerelease: true
|
5
5
|
segments:
|
6
|
-
-
|
7
|
-
- 6
|
6
|
+
- 2
|
8
7
|
- 0
|
9
|
-
|
8
|
+
- 0
|
9
|
+
- pre
|
10
|
+
- 1
|
11
|
+
version: 2.0.0.pre.1
|
10
12
|
platform: ruby
|
11
13
|
authors:
|
12
14
|
- Paper Cavalier
|
@@ -14,7 +16,7 @@ autorequire:
|
|
14
16
|
bindir: bin
|
15
17
|
cert_chain: []
|
16
18
|
|
17
|
-
date: 2011-
|
19
|
+
date: 2011-06-02 00:00:00 +01:00
|
18
20
|
default_executable:
|
19
21
|
dependencies:
|
20
22
|
- !ruby/object:Gem::Dependency
|
@@ -178,7 +180,7 @@ extensions: []
|
|
178
180
|
extra_rdoc_files: []
|
179
181
|
|
180
182
|
files:
|
181
|
-
- lib/sucker/
|
183
|
+
- lib/sucker/hash_builder.rb
|
182
184
|
- lib/sucker/parameters.rb
|
183
185
|
- lib/sucker/request.rb
|
184
186
|
- lib/sucker/response.rb
|
@@ -205,7 +207,7 @@ files:
|
|
205
207
|
- spec/fixtures/cassette_library/spec/sucker/request.yml
|
206
208
|
- spec/fixtures/cassette_library/spec/sucker/response.yml
|
207
209
|
- spec/spec_helper.rb
|
208
|
-
- spec/sucker/
|
210
|
+
- spec/sucker/hash_builder_spec.rb
|
209
211
|
- spec/sucker/parameters_spec.rb
|
210
212
|
- spec/sucker/request_spec.rb
|
211
213
|
- spec/sucker/response_spec.rb
|
@@ -233,11 +235,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
233
235
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
234
236
|
none: false
|
235
237
|
requirements:
|
236
|
-
- - "
|
238
|
+
- - ">"
|
237
239
|
- !ruby/object:Gem::Version
|
238
240
|
segments:
|
239
|
-
-
|
240
|
-
|
241
|
+
- 1
|
242
|
+
- 3
|
243
|
+
- 1
|
244
|
+
version: 1.3.1
|
241
245
|
requirements: []
|
242
246
|
|
243
247
|
rubyforge_project: sucker
|
@@ -265,7 +269,7 @@ test_files:
|
|
265
269
|
- spec/fixtures/cassette_library/spec/sucker/request.yml
|
266
270
|
- spec/fixtures/cassette_library/spec/sucker/response.yml
|
267
271
|
- spec/spec_helper.rb
|
268
|
-
- spec/sucker/
|
272
|
+
- spec/sucker/hash_builder_spec.rb
|
269
273
|
- spec/sucker/parameters_spec.rb
|
270
274
|
- spec/sucker/request_spec.rb
|
271
275
|
- spec/sucker/response_spec.rb
|