sucker 1.6.0 → 2.0.0.pre.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.
- 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
|