amazon_product_api 0.1.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/.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: []
|