emporium 0.0.1 → 0.0.2.alpha
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +13 -3
- data/lib/emporium/product.rb +9 -61
- data/lib/emporium/services/amazon.rb +72 -0
- data/lib/emporium/services.rb +9 -0
- data/lib/emporium/version.rb +1 -1
- data/lib/emporium.rb +1 -8
- data/spec/emporium/emporium_spec.rb +43 -25
- data/spec/spec_helper.rb +0 -1
- metadata +7 -5
data/README.md
CHANGED
@@ -12,19 +12,29 @@ Add to your Gemfile and run the `bundle` command to install it.
|
|
12
12
|
|
13
13
|
**Requires Ruby 1.9.2 or later.**
|
14
14
|
|
15
|
+
## Configuration
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
Product.configuration do |config|
|
19
|
+
config.service = :amazon
|
20
|
+
# ...
|
21
|
+
end
|
22
|
+
```
|
23
|
+
|
15
24
|
|
16
25
|
## Usage
|
17
26
|
|
18
|
-
|
27
|
+
Give it a UPC to fetch a product object. The Code only takes UPC-A digits
|
19
28
|
|
20
29
|
```ruby
|
21
30
|
require 'emporium'
|
22
31
|
|
23
32
|
product = Emporium::Product.new "066661234567"
|
24
|
-
product.use :amazon
|
25
33
|
product.fetch!
|
26
34
|
```
|
27
35
|
|
36
|
+
|
37
|
+
|
28
38
|
## Development
|
29
39
|
|
30
|
-
This gem is
|
40
|
+
This gem is under the MIT License.
|
data/lib/emporium/product.rb
CHANGED
@@ -1,36 +1,21 @@
|
|
1
1
|
module Emporium
|
2
2
|
class Product
|
3
3
|
attr_accessor :code
|
4
|
+
attr_accessor :service
|
4
5
|
|
5
|
-
def initialize(code
|
6
|
-
@code = ::Code.new(code)
|
6
|
+
def initialize(code)
|
7
|
+
@code = Emporium::Code.new(code)
|
7
8
|
raise "invalid code" unless @code.valid?
|
8
|
-
@options = options.merge! code: @code.value
|
9
9
|
end
|
10
10
|
|
11
11
|
def fetch!
|
12
|
-
|
13
|
-
create ::Nokogiri::XML(open("#{@@service_url}?#{signed_query}"))
|
14
|
-
end
|
12
|
+
create @service.response
|
15
13
|
end
|
16
14
|
|
17
|
-
def
|
18
|
-
|
19
|
-
class_eval(<<-EOS)
|
20
|
-
def self.#{symbol}
|
21
|
-
@@#{symbol}
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.#{symbol}=(value)
|
25
|
-
@@#{symbol} = value
|
26
|
-
end
|
27
|
-
EOS
|
28
|
-
end
|
15
|
+
def use(service)
|
16
|
+
@service = service.new(code: @code.value)
|
29
17
|
end
|
30
18
|
|
31
|
-
class_option :access_key, :secret, :associate_tag
|
32
|
-
class_option :service, :service_url
|
33
|
-
|
34
19
|
def method_missing(name, *args)
|
35
20
|
if self.instance_variables.include? :"@#{name}"
|
36
21
|
self.instance_variable_get("@#{name}")
|
@@ -40,47 +25,10 @@ module Emporium
|
|
40
25
|
end
|
41
26
|
|
42
27
|
private
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
result.search("ItemAttributes").children.each do |value|
|
47
|
-
self.instance_variable_set("@#{value.name.downcase}", value.content)
|
48
|
-
end
|
28
|
+
def create(response)
|
29
|
+
response.search("ItemAttributes").children.each do |value|
|
30
|
+
self.instance_variable_set("@#{value.name.downcase}", value.content)
|
49
31
|
end
|
50
32
|
end
|
51
|
-
|
52
|
-
def params
|
53
|
-
{
|
54
|
-
"Service" => "AWSECommerceService",
|
55
|
-
"Operation" => "ItemLookup",
|
56
|
-
"IdType" => "UPC",
|
57
|
-
"ItemId" => @code.value,
|
58
|
-
"SearchIndex" => @options[:search_index] || "All",
|
59
|
-
"ResponseGroup" => @options[:response_group] || "Medium",
|
60
|
-
"Version" => @options[:version] || "2011-08-01",
|
61
|
-
"AssociateTag" => @@associate_tag,
|
62
|
-
"Timestamp" => Time.now.iso8601,
|
63
|
-
"AWSAccessKeyId" => @@access_key
|
64
|
-
}
|
65
|
-
end
|
66
|
-
|
67
|
-
def to_query(hash)
|
68
|
-
hash.sort.collect { |k, v| [encode(k), encode(v.to_s)].join("=") }.join("&")
|
69
|
-
end
|
70
|
-
|
71
|
-
def signed_query
|
72
|
-
digest = HMAC::SHA256.digest(@@secret, request)
|
73
|
-
signature = Base64.encode64(digest).chomp
|
74
|
-
to_query(params.merge "Signature" => signature)
|
75
|
-
end
|
76
|
-
|
77
|
-
def encode(value)
|
78
|
-
CGI.escape(value).gsub("%7E", "~").gsub("+", "%20")
|
79
|
-
end
|
80
|
-
|
81
|
-
def request
|
82
|
-
"GET\nwebservices.amazon.com\n/onca/xml\n#{to_query(params)}"
|
83
|
-
end
|
84
|
-
|
85
33
|
end
|
86
34
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Emporium
|
2
|
+
module Services
|
3
|
+
class Amazon
|
4
|
+
def initialize(options={})
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
def response
|
9
|
+
res = ::Nokogiri::XML(open("http://webservices.amazon.com/onca/xml?#{signed_query}"))
|
10
|
+
message = res.search('Message')
|
11
|
+
raise message.children.first.content unless message.empty?
|
12
|
+
res
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def params
|
17
|
+
{
|
18
|
+
"Service" => "AWSECommerceService",
|
19
|
+
"Operation" => "ItemLookup",
|
20
|
+
"IdType" => "UPC",
|
21
|
+
"ItemId" => @options[:code],
|
22
|
+
"SearchIndex" => @options[:search_index] || "All",
|
23
|
+
"ResponseGroup" => @options[:response_group] || "Medium",
|
24
|
+
"Version" => @options[:version] || "2011-08-01",
|
25
|
+
"AssociateTag" => @@associate_tag,
|
26
|
+
"Timestamp" => Time.now.iso8601,
|
27
|
+
"AWSAccessKeyId" => @@access_key
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_query(hash)
|
32
|
+
hash.sort.collect { |k, v| [encode(k), encode(v.to_s)].join("=") }.join("&")
|
33
|
+
end
|
34
|
+
|
35
|
+
def signed_query
|
36
|
+
digest = HMAC::SHA256.digest(@@secret, request)
|
37
|
+
signature = Base64.encode64(digest).chomp
|
38
|
+
to_query(params.merge "Signature" => signature)
|
39
|
+
end
|
40
|
+
|
41
|
+
def encode(value)
|
42
|
+
CGI.escape(value).gsub("%7E", "~").gsub("+", "%20")
|
43
|
+
end
|
44
|
+
|
45
|
+
def request
|
46
|
+
"GET\nwebservices.amazon.com\n/onca/xml\n#{to_query(params)}"
|
47
|
+
end
|
48
|
+
class << self
|
49
|
+
|
50
|
+
def configuration
|
51
|
+
yield self
|
52
|
+
end
|
53
|
+
|
54
|
+
def class_option(*symbols)
|
55
|
+
symbols.each do |symbol|
|
56
|
+
class_eval(<<-EOS)
|
57
|
+
def self.#{symbol}
|
58
|
+
@@#{symbol}
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.#{symbol}=(value)
|
62
|
+
@@#{symbol} = value
|
63
|
+
end
|
64
|
+
EOS
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class_option :access_key, :secret, :associate_tag
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/emporium/version.rb
CHANGED
data/lib/emporium.rb
CHANGED
@@ -1,40 +1,30 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
Product.associate_tag = CONFIG["associate_tag"]
|
9
|
-
Product.secret = CONFIG["secret"]
|
10
|
-
end
|
11
|
-
|
12
|
-
it "uses the amazon service" do
|
13
|
-
Product.service.should be :amazon
|
14
|
-
end
|
3
|
+
Emporium::Services::Amazon.configuration do |config|
|
4
|
+
config.access_key = CONFIG["access_key"]
|
5
|
+
config.associate_tag = CONFIG["associate_tag"]
|
6
|
+
config.secret = CONFIG["secret"]
|
7
|
+
end
|
15
8
|
|
9
|
+
describe Emporium::Product do
|
16
10
|
describe "#new" do
|
17
11
|
it "creates an instance from a upc" do
|
18
|
-
product = Product.new("036000241457")
|
19
|
-
product.should be_an_instance_of Product
|
12
|
+
product = Emporium::Product.new("036000241457")
|
13
|
+
product.should be_an_instance_of Emporium::Product
|
20
14
|
end
|
21
15
|
|
22
16
|
it "fails to create an instance if no upc is given" do
|
23
|
-
lambda { Product.new() }.should raise_error
|
17
|
+
lambda { Emporium::Product.new() }.should raise_error
|
24
18
|
end
|
25
19
|
|
26
20
|
it "fails to create an instance if invalid upc is given" do
|
27
|
-
lambda { Product.new("036000241452") }.should raise_error
|
28
|
-
end
|
29
|
-
|
30
|
-
it "has options in options if provided" do
|
31
|
-
product = Product.new("036000241457", secret: 'secret')
|
32
|
-
product.instance_eval { @options[:secret] }.should match 'secret'
|
21
|
+
lambda { Emporium::Product.new("036000241452") }.should raise_error
|
33
22
|
end
|
34
23
|
end
|
35
24
|
|
36
25
|
describe "#fetch!" do
|
37
|
-
product = Product.new("610839331574")
|
26
|
+
product = Emporium::Product.new("610839331574")
|
27
|
+
product.use Emporium::Services::Amazon
|
38
28
|
|
39
29
|
it "should fetch product information" do
|
40
30
|
lambda { product.fetch! }.should_not raise_error
|
@@ -44,19 +34,47 @@ describe Product do
|
|
44
34
|
product.fetch!
|
45
35
|
product.brand.should match 'Asus'
|
46
36
|
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#use" do
|
40
|
+
it "tells a product what service to use" do
|
41
|
+
product = Emporium::Product.new("610839331574")
|
42
|
+
product.use Emporium::Services::Amazon
|
43
|
+
product.service.should be_an_instance_of Emporium::Services::Amazon
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
47
|
|
48
|
+
describe Emporium::Services::Amazon do
|
49
|
+
describe "#new" do
|
50
|
+
it "should initialize with options" do
|
51
|
+
options = {some: "option"}
|
52
|
+
service = Emporium::Services::Amazon.new(options)
|
53
|
+
service.instance_variable_get('@options')[:some].should match "option"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "#response" do
|
58
|
+
it "should return an XML document" do
|
59
|
+
service = Emporium::Services::Amazon.new(code: "610839331574")
|
60
|
+
service.response.should be_a_kind_of ::Nokogiri::XML::Document
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should raise an error if nothing is found" do
|
64
|
+
lambda { Emporium::Services::Amazon.new(code: "036000241452").response }.should raise_error
|
65
|
+
end
|
48
66
|
end
|
49
67
|
end
|
50
68
|
|
51
|
-
describe Code do
|
69
|
+
describe Emporium::Code do
|
52
70
|
describe "#valid?" do
|
53
71
|
it "returns true for a valid UPC" do
|
54
|
-
code = Code.new("036000241457")
|
72
|
+
code = Emporium::Code.new("036000241457")
|
55
73
|
code.valid?.should be true
|
56
74
|
end
|
57
75
|
|
58
76
|
it "returns false for an invalid UPC" do
|
59
|
-
code = Code.new("036000241452")
|
77
|
+
code = Emporium::Code.new("036000241452")
|
60
78
|
code.valid?.should_not be true
|
61
79
|
end
|
62
80
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: emporium
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
version: 0.0.
|
4
|
+
prerelease: 6
|
5
|
+
version: 0.0.2.alpha
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Hugo Bastien
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-12-
|
13
|
+
date: 2011-12-05 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: nokogiri
|
@@ -64,6 +64,8 @@ files:
|
|
64
64
|
- lib/emporium.rb
|
65
65
|
- lib/emporium/code.rb
|
66
66
|
- lib/emporium/product.rb
|
67
|
+
- lib/emporium/services.rb
|
68
|
+
- lib/emporium/services/amazon.rb
|
67
69
|
- lib/emporium/version.rb
|
68
70
|
- spec/emporium/emporium_spec.rb
|
69
71
|
- spec/spec_helper.rb
|
@@ -84,9 +86,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
86
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
87
|
none: false
|
86
88
|
requirements:
|
87
|
-
- - "
|
89
|
+
- - ">"
|
88
90
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
91
|
+
version: 1.3.1
|
90
92
|
requirements: []
|
91
93
|
|
92
94
|
rubyforge_project: emporium
|