amazon_product_api 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +6 -0
- data/README.markdown +8 -0
- data/Rakefile +1 -0
- data/amazon_product_api.gemspec +24 -0
- data/lib/amazon_product_api.rb +107 -0
- data/lib/amazon_product_api/version.rb +3 -0
- metadata +52 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# amazon_product_api
|
2
|
+
|
3
|
+
This is a (currently extremely minimal) Ruby client for the Amazon
|
4
|
+
Product Advertising REST API.
|
5
|
+
|
6
|
+
It takes care of signing your API requests correctly, but *does not*
|
7
|
+
parse XML response data, or serialize the response data to Ruby data
|
8
|
+
structures.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "amazon_product_api/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "amazon_product_api"
|
7
|
+
s.version = AmazonProductAPI::VERSION
|
8
|
+
s.authors = ["Nick Dainty"]
|
9
|
+
s.email = ["nick@npad.co.uk"]
|
10
|
+
s.homepage = "https://github.com/nickpad/amazon_product_api"
|
11
|
+
s.summary = %q{Amazon Product Advertising API Client}
|
12
|
+
s.description = %q{An extremely minimal client for Amazon Product Advertising REST API}
|
13
|
+
|
14
|
+
s.rubyforge_project = "amazon_product_api"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
# s.add_development_dependency "rspec"
|
23
|
+
# s.add_runtime_dependency "rest-client"
|
24
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'net/http'
|
3
|
+
require 'openssl'
|
4
|
+
require 'time'
|
5
|
+
require 'amazon_product_api/version'
|
6
|
+
|
7
|
+
# A very simple client for the Amazon Product Advertising API.
|
8
|
+
class AmazonProductAPI
|
9
|
+
ENDPOINTS = {
|
10
|
+
:ca => 'https://ecs.amazonaws.ca/onca/xml',
|
11
|
+
:cn => 'https://webservices.amazon.cn/onca/xml',
|
12
|
+
:de => 'https://ecs.amazonaws.de/onca/xml',
|
13
|
+
:es => 'https://webservices.amazon.es/onca/xml',
|
14
|
+
:fr => 'https://ecs.amazonaws.fr/onca/xml',
|
15
|
+
:it => 'https://webservices.amazon.it/onca/xml',
|
16
|
+
:jp => 'https://ecs.amazonaws.jp/onca/xml',
|
17
|
+
:uk => 'https://ecs.amazonaws.co.uk/onca/xml',
|
18
|
+
:us => 'https://webservices.amazon.com/onca/xml'
|
19
|
+
}
|
20
|
+
|
21
|
+
SERVICE = 'AWSECommerceService'
|
22
|
+
API_VERSION = '2011-08-01'
|
23
|
+
AMPERSAND = '&'
|
24
|
+
COMMA = ','
|
25
|
+
PERCENT = '%'
|
26
|
+
HTTPS = 'https'
|
27
|
+
USER_AGENT = "amazon_product_api #{VERSION}"
|
28
|
+
HEADERS = {'User-Agent' => USER_AGENT, 'Accept' => 'application/xml'}
|
29
|
+
DIGEST = OpenSSL::Digest::SHA256.new
|
30
|
+
ENCODE = /([^a-zA-Z0-9_.~-]+)/
|
31
|
+
|
32
|
+
attr_reader :connection
|
33
|
+
|
34
|
+
# Possible locale values are - :ca, :cn, :de, :es, :fr, :it, :jp, :uk, :us
|
35
|
+
#
|
36
|
+
# @param locale [Symbol] locale corresponding to an API endpoint
|
37
|
+
# @param access_key_id [String] your Amazon access key ID
|
38
|
+
# @param secret_access_key [String] your Amazon secret access key
|
39
|
+
# @param associate_tag [String] your Amazon associate tag
|
40
|
+
def initialize(locale, access_key_id, secret_access_key, associate_tag)
|
41
|
+
# Check that the locale provided maps to an endpoint string:
|
42
|
+
raise ArgumentError, "invalid locale '#{locale}'" if ENDPOINTS[locale].nil?
|
43
|
+
|
44
|
+
@endpoint = URI.parse(ENDPOINTS[locale])
|
45
|
+
@access_key_id = access_key_id
|
46
|
+
@secret_access_key = secret_access_key
|
47
|
+
@associate_tag = associate_tag
|
48
|
+
@connection = Net::HTTP.new(@endpoint.host, @endpoint.port)
|
49
|
+
@default_params = {
|
50
|
+
'Service' => SERVICE,
|
51
|
+
'Version' => API_VERSION,
|
52
|
+
'AWSAccessKeyId' => @access_key_id,
|
53
|
+
'AssociateTag' => @associate_tag
|
54
|
+
}
|
55
|
+
|
56
|
+
if @endpoint.scheme == HTTPS
|
57
|
+
@connection.use_ssl = true
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# @param operation [String] the operation name
|
62
|
+
# @param response_groups [Array<String>] a list of response groups
|
63
|
+
# @param operation_params [Hash] all other parameters required by the operation
|
64
|
+
# @return [Net::HTTPResponse]
|
65
|
+
def get(operation, response_groups, operation_params = {})
|
66
|
+
base_params = {
|
67
|
+
'Operation' => operation,
|
68
|
+
'ResponseGroup' => response_groups.join(COMMA),
|
69
|
+
'Timestamp' => Time.now.xmlschema
|
70
|
+
}
|
71
|
+
|
72
|
+
unsigned_params = operation_params.merge(@default_params.merge(base_params))
|
73
|
+
|
74
|
+
signed_params = unsigned_params.merge({'Signature' => signature(unsigned_params)})
|
75
|
+
|
76
|
+
request_uri = @endpoint.dup
|
77
|
+
request_uri.query = query_string(signed_params)
|
78
|
+
|
79
|
+
@connection.request(Net::HTTP::Get.new(request_uri.to_s, HEADERS))
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
# @param string [String] the string to URL encode
|
85
|
+
# @return [String] the URL encoded string
|
86
|
+
def url_encode(string)
|
87
|
+
string.gsub(ENCODE) do
|
88
|
+
PERCENT + $1.unpack('H2' * $1.bytesize).join(PERCENT).upcase
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# @param params [Hash]
|
93
|
+
# @return [String]
|
94
|
+
def query_string(params)
|
95
|
+
params.map do |key, value|
|
96
|
+
"%s=%s" % [key, url_encode(value)]
|
97
|
+
end.sort.join(AMPERSAND)
|
98
|
+
end
|
99
|
+
|
100
|
+
# @param params [Hash]
|
101
|
+
# @return [String] the request signature
|
102
|
+
def signature(params)
|
103
|
+
signable = "GET\n%s\n%s\n%s" % [@endpoint.host, @endpoint.path, query_string(params)]
|
104
|
+
hmac = OpenSSL::HMAC.digest(DIGEST, @secret_access_key, signable)
|
105
|
+
Base64.encode64(hmac).chomp
|
106
|
+
end
|
107
|
+
end
|
metadata
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: amazon_product_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nick Dainty
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-14 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: An extremely minimal client for Amazon Product Advertising REST API
|
15
|
+
email:
|
16
|
+
- nick@npad.co.uk
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- Gemfile
|
23
|
+
- README.markdown
|
24
|
+
- Rakefile
|
25
|
+
- amazon_product_api.gemspec
|
26
|
+
- lib/amazon_product_api.rb
|
27
|
+
- lib/amazon_product_api/version.rb
|
28
|
+
homepage: https://github.com/nickpad/amazon_product_api
|
29
|
+
licenses: []
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
requirements: []
|
47
|
+
rubyforge_project: amazon_product_api
|
48
|
+
rubygems_version: 1.8.11
|
49
|
+
signing_key:
|
50
|
+
specification_version: 3
|
51
|
+
summary: Amazon Product Advertising API Client
|
52
|
+
test_files: []
|