sucker 1.2.0 → 1.3.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +45 -20
  3. data/lib/sucker/parameters.rb +11 -7
  4. data/lib/sucker/parameters.rbc +723 -0
  5. data/lib/sucker/request.rb +52 -154
  6. data/lib/sucker/request.rbc +2719 -0
  7. data/lib/sucker/response.rb +14 -36
  8. data/lib/sucker/response.rbc +1307 -0
  9. data/lib/sucker/version.rb +3 -1
  10. data/lib/sucker/version.rbc +130 -0
  11. data/lib/sucker.rb +4 -2
  12. data/lib/sucker.rbc +286 -0
  13. data/spec/fixtures/cassette_library/0394751221.yml +26 -0
  14. data/spec/fixtures/cassette_library/0415246334.yml +26 -0
  15. data/spec/fixtures/cassette_library/0679753354.yml +26 -0
  16. data/spec/fixtures/cassette_library/0816614024-0007218095.yml +26 -0
  17. data/spec/fixtures/cassette_library/0816614024-0143105825.yml +26 -0
  18. data/spec/fixtures/cassette_library/0816614024.yml +26 -0
  19. data/spec/fixtures/cassette_library/482224816x.yml +26 -0
  20. data/spec/fixtures/cassette_library/816614024.yml +151 -0
  21. data/spec/fixtures/cassette_library/a2h6nh4sqyfz4m.yml +26 -0
  22. data/spec/fixtures/cassette_library/a2jyso6w6kep83.yml +26 -0
  23. data/spec/fixtures/cassette_library/author-lacan-or-deleuze-and-not-fiction.yml +26 -0
  24. data/spec/fixtures/cassette_library/b000aspues.yml +26 -0
  25. data/spec/fixtures/cassette_library/deleuze-binding-kindle.yml +26 -0
  26. data/spec/fixtures/cassette_library/deleuze.yml +26 -0
  27. data/spec/fixtures/cassette_library/george-orwell.yml +26 -0
  28. data/spec/fixtures/cassette_library/spec/sucker/request.yml +4 -4
  29. data/spec/fixtures/cassette_library/spec/sucker/response.yml +3 -3
  30. data/spec/spec_helper.rbc +230 -0
  31. data/spec/sucker/parameters_spec.rbc +1476 -0
  32. data/spec/sucker/request_spec.rb +34 -217
  33. data/spec/sucker/request_spec.rbc +2473 -0
  34. data/spec/sucker/response_spec.rb +46 -95
  35. data/spec/sucker/response_spec.rbc +2854 -0
  36. data/spec/sucker_spec.rbc +287 -0
  37. data/spec/support/amazon_credentials.rbc +154 -0
  38. data/spec/support/asins.rbc +335 -0
  39. data/spec/support/vcr.rbc +356 -0
  40. metadata +72 -96
  41. data/CHANGELOG.md +0 -47
@@ -1,6 +1,6 @@
1
- require 'curb'
2
- require 'openssl'
3
- require 'ostruct'
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
- # The Amazon secret access key
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 => "API KEY",
26
- # :secret => "API 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
- # "Operation" => "ItemLookup",
36
- # "IdType" => "ASIN",
37
- # "ItemId" => "0816614024" }
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
- # Optionally, pass one or more locales to query specific locales or `:all`
92
- # to query all locales.
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
- end
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, PATH, query].join("\n")
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 get_multi(locales)
222
- responses = []
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
- Curl::Multi.get(uris, curl_opts) do |curl|
225
- response = Response.new(curl)
226
- yield response if block_given?
227
- responses << response
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
- responses
231
- end
125
+ return_value = yield
232
126
 
233
- def host
234
- HOSTS[locale]
235
- end
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
- def locales
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 => PATH,
142
+ :path => '/onca/xml',
245
143
  :query => build_signed_query)
246
144
  end
247
145