amazonian 0.0.1
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/.gitignore +5 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +33 -0
- data/README.rdoc +36 -0
- data/Rakefile +2 -0
- data/amazonian.gemspec +32 -0
- data/lib/amazonian.rb +116 -0
- data/lib/amazonian/version.rb +3 -0
- data/spec/amazonian_spec.rb +2 -0
- metadata +131 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
amazonian (0.0.1)
|
5
|
+
crack
|
6
|
+
hashie
|
7
|
+
httpclient
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
crack (0.1.8)
|
13
|
+
diff-lcs (1.1.2)
|
14
|
+
hashie (0.4.0)
|
15
|
+
httpclient (2.1.5.2)
|
16
|
+
rspec (2.1.0)
|
17
|
+
rspec-core (~> 2.1.0)
|
18
|
+
rspec-expectations (~> 2.1.0)
|
19
|
+
rspec-mocks (~> 2.1.0)
|
20
|
+
rspec-core (2.1.0)
|
21
|
+
rspec-expectations (2.1.0)
|
22
|
+
diff-lcs (~> 1.1.2)
|
23
|
+
rspec-mocks (2.1.0)
|
24
|
+
|
25
|
+
PLATFORMS
|
26
|
+
ruby
|
27
|
+
|
28
|
+
DEPENDENCIES
|
29
|
+
amazonian!
|
30
|
+
crack
|
31
|
+
hashie
|
32
|
+
httpclient
|
33
|
+
rspec
|
data/README.rdoc
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
== Status
|
2
|
+
This project is in active development as of 2010-11.
|
3
|
+
|
4
|
+
Currently it can be used as a rails plugin, and maybe as a gem (untested).
|
5
|
+
|
6
|
+
== Installation
|
7
|
+
|
8
|
+
Copy or symlink into your application's /lib folder.
|
9
|
+
|
10
|
+
In your ApplicationController:
|
11
|
+
|
12
|
+
class ApplicationController < ActionController::Base
|
13
|
+
include Amazonian
|
14
|
+
end
|
15
|
+
|
16
|
+
Then create an initializer in config/initializers:
|
17
|
+
require 'amazonian'
|
18
|
+
Amazonian.setup do |config|
|
19
|
+
config.secret = 'ZkD9VorhnJjoPxZp8S/bP0K3G4NBQPNQrfU4OOUn'
|
20
|
+
config.key = 'AKIAJCTUFLKJWEVW6XVQ'
|
21
|
+
#config.debug = true
|
22
|
+
end
|
23
|
+
|
24
|
+
== Usage
|
25
|
+
Amazonian.asin "1430218150"
|
26
|
+
#=> #<Amazonian::Item>
|
27
|
+
|
28
|
+
#soon:
|
29
|
+
Amazonian.search "The art of Computer Programming" #Title
|
30
|
+
Amazonian.search "978-0201853926" #ISBN-13
|
31
|
+
Amazonian.search "0201853922" #ISBN-10
|
32
|
+
Amazonian.search "<whateveryouwant>" #Anything you might put in the search box on Amazon.com.
|
33
|
+
|
34
|
+
== Info
|
35
|
+
|
36
|
+
For more information on the REST calls, have a look at the whole Amazon E-Commerce-API[http://docs.amazonwebservices.com/AWSEcommerceService/4-0/].
|
data/Rakefile
ADDED
data/amazonian.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "amazonian/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "amazonian"
|
7
|
+
s.version = Amazonian::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Robert L. Carpenter"]
|
10
|
+
s.email = ["robacarp@robacarp.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{Easy to use ruby module for the Amazon Product Advertising API}
|
13
|
+
s.description = %q{Easy to use ruby module for the Amazon Product Advertising API}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_development_dependency "rspec"
|
21
|
+
|
22
|
+
s.add_dependency "hashie"
|
23
|
+
s.add_dependency "crack"
|
24
|
+
s.add_dependency "patron"
|
25
|
+
#s.add_dependency "httpclient"
|
26
|
+
#s.add_dependency "crack/xml"
|
27
|
+
#included in ruby?
|
28
|
+
#s.add_dependency "cgi"
|
29
|
+
#um
|
30
|
+
#s.add_dependency "Base64"
|
31
|
+
#s.add_dependency "logger"
|
32
|
+
end
|
data/lib/amazonian.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
module Amazonian
|
2
|
+
@@host = 'webservices.amazon.com'
|
3
|
+
@@path = '/onca/xml'
|
4
|
+
@@digest = OpenSSL::Digest::Digest.new('sha256')
|
5
|
+
@@logger = Logger.new(STDERR)
|
6
|
+
@@patron = Patron::Session.new
|
7
|
+
@@last_response = nil
|
8
|
+
@@key = ''
|
9
|
+
@@secret = ''
|
10
|
+
@@debug = false
|
11
|
+
|
12
|
+
mattr_reader :host,:path,:digest,:patron,:last_response
|
13
|
+
mattr_accessor :key,:secret,:debug
|
14
|
+
|
15
|
+
#Configure the patron session
|
16
|
+
@@patron.timeout = 10
|
17
|
+
|
18
|
+
# Configure the basic request parameters for Amazonian.
|
19
|
+
def self.setup
|
20
|
+
yield self if block_given?
|
21
|
+
end
|
22
|
+
|
23
|
+
# Performs an +ItemLookup+ REST call against the Amazon API.
|
24
|
+
#
|
25
|
+
# Expects an ASIN (Amazon Standard Identification Number) and returns an +Item+:
|
26
|
+
#
|
27
|
+
# item = lookup '1430218150'
|
28
|
+
# item.title
|
29
|
+
# => "Learn Objective-C on the Mac (Learn Series)"
|
30
|
+
#
|
31
|
+
# ==== Options:
|
32
|
+
#
|
33
|
+
# Additional parameters for the API call like this:
|
34
|
+
#
|
35
|
+
# lookup(asin, :ResponseGroup => :Medium)
|
36
|
+
#
|
37
|
+
def self.asin(asin, params={})
|
38
|
+
params = params.merge :Operation => :ItemLookup, :ItemId => asin
|
39
|
+
xml = self.call params
|
40
|
+
Item.new xml
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def self.call(params)
|
46
|
+
raise "you have to configure ASIN: 'configure :secret => 'your-secret', :key => 'your-key''" if @@key.nil? || @@secret.nil?
|
47
|
+
|
48
|
+
#get the signed query, and assemble the querystring
|
49
|
+
log :debug, "calling with params=#{params}" if @@debug
|
50
|
+
signed = assemble_querystring params
|
51
|
+
url = "http://#{@@host}#{@@path}?#{signed}"
|
52
|
+
|
53
|
+
log :info, "performing rest call to url='#{url}'" if @@debug
|
54
|
+
@@last_response = @@patron.get url
|
55
|
+
|
56
|
+
# force utf-8 chars, works only on 1.9 string
|
57
|
+
log :debug, "got response='#{@@last_response}'" if @@debug
|
58
|
+
|
59
|
+
#parse the response and return it
|
60
|
+
Crack::XML.parse @@last_response.body
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.assemble_querystring(params)
|
64
|
+
# Nice tutorial http://cloudcarpenters.com/blog/amazon_products_api_request_signing/
|
65
|
+
params[:Service] = :AWSECommerceService
|
66
|
+
params[:AWSAccessKeyId] = @@key
|
67
|
+
|
68
|
+
# UTC timestamp needed for signing
|
69
|
+
params[:Timestamp] = Time.now.utc.strftime '%Y-%m-%dT%H:%M:%SZ'
|
70
|
+
|
71
|
+
# CGI escape each param
|
72
|
+
# signing needs to order the query alphabetically
|
73
|
+
query = params.map{|key, value| "#{key}=#{CGI.escape(value.to_s)}" }.sort.join('&')
|
74
|
+
|
75
|
+
sign_query query
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.sign_query(query)
|
79
|
+
# Sign the entire get-request (not just the querystring)
|
80
|
+
# possible gotcha if Patron starts using more/different headers.
|
81
|
+
request_to_sign = %Q{GET\n#{@@host}\n#{@@path}\n#{query}}
|
82
|
+
|
83
|
+
# Sign it.
|
84
|
+
hmac = OpenSSL::HMAC.digest(@@digest, @@secret, request_to_sign)
|
85
|
+
|
86
|
+
# Don't forget to remove the newline from base64
|
87
|
+
signature = CGI.escape(Base64.encode64(hmac).chomp)
|
88
|
+
|
89
|
+
"#{query}&Signature=#{signature}"
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.log(severity, message)
|
93
|
+
@@logger.send severity, message if @@logger
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
# =Item
|
98
|
+
#
|
99
|
+
# The +Item+ class is a wrapper for the Amazon XML-REST-Response.
|
100
|
+
#
|
101
|
+
# A Hashie::Mash is used for the internal data representation and can be accessed over the +raw+ attribute.
|
102
|
+
#
|
103
|
+
class Item
|
104
|
+
|
105
|
+
attr_reader :raw
|
106
|
+
|
107
|
+
def initialize(hash)
|
108
|
+
@raw = Hashie::Mash.new(hash).ItemLookupResponse.Items.Item
|
109
|
+
end
|
110
|
+
|
111
|
+
def title
|
112
|
+
@raw.ItemAttributes.Title
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: amazonian
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Robert L. Carpenter
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-11-26 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: hashie
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: crack
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :runtime
|
62
|
+
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: patron
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
type: :runtime
|
76
|
+
version_requirements: *id004
|
77
|
+
description: Easy to use ruby module for the Amazon Product Advertising API
|
78
|
+
email:
|
79
|
+
- robacarp@robacarp.com
|
80
|
+
executables: []
|
81
|
+
|
82
|
+
extensions: []
|
83
|
+
|
84
|
+
extra_rdoc_files: []
|
85
|
+
|
86
|
+
files:
|
87
|
+
- .gitignore
|
88
|
+
- Gemfile
|
89
|
+
- Gemfile.lock
|
90
|
+
- README.rdoc
|
91
|
+
- Rakefile
|
92
|
+
- amazonian.gemspec
|
93
|
+
- lib/amazonian.rb
|
94
|
+
- lib/amazonian/version.rb
|
95
|
+
- spec/amazonian_spec.rb
|
96
|
+
has_rdoc: true
|
97
|
+
homepage: ""
|
98
|
+
licenses: []
|
99
|
+
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options: []
|
102
|
+
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
hash: 3
|
111
|
+
segments:
|
112
|
+
- 0
|
113
|
+
version: "0"
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
hash: 3
|
120
|
+
segments:
|
121
|
+
- 0
|
122
|
+
version: "0"
|
123
|
+
requirements: []
|
124
|
+
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 1.3.7
|
127
|
+
signing_key:
|
128
|
+
specification_version: 3
|
129
|
+
summary: Easy to use ruby module for the Amazon Product Advertising API
|
130
|
+
test_files:
|
131
|
+
- spec/amazonian_spec.rb
|