sucker 1.2.0 → 1.3.0.pre
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/LICENSE +1 -1
- data/README.md +45 -20
- data/lib/sucker/parameters.rb +11 -7
- data/lib/sucker/parameters.rbc +723 -0
- data/lib/sucker/request.rb +52 -154
- data/lib/sucker/request.rbc +2719 -0
- data/lib/sucker/response.rb +14 -36
- data/lib/sucker/response.rbc +1307 -0
- data/lib/sucker/version.rb +3 -1
- data/lib/sucker/version.rbc +130 -0
- data/lib/sucker.rb +4 -2
- data/lib/sucker.rbc +286 -0
- data/spec/fixtures/cassette_library/0394751221.yml +26 -0
- data/spec/fixtures/cassette_library/0415246334.yml +26 -0
- data/spec/fixtures/cassette_library/0679753354.yml +26 -0
- data/spec/fixtures/cassette_library/0816614024-0007218095.yml +26 -0
- data/spec/fixtures/cassette_library/0816614024-0143105825.yml +26 -0
- data/spec/fixtures/cassette_library/0816614024.yml +26 -0
- data/spec/fixtures/cassette_library/482224816x.yml +26 -0
- data/spec/fixtures/cassette_library/816614024.yml +151 -0
- data/spec/fixtures/cassette_library/a2h6nh4sqyfz4m.yml +26 -0
- data/spec/fixtures/cassette_library/a2jyso6w6kep83.yml +26 -0
- data/spec/fixtures/cassette_library/author-lacan-or-deleuze-and-not-fiction.yml +26 -0
- data/spec/fixtures/cassette_library/b000aspues.yml +26 -0
- data/spec/fixtures/cassette_library/deleuze-binding-kindle.yml +26 -0
- data/spec/fixtures/cassette_library/deleuze.yml +26 -0
- data/spec/fixtures/cassette_library/george-orwell.yml +26 -0
- data/spec/fixtures/cassette_library/spec/sucker/request.yml +4 -4
- data/spec/fixtures/cassette_library/spec/sucker/response.yml +3 -3
- data/spec/spec_helper.rbc +230 -0
- data/spec/sucker/parameters_spec.rbc +1476 -0
- data/spec/sucker/request_spec.rb +34 -217
- data/spec/sucker/request_spec.rbc +2473 -0
- data/spec/sucker/response_spec.rb +46 -95
- data/spec/sucker/response_spec.rbc +2854 -0
- data/spec/sucker_spec.rbc +287 -0
- data/spec/support/amazon_credentials.rbc +154 -0
- data/spec/support/asins.rbc +335 -0
- data/spec/support/vcr.rbc +356 -0
- metadata +72 -96
- data/CHANGELOG.md +0 -47
data/lib/sucker/request.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require '
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'net/http'
|
4
4
|
require 'uri'
|
5
5
|
|
6
6
|
module Sucker #:nodoc:
|
@@ -14,16 +14,27 @@ module Sucker #:nodoc:
|
|
14
14
|
:ca => 'ecs.amazonaws.ca',
|
15
15
|
:fr => 'ecs.amazonaws.fr',
|
16
16
|
:jp => 'ecs.amazonaws.jp' }
|
17
|
-
PATH = "/onca/xml"
|
18
17
|
|
19
|
-
#
|
18
|
+
# Your Amazon associate tag
|
19
|
+
attr_accessor :associate_tag
|
20
|
+
|
21
|
+
# Your AWS access key
|
22
|
+
attr_accessor :key
|
23
|
+
|
24
|
+
# Local IP to route the request through
|
25
|
+
attr_accessor :local_ip
|
26
|
+
|
27
|
+
# Amazon locale
|
28
|
+
attr_accessor :locale
|
29
|
+
|
30
|
+
# Your AWS secret
|
20
31
|
attr_accessor :secret
|
21
32
|
|
22
33
|
# Initializes a request object
|
23
34
|
#
|
24
35
|
# worker = Sucker.new(
|
25
|
-
# :key =>
|
26
|
-
# :secret =>
|
36
|
+
# :key => 'API KEY',
|
37
|
+
# :secret => 'API SECRET')
|
27
38
|
#
|
28
39
|
def initialize(args)
|
29
40
|
args.each { |k, v| send("#{k}=", v) }
|
@@ -32,147 +43,23 @@ module Sucker #:nodoc:
|
|
32
43
|
# Merges a hash into the existing parameters
|
33
44
|
#
|
34
45
|
# worker << {
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
46
|
+
# 'Operation' => 'ItemLookup',
|
47
|
+
# 'IdType' => 'ASIN',
|
48
|
+
# 'ItemId' => '0816614024' }
|
38
49
|
#
|
39
50
|
def <<(hash)
|
40
51
|
self.parameters.merge!(hash)
|
41
52
|
end
|
42
53
|
|
43
|
-
# Returns the associate tag for the current locale
|
44
|
-
def associate_tag
|
45
|
-
@associate_tags[locale.to_sym] rescue ''
|
46
|
-
end
|
47
|
-
|
48
|
-
# Sets the associate tag for the current locale
|
49
|
-
#
|
50
|
-
# worker.associate_tag = 'foo-bar'
|
51
|
-
#
|
52
|
-
def associate_tag=(token)
|
53
|
-
associate_tags[locale.to_sym] = token
|
54
|
-
end
|
55
|
-
|
56
|
-
# Gets the associate tags for all locales
|
57
|
-
def associate_tags
|
58
|
-
@associate_tags ||= {}
|
59
|
-
end
|
60
|
-
|
61
|
-
# Sets associate tags for all locales
|
62
|
-
#
|
63
|
-
# You need a distinct associate tag for each locale.
|
64
|
-
#
|
65
|
-
# tags = {
|
66
|
-
# :us => 'foo-bar-10',
|
67
|
-
# :uk => 'foo-bar-20',
|
68
|
-
# ... }
|
69
|
-
#
|
70
|
-
# worker.associate_tags = tags
|
71
|
-
#
|
72
|
-
def associate_tags=(tokens)
|
73
|
-
@associate_tags = tokens
|
74
|
-
end
|
75
|
-
|
76
|
-
# Returns options for curl and yields them if given a block
|
77
|
-
#
|
78
|
-
# worker.curl_opts { |c| c.interface = "eth1" }
|
79
|
-
#
|
80
|
-
def curl_opts
|
81
|
-
@curl_opts ||= OpenStruct.new
|
82
|
-
yield @curl_opts if block_given?
|
83
|
-
|
84
|
-
@curl_opts.marshal_dump
|
85
|
-
end
|
86
|
-
|
87
54
|
# Performs a request and returns a response
|
88
55
|
#
|
89
56
|
# response = worker.get
|
90
57
|
#
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
# responses = worker.get(:us)
|
95
|
-
#
|
96
|
-
# responses = worker.get(:all)
|
97
|
-
#
|
98
|
-
def get(*args)
|
99
|
-
case args.count
|
100
|
-
|
101
|
-
when 0
|
102
|
-
curl = Curl::Easy.perform(uri.to_s) do |easy|
|
103
|
-
curl_opts.each { |k, v| easy.send("#{k}=", v) }
|
104
|
-
end
|
105
|
-
Response.new(curl)
|
106
|
-
|
107
|
-
when 1
|
108
|
-
arg = args.first
|
109
|
-
if arg == :all
|
110
|
-
get_multi locales
|
111
|
-
else
|
112
|
-
self.locale = arg
|
113
|
-
get
|
114
|
-
end
|
115
|
-
|
116
|
-
else
|
117
|
-
get_multi args
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
def get_all # :nodoc:
|
122
|
-
warn "[DEPRECATION] `get_all` is deprecated. Please use `get(:all) instead."
|
123
|
-
get(:all)
|
124
|
-
end
|
125
|
-
|
126
|
-
# Returns the AWS access key for the current locale
|
127
|
-
def key
|
128
|
-
raise ArgumentError.new "AWS access key missing" unless @keys[locale]
|
129
|
-
|
130
|
-
@keys[locale]
|
131
|
-
end
|
132
|
-
|
133
|
-
# Sets a global AWS access key
|
134
|
-
#
|
135
|
-
# worker.key = 'foo'
|
136
|
-
#
|
137
|
-
def key=(token)
|
138
|
-
@keys = locales.inject({}) do |keys, locale|
|
139
|
-
keys[locale] = token
|
140
|
-
keys
|
58
|
+
def get
|
59
|
+
response = request_through(local_ip) do
|
60
|
+
Net::HTTP.get_response(uri)
|
141
61
|
end
|
142
|
-
|
143
|
-
|
144
|
-
# Sets distinct AWS access keys for the locales
|
145
|
-
#
|
146
|
-
# You can use the same key on multiple venues. Caveat: Calls against (1) the US
|
147
|
-
# and Canada and (2) the UK, France, and Germany count against the same call
|
148
|
-
# rate quota.
|
149
|
-
#
|
150
|
-
# keys = {
|
151
|
-
# :us => 'foo',
|
152
|
-
# :uk => 'bar',
|
153
|
-
# ... }
|
154
|
-
#
|
155
|
-
# worker.keys = keys
|
156
|
-
#
|
157
|
-
def keys=(tokens)
|
158
|
-
@keys = tokens
|
159
|
-
end
|
160
|
-
|
161
|
-
def locale
|
162
|
-
raise ArgumentError.new "Locale not set" unless @locale
|
163
|
-
|
164
|
-
@locale
|
165
|
-
end
|
166
|
-
|
167
|
-
# Sets the current Amazon locale
|
168
|
-
#
|
169
|
-
# Valid values are :us, :uk, :de, :ca, :fr, and :jp.
|
170
|
-
def locale=(new_locale)
|
171
|
-
new_locale = new_locale.to_sym
|
172
|
-
|
173
|
-
raise ArgumentError.new "Invalid locale" unless locales.include? new_locale
|
174
|
-
|
175
|
-
@locale = new_locale
|
62
|
+
Response.new(response)
|
176
63
|
end
|
177
64
|
|
178
65
|
# The parameters to query Amazon with
|
@@ -194,7 +81,7 @@ module Sucker #:nodoc:
|
|
194
81
|
parameters.
|
195
82
|
normalize.
|
196
83
|
merge({ 'AWSAccessKeyId' => key }).
|
197
|
-
merge({ 'AssociateTag' => associate_tag }).
|
84
|
+
merge({ 'AssociateTag' => associate_tag.to_s }).
|
198
85
|
sort.
|
199
86
|
map do |k, v|
|
200
87
|
"#{k}=" + escape(v)
|
@@ -205,7 +92,7 @@ module Sucker #:nodoc:
|
|
205
92
|
query = build_query
|
206
93
|
|
207
94
|
digest = OpenSSL::Digest::Digest.new('sha256')
|
208
|
-
string = ['GET', host,
|
95
|
+
string = ['GET', host, '/onca/xml', query].join("\n")
|
209
96
|
hmac = OpenSSL::HMAC.digest(digest, secret, string)
|
210
97
|
signature = escape([hmac].pack('m').chomp)
|
211
98
|
|
@@ -218,30 +105,41 @@ module Sucker #:nodoc:
|
|
218
105
|
end
|
219
106
|
end
|
220
107
|
|
221
|
-
def
|
222
|
-
|
108
|
+
def host
|
109
|
+
HOSTS[locale]
|
110
|
+
end
|
111
|
+
|
112
|
+
def request_through(local_ip)
|
113
|
+
if local_ip
|
114
|
+
TCPSocket.instance_eval do
|
115
|
+
(class << self; self; end).instance_eval do
|
116
|
+
alias_method :orig_open, :open
|
223
117
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
118
|
+
define_method(:open) do |conn_address, conn_port|
|
119
|
+
original_open(conn_address, conn_port, local_ip)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
228
123
|
end
|
229
124
|
|
230
|
-
|
231
|
-
end
|
125
|
+
return_value = yield
|
232
126
|
|
233
|
-
|
234
|
-
|
235
|
-
|
127
|
+
if local_ip
|
128
|
+
TCPSocket.instance_eval do
|
129
|
+
(class << self; self; end).instance_eval do
|
130
|
+
alias_method :open, :orig_open
|
131
|
+
remove_method :orig_open
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
236
135
|
|
237
|
-
|
238
|
-
@locales ||= HOSTS.keys
|
136
|
+
return_value
|
239
137
|
end
|
240
138
|
|
241
139
|
def uri
|
242
140
|
URI::HTTP.build(
|
243
141
|
:host => host,
|
244
|
-
:path =>
|
142
|
+
:path => '/onca/xml',
|
245
143
|
:query => build_signed_query)
|
246
144
|
end
|
247
145
|
|