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.
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