sucker 0.7.1 → 0.8.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.
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