sucker 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  Sucker
2
2
  ======
3
3
 
4
- Sucker is a paper-thin Ruby wrapper to the [Amazon Product Advertising API](https://affiliate-program.amazon.co.uk/gp/advertising/api/detail/main.html). It runs on cURL and Nokogiri and supports __everything__ in the API.
4
+ Sucker is a paper-thin Ruby wrapper to the [Amazon Product Advertising API](https://affiliate-program.amazon.co.uk/gp/advertising/api/detail/main.html). It runs on cURL and Nokogiri and supports __everything in the API__.
5
5
 
6
- ![Sucker](http://upload.wikimedia.org/wikipedia/en/7/71/Vacuum_cleaner_1910.JPG)
6
+ ![Sucker](http://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/FEMA_-_32011_-_FEMA_Joint_Field_Office_%28JFO%29_preparation_in_Ohio.jpg/540px-FEMA_-_32011_-_FEMA_Joint_Field_Office_%28JFO%29_preparation_in_Ohio.jpg)
7
7
 
8
8
  Examples
9
9
  --------
@@ -13,15 +13,17 @@ Set up a worker.
13
13
  worker = Sucker.new(
14
14
  :locale => "us",
15
15
  :key => "API KEY",
16
- :secret => "API SECRET",
17
- :associate_tag => "ASSOCIATE TAG")
16
+ :secret => "API SECRET")
18
17
 
19
- Fiddle with curl.
18
+ Optionally, fiddle with curl. Say you want to use multiple network interfaces to query Amazon:
20
19
 
21
20
  worker.curl { |c| c.interface = "eth1" }
22
21
 
23
22
  Set up a request.
24
23
 
24
+ asin_batch = %w{
25
+ 0816614024 0143105825 0485113600 0816616779 0942299078
26
+ 0816614008 144006654X 0486400360 0486417670 087220474X }
25
27
  worker << {
26
28
  "Operation" => "ItemLookup",
27
29
  "IdType" => "ASIN",
@@ -39,20 +41,24 @@ View the internals of the response object.
39
41
  response.body,
40
42
  response.xml
41
43
 
42
- Work on the entire document or a particular node.
44
+ Here is the response parsed into a simple hash:
43
45
 
44
46
  pp response.to_hash
45
-
46
- response.node("Item").each { |book| do_something }
47
- response.node("Error").each { |error| do_something }
48
47
 
49
- Hit Amazon again.
48
+ But you will probably be more interested particular nodes:
50
49
 
51
- worker << { "ItemId" => another_asin_batch }
52
- response = worker.get
50
+ response.node("Item"),
51
+ response.node("Error")
52
+
53
+ Fetch another ASIN in a more DSL-y way.
54
+
55
+ worker << { "ItemId" => "0486454398" }
56
+ pp worker.get.node("Item")
53
57
 
54
58
  Check the integration specs for more examples.
55
59
 
60
+ Ultimately, you should rely on the API documentation to build your queries.
61
+
56
62
  Stubbing
57
63
  --------
58
64
 
@@ -69,7 +75,18 @@ In your spec, you can now stub the worker:
69
75
 
70
76
  The first time you run the spec, Sucker will perform the actual request. Following requests will use a cached response.
71
77
 
78
+ Active Support
79
+ --------------
80
+ Sucker::Response relies on the Nokogiri implementation of the XmlMini parser in Active Support (~> 3.0).
81
+
82
+ In a non-Rails environment, that merely means requiring twenty-something lines of code from Active Support.
83
+
72
84
  Compatibility
73
85
  -------------
74
86
 
75
- Specs pass against Ruby 1.8.7, 1.9.1, 1.9.2, and REE.
87
+ Specs pass against Ruby 1.8.7, 1.9.2, and REE.
88
+
89
+ Todo
90
+ ----
91
+
92
+ * See if I can do away with the stub class and use something like VCR in its place.
@@ -8,8 +8,8 @@ module Sucker
8
8
  :de => 'ecs.amazonaws.de',
9
9
  :ca => 'ecs.amazonaws.ca',
10
10
  :fr => 'ecs.amazonaws.fr',
11
- :jp => 'ecs.amazonaws.jp' }
12
- PATH = "/onca/xml"
11
+ :jp => 'ecs.amazonaws.jp' }.freeze
12
+ PATH = "/onca/xml".freeze
13
13
 
14
14
  # The Amazon locale to query
15
15
  attr_accessor :locale
@@ -2,7 +2,7 @@ module Sucker
2
2
 
3
3
  # A Nokogiri-driven wrapper around the cURL response
4
4
  class Response
5
- attr_accessor :body, :code, :time, :xml
5
+ attr_accessor :body, :code, :time
6
6
 
7
7
  def initialize(curl)
8
8
  self.body = curl.body_str
@@ -10,18 +10,16 @@ module Sucker
10
10
  self.time = curl.total_time
11
11
  end
12
12
 
13
- # Queries an xpath and returns a collection of hashified matches
13
+ # Queries an xpath and returns result as an array of hashes
14
14
  def node(path)
15
15
  xml.xpath("//xmlns:#{path}").map { |node| strip_content(node.to_hash[path]) }
16
16
  end
17
17
 
18
- # Hashifies XML document or node
18
+ # Parses the response into a simple hash
19
19
  def to_hash
20
20
  strip_content(xml.to_hash)
21
21
  end
22
22
 
23
- alias :to_h :to_hash
24
-
25
23
  # The XML document
26
24
  def xml
27
25
  @xml ||= Nokogiri::XML(body)
data/lib/sucker/stub.rb CHANGED
@@ -1,4 +1,8 @@
1
1
  module Sucker
2
+
3
+ # Stubs Sucker::Response to run specs offline. Ideally, I'd like to use
4
+ # a general-purpose stubber for Curb but last time I checked, there was
5
+ # none.
2
6
  class MockResponse < Response
3
7
  def initialize(mock_response_body)
4
8
  self.body = mock_response_body
data/lib/sucker.rb CHANGED
@@ -8,10 +8,9 @@ require "sucker/response"
8
8
  # = Sucker
9
9
  # Sucker is a paper-thin Ruby wrapper to the Amazon Product Advertising API.
10
10
  module Sucker
11
- $KCODE = "u" if RUBY_VERSION < "1.9"
12
-
13
- AMAZON_API_VERSION = "2010-06-01"
11
+ AMAZON_API_VERSION = "2010-06-01".freeze
14
12
 
13
+ # Instantiates a new Sucker::Request
15
14
  def self.new(args={})
16
15
  Sucker::Request.new(args)
17
16
  end
@@ -16,8 +16,7 @@ module Sucker
16
16
  Sucker.stub(@worker)
17
17
 
18
18
  @worker << { "ItemId" => "0816614024" }
19
- @response = @worker.get
20
- @item = @response.node("Item").first
19
+ @item = @worker.get.node("Item").first
21
20
  end
22
21
 
23
22
  it "has an ASIN" do
@@ -1,3 +1,6 @@
1
+ # A word of caution: It seems Amazon will deprecate multiple requests
2
+ # on October 15 2010. We're petitioning them not to.
3
+
1
4
  require "spec_helper"
2
5
 
3
6
  module Sucker
data/spec/spec_helper.rb CHANGED
@@ -1,8 +1,5 @@
1
- unless defined?(Bundler)
2
- require "rubygems"
3
- require "bundler/setup"
4
- end
5
-
1
+ require "rubygems"
2
+ require "bundler/setup"
6
3
  require "rspec"
7
4
 
8
5
  require File.expand_path("../../lib/sucker", __FILE__)
@@ -59,11 +59,6 @@ module Sucker
59
59
  @response.to_hash["book"]["title"].should be_an_instance_of String
60
60
  end
61
61
 
62
- it "is aliased as to_h" do
63
- @response.should respond_to :to_h
64
- @response.to_h.should eql @response.to_hash
65
- end
66
-
67
62
  it "renders French" do
68
63
  @response.body = "<Title>L'archéologie du savoir</Title>"
69
64
  @response.to_hash["Title"].should eql "L'archéologie du savoir"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sucker
3
3
  version: !ruby/object:Gem::Version
4
- hash: 1
4
+ hash: 63
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 7
9
- - 1
10
- version: 0.7.1
8
+ - 8
9
+ - 0
10
+ version: 0.8.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Hakan Ensari
@@ -16,59 +16,56 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-08-07 00:00:00 +01:00
19
+ date: 2010-09-02 00:00:00 +03:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
23
- prerelease: false
24
23
  type: :runtime
24
+ prerelease: false
25
25
  name: activesupport
26
26
  version_requirements: &id001 !ruby/object:Gem::Requirement
27
27
  none: false
28
28
  requirements:
29
- - - ">="
29
+ - - ~>
30
30
  - !ruby/object:Gem::Version
31
- hash: 7712042
31
+ hash: 7
32
32
  segments:
33
33
  - 3
34
34
  - 0
35
35
  - 0
36
- - rc
37
- version: 3.0.0.rc
36
+ version: 3.0.0
38
37
  requirement: *id001
39
38
  - !ruby/object:Gem::Dependency
40
- prerelease: false
41
39
  type: :runtime
40
+ prerelease: false
42
41
  name: nokogiri
43
42
  version_requirements: &id002 !ruby/object:Gem::Requirement
44
43
  none: false
45
44
  requirements:
46
- - - ">="
45
+ - - ~>
47
46
  - !ruby/object:Gem::Version
48
- hash: 113
47
+ hash: 7
49
48
  segments:
50
49
  - 1
51
50
  - 4
52
- - 3
53
- - 1
54
- version: 1.4.3.1
51
+ - 0
52
+ version: 1.4.0
55
53
  requirement: *id002
56
54
  - !ruby/object:Gem::Dependency
57
- prerelease: false
58
55
  type: :runtime
56
+ prerelease: false
59
57
  name: curb
60
58
  version_requirements: &id003 !ruby/object:Gem::Requirement
61
59
  none: false
62
60
  requirements:
63
- - - ">="
61
+ - - ~>
64
62
  - !ruby/object:Gem::Version
65
- hash: 105
63
+ hash: 3
66
64
  segments:
67
65
  - 0
68
66
  - 7
69
- - 7
70
- - 1
71
- version: 0.7.7.1
67
+ - 0
68
+ version: 0.7.0
72
69
  requirement: *id003
73
70
  description: A paper-thin Ruby wrapper to the Amazon Product Advertising API
74
71
  email: code@papercavalier.com
@@ -86,7 +83,6 @@ files:
86
83
  - lib/sucker/response.rb
87
84
  - lib/sucker/stub.rb
88
85
  - README.md
89
- - spec/benchmark/to_hash_implementations.rb
90
86
  - spec/integration/errors_spec.rb
91
87
  - spec/integration/france_spec.rb
92
88
  - spec/integration/images_spec.rb
@@ -136,7 +132,6 @@ signing_key:
136
132
  specification_version: 3
137
133
  summary: A paper-thin Ruby wrapper to the Amazon Product Advertising API
138
134
  test_files:
139
- - spec/benchmark/to_hash_implementations.rb
140
135
  - spec/integration/errors_spec.rb
141
136
  - spec/integration/france_spec.rb
142
137
  - spec/integration/images_spec.rb
@@ -1,38 +0,0 @@
1
- require File.dirname(__FILE__) + "/../spec_helper"
2
-
3
- require "benchmark"
4
- require "crack/xml"
5
- require "xmlsimple"
6
-
7
- worker = Sucker.new(
8
- :locale => "us",
9
- :key => amazon["key"],
10
- :secret => amazon["secret"])
11
-
12
- # Prep worker
13
- worker << {
14
- "Operation" => "ItemLookup",
15
- "ItemLookup.Shared.IdType" => "ASIN",
16
- "ItemLookup.Shared.Condition" => "All",
17
- "ItemLookup.Shared.MerchantId" => "All",
18
- "ItemLookup.Shared.ResponseGroup" => "OfferFull" }
19
-
20
- # Push twenty ASINs to worker
21
- asins = %w{
22
- 0816614024 0143105825 0485113600 0816616779 0942299078
23
- 0816614008 144006654X 0486400360 0486417670 087220474X
24
- 0486454398 0268018359 1604246014 184467598X 0312427182
25
- 1844674282 0745640974 0745646441 0826489540 1844672972 }
26
- worker << {
27
- "ItemLookup.1.ItemId" => asins[0, 10],
28
- "ItemLookup.2.ItemId" => asins[10, 10] }
29
-
30
- Sucker.stub(worker)
31
-
32
- response = worker.get
33
-
34
- Benchmark.bm(100) do |x|
35
- x.report("Crack") { Crack::XML.parse(response.body) }
36
- x.report("SimpleXml") { XmlSimple.xml_in(response.body, { "ForceArray" => false }) }
37
- x.report("AS + Nokogiri") { response.to_hash }
38
- end