sucker 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ Sucker
2
+ ======
3
+
4
+ ![Sucker](http://upload.wikimedia.org/wikipedia/en/7/71/Vacuum_cleaner_1910.JPG)
5
+
6
+ Sucker is a light-weight Ruby wrapper to the Amazon Product Advertising API. It runs on Curb and Crack.
7
+
8
+ Examples
9
+ --------
10
+
11
+ Set up a worker.
12
+
13
+ @worker = Sucker.new(
14
+ :locale => "us",
15
+ :key => "API KEY",
16
+ :secret => "API SECRET")
17
+
18
+ Fiddle with curl.
19
+
20
+ @worker.curl { |c| c.interface = "eth1" }
21
+
22
+ Set up a request.
23
+
24
+ @worker << {
25
+ "Operation" => "ItemLookup",
26
+ "IdType" => "ASIN",
27
+ "ItemId" => ["0816614024", "0143105825"] }
28
+
29
+ Hit Amazon and do something with the response.
30
+
31
+ pp @worker.get["ItemLookupResponse"]["Items"]["Item"]
32
+
33
+ Hit Amazon again.
34
+
35
+ @worker << {
36
+ "ItemId" => ["0393329259", "0393317757"] }
37
+ @worker.get
38
+
39
+ Check the integration specs for some more examples.
@@ -43,12 +43,15 @@ module Sucker
43
43
  @curl
44
44
  end
45
45
 
46
- # Hits Amazon with an API request
47
- def fetch
48
- return nil if !valid?
46
+ # Makes a request to Amazon and returns the response as a hash
47
+ # Todo: Handle errors
48
+ def get
49
+ raise ArgumentError, 'Set key, secret, and valid locale' if !valid?
49
50
 
50
51
  curl.url = uri.to_s
51
52
  curl.perform
53
+
54
+ Crack::XML.parse(curl.body_str)
52
55
  end
53
56
 
54
57
  # A helper method that sets the AWS Access Key ID
@@ -56,11 +59,6 @@ module Sucker
56
59
  parameters["AWSAccessKeyId"] = key
57
60
  end
58
61
 
59
- # Returns a hash of the response
60
- def to_h
61
- Crack::XML.parse(curl.body_str)
62
- end
63
-
64
62
  private
65
63
 
66
64
  # Escapes parameters and concatenates them into a query string
data/lib/sucker.rb CHANGED
@@ -4,11 +4,9 @@ require "curb"
4
4
  require "sucker/request"
5
5
 
6
6
  module Sucker
7
- VERSION = "0.1.0".freeze
7
+ VERSION = "0.2.0".freeze
8
8
  AMAZON_API_VERSION = "2009-11-01".freeze
9
9
 
10
- class SuckerError < StandardError; end
11
-
12
10
  def self.new(args={})
13
11
  Sucker::Request.new(args)
14
12
  end
@@ -3,23 +3,22 @@ require "spec_helper"
3
3
  module Sucker
4
4
  describe "Item Lookup" do
5
5
  before do
6
- @sucker = Sucker.new(
6
+ @worker = Sucker.new(
7
7
  :locale => "us",
8
8
  :key => amazon["key"],
9
9
  :secret => amazon["secret"])
10
10
 
11
- # @sucker.curl { |curl| curl.verbose = true }
11
+ # @worker.curl { |curl| curl.verbose = true }
12
12
 
13
- @sucker << {
13
+ @worker << {
14
14
  "Operation" => "ItemLookup",
15
15
  "IdType" => "ASIN" }
16
16
  end
17
17
 
18
18
  context "single item" do
19
19
  before do
20
- @sucker << { "ItemId" => "0816614024" }
21
- @sucker.fetch
22
- @item = @sucker.to_h["ItemLookupResponse"]["Items"]["Item"]
20
+ @worker << { "ItemId" => "0816614024" }
21
+ @item = @worker.get["ItemLookupResponse"]["Items"]["Item"]
23
22
  end
24
23
 
25
24
  it "returns an item" do
@@ -37,9 +36,8 @@ module Sucker
37
36
 
38
37
  context "multiple items" do
39
38
  before do
40
- @sucker << { "ItemId" => ["0816614024", "0143105825"] }
41
- @sucker.fetch
42
- @items = @sucker.to_h["ItemLookupResponse"]["Items"]["Item"]
39
+ @worker << { "ItemId" => ["0816614024", "0143105825"] }
40
+ @items = @worker.get["ItemLookupResponse"]["Items"]["Item"]
43
41
  end
44
42
 
45
43
  it "returns two items" do
@@ -3,18 +3,17 @@ require "spec_helper"
3
3
  module Sucker
4
4
  describe "Seller Listing Search" do
5
5
  before do
6
- @sucker = Sucker.new(
6
+ @worker = Sucker.new(
7
7
  :locale => "us",
8
8
  :key => amazon["key"],
9
9
  :secret => amazon["secret"])
10
10
 
11
- # @sucker.curl { |curl| curl.verbose = true }
11
+ # @worker.curl { |curl| curl.verbose = true }
12
12
 
13
- @sucker << {
13
+ @worker << {
14
14
  "Operation" => "SellerListingSearch",
15
15
  "SellerId" => "A31N271NVIORU3" }
16
- @sucker.fetch
17
- @listings = @sucker.to_h["SellerListingSearchResponse"]["SellerListings"]
16
+ @listings = @worker.get["SellerListingSearchResponse"]["SellerListings"]
18
17
  end
19
18
 
20
19
  it "returns page count" do
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,3 @@
1
- require "rubygems"
2
- require "bundler/setup"
3
1
  require "rspec"
4
2
 
5
3
  require File.expand_path("../../lib/sucker", __FILE__)
@@ -3,7 +3,7 @@ require "spec_helper"
3
3
  module Sucker
4
4
  describe "Request" do
5
5
  before do
6
- @sucker = Sucker.new
6
+ @worker = Sucker.new
7
7
  end
8
8
 
9
9
  context "public" do
@@ -12,153 +12,158 @@ module Sucker
12
12
  default_parameters = {
13
13
  "Service" => "AWSECommerceService",
14
14
  "Version" => Sucker::AMAZON_API_VERSION }
15
- @sucker.parameters.should eql default_parameters
15
+ @worker.parameters.should eql default_parameters
16
16
  end
17
17
  end
18
18
 
19
19
  context "#<<" do
20
- it "merges a hash into the paramters" do
21
- @sucker << { "foo" => "bar" }
22
- @sucker.parameters["foo"].should eql "bar"
20
+ it "merges a hash into the parameters" do
21
+ @worker << { "foo" => "bar" }
22
+ @worker.parameters["foo"].should eql "bar"
23
23
  end
24
24
  end
25
25
 
26
26
  context "#curl" do
27
27
  it "returns a cURL object" do
28
- @sucker.curl.should be_an_instance_of Curl::Easy
28
+ @worker.curl.should be_an_instance_of Curl::Easy
29
29
  end
30
30
 
31
31
  it "configures the cURL object" do
32
- @sucker.curl.interface.should be_nil
32
+ @worker.curl.interface.should be_nil
33
33
 
34
- @sucker.curl do |curl|
34
+ @worker.curl do |curl|
35
35
  curl.interface = "eth1"
36
36
  end
37
37
 
38
- @sucker.curl.interface.should eql "eth1"
38
+ @worker.curl.interface.should eql "eth1"
39
39
  end
40
40
  end
41
41
 
42
- context "#fetch" do
43
- it "returns nil if valid? returns false" do
44
- @sucker.stub!(:valid?).and_return(false)
45
- @sucker.fetch.should be_nil
46
- end
47
- end
48
-
49
- context "#to_h" do
42
+ context "#get" do
50
43
  before do
51
- @sucker.curl.stub!(:body_str).and_return(fixture("single_item_lookup.us"))
44
+ @worker.locale = "us"
45
+ @worker.key = "key"
46
+ @worker.secret = "secret"
47
+
48
+ # Stub curl
49
+ curl = @worker.curl
50
+ curl.stub(:get).and_return(nil)
51
+ curl.stub!(:body_str).and_return(fixture("single_item_lookup.us"))
52
52
  end
53
53
 
54
- it "should return a hash" do
55
- @sucker.to_h.should be_an_instance_of Hash
54
+ it "returns a hash" do
55
+ @worker.get.should be_an_instance_of Hash
56
56
  end
57
+
58
+ it "raises an ArgumentError if valid? returns false" do
59
+ @worker.stub!(:valid?).and_return(false)
60
+ lambda{ @worker.get }.should raise_error ArgumentError
61
+ end
57
62
  end
58
63
  end
59
64
 
60
65
  context "private" do
61
66
  context "#build_query" do
62
67
  it "canonicalizes parameters" do
63
- query = @sucker.send(:build_query)
68
+ query = @worker.send(:build_query)
64
69
  query.should eql "Service=AWSECommerceService&Version=#{Sucker::AMAZON_API_VERSION}"
65
70
  end
66
71
 
67
72
  it "sorts parameters" do
68
- @sucker.parameters["Foo"] = "bar"
69
- query = @sucker.send(:build_query)
73
+ @worker.parameters["Foo"] = "bar"
74
+ query = @worker.send(:build_query)
70
75
  query.should match /^Foo=bar/
71
76
  end
72
77
 
73
78
  it "converts a parameter whose value is an array to a string" do
74
- @sucker.parameters["Foo"] = ["bar", "baz"]
75
- query = @sucker.send(:build_query)
79
+ @worker.parameters["Foo"] = ["bar", "baz"]
80
+ query = @worker.send(:build_query)
76
81
  query.should match /^Foo=bar%2Cbaz/
77
82
  end
78
83
  end
79
84
 
80
85
  context "#digest" do
81
86
  it "returns a digest object" do
82
- @sucker.send(:digest).should be_an_instance_of OpenSSL::Digest::Digest
87
+ @worker.send(:digest).should be_an_instance_of OpenSSL::Digest::Digest
83
88
  end
84
89
  end
85
90
 
86
91
  context "#key=" do
87
92
  it "sets the Amazon AWS access key in the parameters" do
88
- @sucker.key = "key"
89
- @sucker.parameters["AWSAccessKeyId"].should eql "key"
93
+ @worker.key = "key"
94
+ @worker.parameters["AWSAccessKeyId"].should eql "key"
90
95
  end
91
96
  end
92
97
 
93
98
  context "#host" do
94
99
  it "returns a host" do
95
- @sucker.locale = "us"
96
- @sucker.send(:host).should eql "ecs.amazonaws.com"
100
+ @worker.locale = "us"
101
+ @worker.send(:host).should eql "ecs.amazonaws.com"
97
102
  end
98
103
  end
99
104
 
100
105
  context "#path" do
101
106
  it "returns a path" do
102
- @sucker.send(:path).should eql "/onca/xml"
107
+ @worker.send(:path).should eql "/onca/xml"
103
108
  end
104
109
  end
105
110
 
106
111
  context "#sign_query" do
107
112
  it "returns a signed query string" do
108
- @sucker.secret = "secret"
109
- @sucker.locale = "us"
110
- query = @sucker.send :sign_query
113
+ @worker.secret = "secret"
114
+ @worker.locale = "us"
115
+ query = @worker.send :sign_query
111
116
  query.should match /&Signature=.*/
112
117
  end
113
118
  end
114
119
 
115
120
  context "#timestamp_parameters" do
116
121
  it "upserts a timestamp to the parameters" do
117
- @sucker.send :timestamp_parameters
118
- @sucker.parameters["Timestamp"].should match /^\d+-\d+-\d+T\d+:\d+:\d+Z$/
122
+ @worker.send :timestamp_parameters
123
+ @worker.parameters["Timestamp"].should match /^\d+-\d+-\d+T\d+:\d+:\d+Z$/
119
124
  end
120
125
  end
121
126
 
122
127
  context "#uri" do
123
128
  it "returns the URI with which to query Amazon" do
124
- @sucker.key = "key"
125
- @sucker.locale = "us"
126
- @sucker.secret = "secret"
127
- @sucker.send(:uri).should be_an_instance_of URI::HTTP
129
+ @worker.key = "key"
130
+ @worker.locale = "us"
131
+ @worker.secret = "secret"
132
+ @worker.send(:uri).should be_an_instance_of URI::HTTP
128
133
  end
129
134
  end
130
135
 
131
136
  context "valid?" do
132
137
  it "returns true if key, secret, and a valid locale are set" do
133
- @sucker.key = "key"
134
- @sucker.locale = "us"
135
- @sucker.secret = "secret"
136
- @sucker.send(:valid?).should be_true
138
+ @worker.key = "key"
139
+ @worker.locale = "us"
140
+ @worker.secret = "secret"
141
+ @worker.send(:valid?).should be_true
137
142
  end
138
143
 
139
144
  it "returns false if key is not set" do
140
- @sucker.locale = "us"
141
- @sucker.secret = "secret"
142
- @sucker.send(:valid?).should be_false
145
+ @worker.locale = "us"
146
+ @worker.secret = "secret"
147
+ @worker.send(:valid?).should be_false
143
148
  end
144
149
 
145
150
  it "returns false if secret is not set" do
146
- @sucker.locale = "us"
147
- @sucker.key = "key"
148
- @sucker.send(:valid?).should be_false
151
+ @worker.locale = "us"
152
+ @worker.key = "key"
153
+ @worker.send(:valid?).should be_false
149
154
  end
150
155
 
151
156
  it "returns false if locale is not set" do
152
- @sucker.key = "key"
153
- @sucker.secret = "secret"
154
- @sucker.send(:valid?).should be_false
157
+ @worker.key = "key"
158
+ @worker.secret = "secret"
159
+ @worker.send(:valid?).should be_false
155
160
  end
156
161
 
157
162
  it "returns false if locale is not valid" do
158
- @sucker.key = "key"
159
- @sucker.locale = "US"
160
- @sucker.secret = "secret"
161
- @sucker.send(:valid?).should be_false
163
+ @worker.key = "key"
164
+ @worker.locale = "US"
165
+ @worker.secret = "secret"
166
+ @worker.send(:valid?).should be_false
162
167
  end
163
168
  end
164
169
  end
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: 31
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 1
9
8
  - 2
10
- version: 0.1.2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Hakan Ensari
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-07-22 00:00:00 +01:00
19
+ date: 2010-07-26 00:00:00 +01:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -52,40 +52,6 @@ dependencies:
52
52
  - 1
53
53
  version: 0.7.7.1
54
54
  requirement: *id002
55
- - !ruby/object:Gem::Dependency
56
- prerelease: false
57
- type: :development
58
- name: rspec
59
- version_requirements: &id003 !ruby/object:Gem::Requirement
60
- none: false
61
- requirements:
62
- - - "="
63
- - !ruby/object:Gem::Version
64
- hash: 62196417
65
- segments:
66
- - 2
67
- - 0
68
- - 0
69
- - beta
70
- - 17
71
- version: 2.0.0.beta.17
72
- requirement: *id003
73
- - !ruby/object:Gem::Dependency
74
- prerelease: false
75
- type: :development
76
- name: ruby-debug
77
- version_requirements: &id004 !ruby/object:Gem::Requirement
78
- none: false
79
- requirements:
80
- - - "="
81
- - !ruby/object:Gem::Version
82
- hash: 49
83
- segments:
84
- - 0
85
- - 10
86
- - 3
87
- version: 0.10.3
88
- requirement: *id004
89
55
  description: Sucker is a thin Ruby wrapper to the Amazon Product Advertising API.
90
56
  email: code@papercavalier.com
91
57
  executables: []
@@ -94,12 +60,12 @@ extensions: []
94
60
 
95
61
  extra_rdoc_files:
96
62
  - LICENSE
97
- - README.textile
63
+ - README.md
98
64
  files:
99
65
  - LICENSE
100
66
  - lib/sucker.rb
101
67
  - lib/sucker/request.rb
102
- - README.textile
68
+ - README.md
103
69
  - spec/integration/item_lookup_spec.rb
104
70
  - spec/integration/seller_listing_search_spec.rb
105
71
  - spec/spec_helper.rb
data/README.textile DELETED
@@ -1,45 +0,0 @@
1
- h1. Sucker
2
-
3
- Sucker is a thin Ruby wrapper to the Amazon Product Advertising API. It's built on Curb and Crack.
4
-
5
- I wrote this because ruby_aaws feels somewhat bloated and we are too lazy to conjure a straightforward way to run the latter through multiple network interfaces.
6
-
7
- h2. Examples
8
-
9
- Woo a worker.
10
-
11
- bc. @worker = Sucker.new(
12
- :locale => "us",
13
- :key => "API KEY",
14
- :secret => "API SECRET")
15
-
16
- Fiddle with curl.
17
-
18
- bc. @worker.curl { |c| c.interface = "eth1" }
19
-
20
- Set up a request.
21
-
22
- bc. @worker << {
23
- "Operation" => "ItemLookup",
24
- "IdType" => "ASIN",
25
- "ItemId" => ["0816614024", "0143105825"] }
26
-
27
- Hit the Amazon API.
28
-
29
- bc. @worker.fetch
30
-
31
- Do something with the response.
32
-
33
- bc. pp @worker.to_h
34
-
35
- Hit the Amazon API again.
36
-
37
- bc. @worker << {
38
- "ItemId" => ["0393329259", "0393317757"] }
39
- @worker.fetch
40
-
41
- Check the integration tests in the spec folder for some more examples.
42
-
43
- h2. Tangential Endnote
44
-
45
- !http://upload.wikimedia.org/wikipedia/en/7/71/Vacuum_cleaner_1910.JPG!