sucker 1.4.1 → 1.5.0

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 (59) hide show
  1. data/README.md +17 -54
  2. data/lib/sucker/hash.rb +1 -0
  3. data/lib/sucker/hash.rbc +26 -26
  4. data/lib/sucker/parameters.rb +4 -0
  5. data/lib/sucker/parameters.rbc +95 -30
  6. data/lib/sucker/request.rb +35 -12
  7. data/lib/sucker/request.rbc +420 -244
  8. data/lib/sucker/response.rb +3 -3
  9. data/lib/sucker/response.rbc +91 -65
  10. data/lib/sucker/version.rb +1 -1
  11. data/lib/sucker/version.rbc +1 -1
  12. data/lib/sucker.rb +1 -1
  13. data/spec/fixtures/cassette_library/cartcreate/e3e2f9b71afba67619a95c7178178595.yml +26 -0
  14. data/spec/fixtures/cassette_library/cartcreate/f8fe45cc6b78ac1aac675a8f76d5f7d9.yml +26 -0
  15. data/spec/fixtures/cassette_library/{0415246334.yml → itemlookup/0547439fa22ec1178508f61bc8fb1dfb.yml} +3 -3
  16. data/spec/fixtures/cassette_library/itemlookup/2656b1813249aff0d4febb01044962ff.yml +26 -0
  17. data/spec/fixtures/cassette_library/itemlookup/4908294851a4df13269707e9f6507f91.yml +26 -0
  18. data/spec/fixtures/cassette_library/itemlookup/49690856d2b9cb358fc505dc52862acf.yml +26 -0
  19. data/spec/fixtures/cassette_library/itemlookup/5670727fa0cb9f30464e41aa1346c91c.yml +26 -0
  20. data/spec/fixtures/cassette_library/{b000aspues.yml → itemlookup/67b3c825b2902b511412057442db6e91.yml} +3 -3
  21. data/spec/fixtures/cassette_library/itemlookup/6e6b1dc74378e2e1118713e254191fc0.yml +26 -0
  22. data/spec/fixtures/cassette_library/itemlookup/742f3458144935c0a3320be6e842a17c.yml +26 -0
  23. data/spec/fixtures/cassette_library/itemlookup/76f548183c2804a74d0ed7e0bfbd6d4a.yml +26 -0
  24. data/spec/fixtures/cassette_library/itemlookup/8286b763b726d3dc1fc992023e639b9b.yml +151 -0
  25. data/spec/fixtures/cassette_library/{816614024.yml → itemlookup/9853d1f8ae05d5501df4e4390c5abeae.yml} +18 -18
  26. data/spec/fixtures/cassette_library/itemlookup/9d82768fe80b09c4a3697c608e5edebe.yml +26 -0
  27. data/spec/fixtures/cassette_library/{482224816x.yml → itemlookup/b6c76ad93b17b86adb932b9b97c1f019.yml} +3 -3
  28. data/spec/fixtures/cassette_library/itemlookup/d3d6ea869d31173526f48907bff752a3.yml +26 -0
  29. data/spec/fixtures/cassette_library/itemlookup/d8ad346710c3b479febcf58e67fea7ef.yml +26 -0
  30. data/spec/fixtures/cassette_library/{0394751221.yml → itemlookup/e880c4cb3dd56cdfa2161a71fece15ac.yml} +3 -3
  31. data/spec/fixtures/cassette_library/itemsearch/1c4db6b83580a7498b87d7502c249307.yml +26 -0
  32. data/spec/fixtures/cassette_library/itemsearch/295b9eadfb69d55e1c0acb06220e0b6e.yml +26 -0
  33. data/spec/fixtures/cassette_library/itemsearch/30d2bff757af125e31b82c47380b98ba.yml +26 -0
  34. data/spec/fixtures/cassette_library/itemsearch/34098006ffbbd9570b2c2f9ce23df9f3.yml +26 -0
  35. data/spec/fixtures/cassette_library/itemsearch/4c1e50d070821f4eb9fe3961aba105ee.yml +26 -0
  36. data/spec/fixtures/cassette_library/itemsearch/5a15430433ab94c70466eb61c919a028.yml +26 -0
  37. data/spec/fixtures/cassette_library/itemsearch/8fd40b929a9ed46e2b38ac905c8ab53a.yml +26 -0
  38. data/spec/fixtures/cassette_library/itemsearch/e9a6659c2b464d7388c3831c6425a526.yml +26 -0
  39. data/spec/fixtures/cassette_library/sellerlistingsearch/6b38af058d6a0bda696f49de13cfd343.yml +26 -0
  40. data/spec/fixtures/cassette_library/{a2h6nh4sqyfz4m.yml → sellerlistingsearch/c92200a4bd3d6d9023fa6317a780589b.yml} +3 -3
  41. data/spec/fixtures/cassette_library/sellerlistingsearch/cb25caadce96ac3de70b69b76431d730.yml +26 -0
  42. data/spec/fixtures/cassette_library/sellerlistingsearch/e1261838e1754870ffd309dd78eb7374.yml +26 -0
  43. data/spec/fixtures/cassette_library/spec/sucker/request.yml +4 -4
  44. data/spec/fixtures/cassette_library/spec/sucker/response.yml +3 -3
  45. data/spec/sucker/request_spec.rb +35 -15
  46. data/spec/sucker/request_spec.rbc +660 -166
  47. data/spec/sucker/response_spec.rb +4 -4
  48. data/spec/sucker/response_spec.rbc +133 -269
  49. metadata +75 -36
  50. data/spec/fixtures/cassette_library/0679753354.yml +0 -26
  51. data/spec/fixtures/cassette_library/0816614024-0007218095.yml +0 -26
  52. data/spec/fixtures/cassette_library/0816614024-0143105825.yml +0 -26
  53. data/spec/fixtures/cassette_library/0816614024.yml +0 -26
  54. data/spec/fixtures/cassette_library/a2jyso6w6kep83.yml +0 -26
  55. data/spec/fixtures/cassette_library/author-lacan-or-deleuze-and-not-fiction.yml +0 -26
  56. data/spec/fixtures/cassette_library/deleuze-binding-kindle.yml +0 -26
  57. data/spec/fixtures/cassette_library/deleuze.yml +0 -26
  58. data/spec/fixtures/cassette_library/george-orwell.yml +0 -26
  59. data/spec/fixtures/cassette_library/offer-listing-id.yml +0 -26
data/README.md CHANGED
@@ -1,27 +1,26 @@
1
1
  Sucker
2
2
  ======
3
3
 
4
- Sucker is a Nokogiri-based Ruby wrapper to the [Amazon Product Advertising API](https://affiliate-program.amazon.co.uk/gp/advertising/api/detail/main.html).
5
-
6
- Sucker is fast and supports __the entire Amazon API__.
4
+ Sucker is a Nokogiri-based Ruby wrapper to the [Amazon Product Advertising API](https://affiliate-program.amazon.co.uk/gp/advertising/api/detail/main.html). It's fast and supports the entire API.
7
5
 
8
6
  ![Hoover](https://github.com/papercavalier/sucker/raw/master/hoover.jpg)
9
7
 
10
8
  Usage
11
9
  -----
12
10
 
13
- Read the [API](http://aws.amazon.com/archives/Product%20Advertising%20API). Skip to the __Operations__ section if in a hurry.
11
+ Read [Amazon's API](http://aws.amazon.com/archives/Product%20Advertising%20API).
12
+ Skip to the __Operations__ section if in a hurry.
14
13
 
15
14
  Set up.
16
15
 
17
- worker = Sucker.new \
18
- :locale => :us,
19
- :key => api_key,
20
- :secret => api_secret
16
+ request = Sucker.new(
17
+ :locale => :us,
18
+ :key => a_key,
19
+ :secret => a_secret)
21
20
 
22
21
  Build a request.
23
22
 
24
- worker << {
23
+ request << {
25
24
  'Operation' => 'ItemLookup',
26
25
  'IdType' => 'ASIN',
27
26
  'ItemId' => 10.asins,
@@ -29,7 +28,7 @@ Build a request.
29
28
 
30
29
  Get a response.
31
30
 
32
- response = worker.get
31
+ response = request.get
33
32
 
34
33
  Fulfill a business value.
35
34
 
@@ -58,56 +57,20 @@ To dig further into the response object:
58
57
  response.to_hash,
59
58
  response.xml
60
59
 
61
- Browse the Sucker API [here](http://rdoc.info/github/papercavalier/sucker/master/frames). To see more advanced examples such as twenty-item batch requests and remote cart manipulation, read [here](http://relishapp.com/papercavalier/sucker).
62
-
63
- Managing calls
64
- --------------
65
-
66
- We have a home-grown collection of gems that help us manage our
67
- calls to the Amazon API.
68
-
69
- * [Multiplex](http://github.com/papercavalier/multiplex) binds a
70
- request to a specified local IP.
71
- * [Throttler](http://github.com/papercavalier/throttler) throttles
72
- requests to a venue to one per second per IP.
60
+ To use multiple local IPs on your server, configure the request object like so:
73
61
 
74
- A hypothetical setup:
62
+ adapter = request.adapter
63
+ adapter.socket_local.host = '10.0.0.2'
75
64
 
76
- require 'multiplex'
77
- require 'throttler'
78
-
79
- ips.each do |ip|
80
-
81
- Thread.new do
82
- scope = "#{ip}-#{locale}"
83
-
84
- Throttler.throttle(scope) do
85
- Net::HTTP.bind ip do
86
- # Set up worker
87
- response = worker.get
88
- # Consume response
89
- end
90
- end
91
-
92
- end
93
-
94
- end
95
-
96
- We prefer to use [Resque](http://github.com/defunkt/resque) to manage
97
- multiple requests.
98
-
99
- Generally, four or five workers per locale per IP proves enough to provide
100
- optimum throughput.
65
+ Browse the public interface of Sucker
66
+ [here](http://rdoc.info/github/papercavalier/sucker/master/frames). To see more
67
+ advanced usage examples such as twenty-item batch requests and remote cart
68
+ manipulation, read [here](http://relishapp.com/papercavalier/sucker).
101
69
 
102
70
  Stubbing in Tests
103
71
  -----------------
104
72
 
105
- Use [VCR](http://github.com/myronmarston/vcr).
106
-
107
- Compatibility
108
- -------------
109
-
110
- Specs pass against Ruby 1.8.7, Ruby 1.9.2, JRuby 1.5.6, and Rubinius 1.2.1.
73
+ Try [VCR](http://github.com/myronmarston/vcr).
111
74
 
112
75
  Moral of the story
113
76
  ------------------
data/lib/sucker/hash.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  module Sucker
2
2
 
3
+ # A monkey-patched Hash, safely stashed away in the Sucker namespace.
3
4
  class Hash < ::Hash
4
5
  class << self
5
6
 
data/lib/sucker/hash.rbc CHANGED
@@ -480,11 +480,11 @@ p
480
480
  I
481
481
  0
482
482
  I
483
- 14
483
+ 15
484
484
  I
485
485
  a
486
486
  I
487
- 15
487
+ 16
488
488
  I
489
489
  1c
490
490
  x
@@ -727,47 +727,47 @@ p
727
727
  I
728
728
  0
729
729
  I
730
- 18
730
+ 19
731
731
  I
732
732
  4
733
733
  I
734
- 19
734
+ 1a
735
735
  I
736
736
  e
737
737
  I
738
- 1b
738
+ 1c
739
739
  I
740
740
  1a
741
741
  I
742
- 1c
742
+ 1d
743
743
  I
744
744
  22
745
745
  I
746
- 1d
746
+ 1e
747
747
  I
748
748
  27
749
749
  I
750
- 1f
750
+ 20
751
751
  I
752
752
  38
753
753
  I
754
- 21
754
+ 22
755
755
  I
756
756
  45
757
757
  I
758
- 22
758
+ 23
759
759
  I
760
760
  58
761
761
  I
762
- 23
762
+ 24
763
763
  I
764
764
  6a
765
765
  I
766
- 25
766
+ 26
767
767
  I
768
768
  8d
769
769
  I
770
- 28
770
+ 29
771
771
  I
772
772
  9f
773
773
  x
@@ -795,43 +795,43 @@ p
795
795
  I
796
796
  -1
797
797
  I
798
- d
798
+ e
799
799
  I
800
800
  0
801
801
  I
802
- e
802
+ f
803
803
  I
804
804
  2
805
805
  I
806
- f
806
+ 10
807
807
  I
808
808
  11
809
809
  I
810
- 10
810
+ 11
811
811
  I
812
812
  43
813
813
  I
814
- 11
814
+ 12
815
815
  I
816
816
  52
817
817
  I
818
- 12
818
+ 13
819
819
  I
820
820
  6c
821
821
  I
822
- 14
822
+ 15
823
823
  I
824
824
  77
825
825
  I
826
- 18
826
+ 19
827
827
  I
828
828
  82
829
829
  I
830
- 2c
830
+ 2d
831
831
  I
832
832
  87
833
833
  I
834
- 2e
834
+ 2f
835
835
  I
836
836
  90
837
837
  x
@@ -856,7 +856,7 @@ p
856
856
  I
857
857
  2
858
858
  I
859
- d
859
+ e
860
860
  I
861
861
  10
862
862
  x
@@ -872,7 +872,7 @@ p
872
872
  I
873
873
  2
874
874
  I
875
- 4
875
+ 5
876
876
  I
877
877
  1c
878
878
  x
@@ -888,7 +888,7 @@ p
888
888
  I
889
889
  2
890
890
  I
891
- 3
891
+ 4
892
892
  I
893
893
  1f
894
894
  x
@@ -3,6 +3,10 @@ module Sucker
3
3
  CURRENT_API_VERSION = '2010-11-01'
4
4
 
5
5
  def initialize
6
+ set_up
7
+ end
8
+
9
+ def set_up
6
10
  self.store 'Service', 'AWSECommerceService'
7
11
  self.store 'Version', CURRENT_API_VERSION
8
12
  self.store 'Timestamp', timestamp
@@ -129,7 +129,7 @@ x
129
129
  10
130
130
  Parameters
131
131
  i
132
- 58
132
+ 72
133
133
  5
134
134
  66
135
135
  65
@@ -170,15 +170,29 @@ i
170
170
  6
171
171
  4
172
172
  15
173
+ 99
174
+ 7
175
+ 9
176
+ 7
177
+ 10
178
+ 65
179
+ 67
180
+ 49
181
+ 5
182
+ 0
183
+ 49
184
+ 6
185
+ 4
186
+ 15
173
187
  5
174
188
  48
175
- 9
189
+ 11
176
190
  15
177
191
  99
178
192
  7
179
- 10
193
+ 12
180
194
  7
181
- 11
195
+ 13
182
196
  65
183
197
  67
184
198
  49
@@ -198,7 +212,7 @@ I
198
212
  0
199
213
  n
200
214
  p
201
- 12
215
+ 14
202
216
  x
203
217
  19
204
218
  CURRENT_API_VERSION
@@ -219,6 +233,59 @@ x
219
233
  10
220
234
  initialize
221
235
  i
236
+ 4
237
+ 5
238
+ 48
239
+ 0
240
+ 11
241
+ I
242
+ 1
243
+ I
244
+ 0
245
+ I
246
+ 0
247
+ I
248
+ 0
249
+ n
250
+ p
251
+ 1
252
+ x
253
+ 6
254
+ set_up
255
+ p
256
+ 5
257
+ I
258
+ -1
259
+ I
260
+ 5
261
+ I
262
+ 0
263
+ I
264
+ 6
265
+ I
266
+ 4
267
+ x
268
+ 55
269
+ /Users/hakanensari/code/sucker/lib/sucker/parameters.rb
270
+ p
271
+ 0
272
+ x
273
+ 17
274
+ method_visibility
275
+ x
276
+ 15
277
+ add_defn_method
278
+ x
279
+ 6
280
+ set_up
281
+ M
282
+ 1
283
+ n
284
+ n
285
+ x
286
+ 6
287
+ set_up
288
+ i
222
289
  33
223
290
  5
224
291
  7
@@ -291,19 +358,19 @@ p
291
358
  I
292
359
  -1
293
360
  I
294
- 5
361
+ 9
295
362
  I
296
363
  0
297
364
  I
298
- 6
365
+ a
299
366
  I
300
367
  b
301
368
  I
302
- 7
369
+ b
303
370
  I
304
371
  16
305
372
  I
306
- 8
373
+ c
307
374
  I
308
375
  21
309
376
  x
@@ -312,12 +379,6 @@ x
312
379
  p
313
380
  0
314
381
  x
315
- 17
316
- method_visibility
317
- x
318
- 15
319
- add_defn_method
320
- x
321
382
  9
322
383
  normalize
323
384
  M
@@ -562,7 +623,7 @@ p
562
623
  I
563
624
  0
564
625
  I
565
- 10
626
+ 14
566
627
  I
567
628
  1d
568
629
  x
@@ -584,23 +645,23 @@ p
584
645
  I
585
646
  0
586
647
  I
587
- d
648
+ 11
588
649
  I
589
650
  a
590
651
  I
591
- e
652
+ 12
592
653
  I
593
654
  18
594
655
  I
595
- f
656
+ 13
596
657
  I
597
658
  34
598
659
  I
599
- 10
660
+ 14
600
661
  I
601
662
  53
602
663
  I
603
- 11
664
+ 15
604
665
  I
605
666
  56
606
667
  x
@@ -628,11 +689,11 @@ p
628
689
  I
629
690
  -1
630
691
  I
631
- c
692
+ 10
632
693
  I
633
694
  0
634
695
  I
635
- d
696
+ 11
636
697
  I
637
698
  f
638
699
  x
@@ -703,11 +764,11 @@ p
703
764
  I
704
765
  -1
705
766
  I
706
- 17
767
+ 1b
707
768
  I
708
769
  0
709
770
  I
710
- 18
771
+ 1c
711
772
  I
712
773
  10
713
774
  x
@@ -716,7 +777,7 @@ x
716
777
  p
717
778
  0
718
779
  p
719
- 11
780
+ 13
720
781
  I
721
782
  2
722
783
  I
@@ -728,17 +789,21 @@ I
728
789
  I
729
790
  1a
730
791
  I
731
- c
792
+ 9
732
793
  I
733
794
  28
734
795
  I
735
- 15
796
+ 10
736
797
  I
737
- 2c
798
+ 36
738
799
  I
739
- 17
800
+ 19
740
801
  I
741
802
  3a
803
+ I
804
+ 1b
805
+ I
806
+ 48
742
807
  x
743
808
  55
744
809
  /Users/hakanensari/code/sucker/lib/sucker/parameters.rb
@@ -1,4 +1,4 @@
1
- require 'net/http'
1
+ require 'httpclient'
2
2
  require 'openssl'
3
3
  require 'sucker/parameters'
4
4
 
@@ -14,6 +14,11 @@ module Sucker
14
14
  :fr => 'ecs.amazonaws.fr',
15
15
  :jp => 'ecs.amazonaws.jp' }
16
16
 
17
+ # Available Amazon locales.
18
+ def self.locales
19
+ @locales ||= HOSTS.keys
20
+ end
21
+
17
22
  # The Amazon associate tag.
18
23
  attr_accessor :associate_tag
19
24
 
@@ -30,17 +35,24 @@ module Sucker
30
35
  #
31
36
  # Takes an optional hash of attribute and value pairs.
32
37
  #
33
- # worker = Sucker.new(
34
- # :key => 'API KEY',
35
- # :secret => 'API SECRET')
38
+ # request = Sucker.new(
39
+ # :locale => :us,
40
+ # :key => a_key,
41
+ # :secret => a_secret,
42
+ # :associate_tag => a_tag)
36
43
  #
37
44
  def initialize(args={})
38
45
  args.each { |k, v| send("#{k}=", v) }
39
46
  end
40
47
 
48
+ # The HTTP adapter.
49
+ def adapter
50
+ @adapter ||= HTTPClient.new
51
+ end
52
+
41
53
  # Merges a hash into the existing parameters.
42
54
  #
43
- # worker << {
55
+ # request << {
44
56
  # 'Operation' => 'ItemLookup',
45
57
  # 'IdType' => 'ASIN',
46
58
  # 'ItemId' => '0816614024' }
@@ -51,14 +63,10 @@ module Sucker
51
63
 
52
64
  # Performs a request and returns a response object.
53
65
  #
54
- # response = worker.get
66
+ # response = request.get
55
67
  #
56
68
  def get
57
- response = Net::HTTP.start(host) do |http|
58
- query = build_signed_query
59
- http.get("/onca/xml?#{query}")
60
- end
61
-
69
+ response = adapter.get(uri)
62
70
  Response.new(response)
63
71
  end
64
72
 
@@ -67,9 +75,17 @@ module Sucker
67
75
  @parameters ||= Parameters.new
68
76
  end
69
77
 
78
+ # Resets parameters and returns itself.
79
+ def reset
80
+ parameters.clear
81
+ parameters.set_up
82
+
83
+ self
84
+ end
85
+
70
86
  # Sets the Amazon API version.
71
87
  #
72
- # worker.version = '2010-06-01'
88
+ # request.version = '2010-06-01'
73
89
  #
74
90
  def version=(version)
75
91
  parameters['Version'] = version
@@ -107,5 +123,12 @@ module Sucker
107
123
  def host
108
124
  HOSTS[locale.to_sym]
109
125
  end
126
+
127
+ def uri
128
+ URI::HTTP.build(
129
+ :host => host,
130
+ :path => '/onca/xml',
131
+ :query => build_signed_query)
132
+ end
110
133
  end
111
134
  end