completelynovel-amazon-product-advertising-api 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +12 -0
- data/amazon-product-advertising-api.gemspec +3 -3
- data/lib/amazon_product_advertising_api/base.rb +9 -1
- data/lib/amazon_product_advertising_api/operations/base.rb +44 -9
- data/lib/amazon_product_advertising_api/operations/browse_node.rb +10 -5
- data/lib/amazon_product_advertising_api/operations/item.rb +27 -5
- data/lib/amazon_product_advertising_api/support.rb +9 -1
- metadata +3 -2
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Generate documentation for the amazon-product-advertising-api gem.'
|
6
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
7
|
+
rdoc.rdoc_dir = 'rdoc'
|
8
|
+
rdoc.title = 'AmazonProductAdvertisingApi'
|
9
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
10
|
+
rdoc.rdoc_files.include('README.rdoc')
|
11
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
12
|
+
end
|
@@ -2,15 +2,15 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{amazon-product-advertising-api}
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.5"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Jon Gilbraith"]
|
9
9
|
s.date = %q{2009-06-11}
|
10
10
|
s.description = %q{A nice rubyish interface to the Amazon Product Advertising API, formerly known as the Associates Web Service and before that the Amazon E-Commerce Service.}
|
11
11
|
s.email = %q{jon@completelynovel.com}
|
12
|
-
s.files = ["EXAMPLE.txt", "MIT-LICENSE", "README.rdoc", "amazon-product-advertising-api.gemspec", "lib/amazon_product_advertising_api", "lib/amazon_product_advertising_api/base.rb", "lib/amazon_product_advertising_api/operations", "lib/amazon_product_advertising_api/operations/base.rb", "lib/amazon_product_advertising_api/operations/browse_node.rb", "lib/amazon_product_advertising_api/operations/item.rb", "lib/amazon_product_advertising_api/support.rb", "lib/amazon_product_advertising_api.rb"]
|
13
|
-
s.has_rdoc =
|
12
|
+
s.files = ["Rakefile", "EXAMPLE.txt", "MIT-LICENSE", "README.rdoc", "amazon-product-advertising-api.gemspec", "lib/amazon_product_advertising_api", "lib/amazon_product_advertising_api/base.rb", "lib/amazon_product_advertising_api/operations", "lib/amazon_product_advertising_api/operations/base.rb", "lib/amazon_product_advertising_api/operations/browse_node.rb", "lib/amazon_product_advertising_api/operations/item.rb", "lib/amazon_product_advertising_api/support.rb", "lib/amazon_product_advertising_api.rb"]
|
13
|
+
s.has_rdoc = true
|
14
14
|
s.homepage = %q{http://github.com/completelynovel/amazon-product-advertising-api}
|
15
15
|
s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
|
16
16
|
s.require_paths = ["lib"]
|
@@ -1,5 +1,13 @@
|
|
1
|
-
module AmazonProductAdvertisingApi
|
1
|
+
module AmazonProductAdvertisingApi #:nodoc:
|
2
2
|
|
3
|
+
# This is the main base class where you define your config data. Setup like so:
|
4
|
+
# AmazonProductAdvertisingApi.base.access_key_id = <your Amazon AccessKeyId>
|
5
|
+
# There is no support for the secret key yet, so it's just your access key for now.
|
6
|
+
#
|
7
|
+
# You also setup your Associates codes for different regions here (the right one is supplied)
|
8
|
+
# based on what region you are requesting for.
|
9
|
+
# AmazonProductAdvertisingApi.base.associate_ids.ca = <your associates CA Affiliate key>
|
10
|
+
# AmazonProductAdvertisingApi.base.associate_ids.uk = <your associates UK Affiliate key>
|
3
11
|
class Base
|
4
12
|
|
5
13
|
cattr_accessor :access_key_id
|
@@ -1,23 +1,43 @@
|
|
1
|
-
module AmazonProductAdvertisingApi
|
2
|
-
module Operations
|
3
|
-
module Base
|
1
|
+
module AmazonProductAdvertisingApi #:nodoc:
|
2
|
+
module Operations #:nodoc:
|
3
|
+
module Base #:nodoc:
|
4
4
|
|
5
|
+
# This is the parent class of any Operations performed.
|
6
|
+
#
|
7
|
+
# Each class should have a constant defined called REQUEST_PARAMETERS which contains the available parameters
|
8
|
+
# as defined in the API docs. Each class should also override the parse method with a custom version to suit the
|
9
|
+
# particular pattern of XML returned for it.
|
10
|
+
#
|
11
|
+
# Subclasses should also override initialize to take any parameters the API defines as required, and follow the pattern
|
12
|
+
# of the region being the last parameter.
|
13
|
+
#
|
14
|
+
# Before doing that though it should call super back to this one.
|
5
15
|
class Request
|
6
|
-
|
16
|
+
|
17
|
+
# String - Amazon API calls can be sent to any of 6 regions, so this defines which one.
|
18
|
+
# It'll also use this data to pick the right Associates key to use.
|
7
19
|
attr_accessor :region
|
8
|
-
|
20
|
+
|
21
|
+
# String - The name of the Operation you want to perform, i.e. ItemSearch, ItemLookup, etc.
|
9
22
|
attr_accessor :operation
|
10
23
|
|
24
|
+
# String - This stores the request that gets sent to Amazon (for investigation if you want to look under the covers).
|
11
25
|
attr_accessor :request_uri
|
12
|
-
|
26
|
+
|
27
|
+
# String - This stores the raw data of the request response (again, for investigation if you want to look under the covers).
|
13
28
|
attr_accessor :raw_data
|
14
|
-
|
29
|
+
|
30
|
+
# Hpricot - This stores the raw data of the request response should you feel the need / desire to do some parsing yourself.
|
15
31
|
attr_accessor :hpricot_data
|
16
|
-
|
32
|
+
|
33
|
+
# Element - This is the root of the structure that the lib assembles from the data when parsed.
|
17
34
|
attr_accessor :response
|
18
35
|
|
36
|
+
# Boolean - All responses have a field saying whether the request was valid. Note that this refers to the format of the request, etc
|
37
|
+
# and not errors with the request parameters, etc. I.e. a lookup for an item that doesn't exsist is still valid.
|
19
38
|
attr_accessor :is_valid
|
20
39
|
|
40
|
+
# Array of Struct - Any errors will be added to this attribute and each has an attribute of code or message.
|
21
41
|
attr_accessor :errors
|
22
42
|
|
23
43
|
SERVICE_URLS = {
|
@@ -33,7 +53,8 @@ module AmazonProductAdvertisingApi
|
|
33
53
|
self.response = AmazonProductAdvertisingApi::Operations::Base::Element.new
|
34
54
|
self.errors = []
|
35
55
|
end
|
36
|
-
|
56
|
+
|
57
|
+
# This takes care of building request, performing it, storing the results, checking for errors then parsing the data (if the request was valid).
|
37
58
|
def query_amazon(params)
|
38
59
|
request_params = {}
|
39
60
|
request_params["AWSAccessKeyId"] = AmazonProductAdvertisingApi::Base.access_key_id
|
@@ -67,10 +88,12 @@ module AmazonProductAdvertisingApi
|
|
67
88
|
self.is_valid ? self.response : false
|
68
89
|
end
|
69
90
|
|
91
|
+
# The parse method of a request should be overwritted by any subclasses to account for different patterns in the XML.
|
70
92
|
def parse
|
71
93
|
raise "This should be being overridden by it's subclass to provide custom parsing for the particular operation concerned."
|
72
94
|
end
|
73
95
|
|
96
|
+
# Launches the request's query to Amazon (via query_amazon).
|
74
97
|
def run
|
75
98
|
self.query_amazon(params)
|
76
99
|
end
|
@@ -88,6 +111,12 @@ module AmazonProductAdvertisingApi
|
|
88
111
|
|
89
112
|
end
|
90
113
|
|
114
|
+
# XML data that is returned by Amazon gets built into a tree of nodes, which are made up of instances of this class.
|
115
|
+
# They represent the 'response element' entity within the API docs.
|
116
|
+
#
|
117
|
+
# As well as various having attributes it can also contain a collection and behave like an array.
|
118
|
+
#
|
119
|
+
# I think I might have got a bit confused with all this, will come back to this shortly to check.
|
91
120
|
class Element
|
92
121
|
|
93
122
|
include Enumerable
|
@@ -96,6 +125,7 @@ module AmazonProductAdvertisingApi
|
|
96
125
|
@contained_elements = []
|
97
126
|
end
|
98
127
|
|
128
|
+
# Defines a new accessor on the element and if supplied assigns that attribute a value.
|
99
129
|
def add_element(name, value = nil)
|
100
130
|
name = name.underscore
|
101
131
|
|
@@ -117,24 +147,29 @@ module AmazonProductAdvertisingApi
|
|
117
147
|
self.instance_eval("self.#{name}")
|
118
148
|
end
|
119
149
|
|
150
|
+
# Add an item to the element's internal collection.
|
120
151
|
def << element
|
121
152
|
@contained_elements << element
|
122
153
|
end
|
123
154
|
|
155
|
+
# Iterate over the element's internal collection.
|
124
156
|
def each(&block)
|
125
157
|
@contained_elements.each do |element|
|
126
158
|
yield element
|
127
159
|
end
|
128
160
|
end
|
129
161
|
|
162
|
+
# Return the value of the internal collection's element at the given position.
|
130
163
|
def [] position
|
131
164
|
@contained_elements[position]
|
132
165
|
end
|
133
166
|
|
167
|
+
# Return the first element of the internal collection.
|
134
168
|
def first
|
135
169
|
@contained_elements.first
|
136
170
|
end
|
137
171
|
|
172
|
+
# Return the number of elements in the internal collection.
|
138
173
|
def size
|
139
174
|
@contained_elements.size
|
140
175
|
end
|
@@ -1,7 +1,8 @@
|
|
1
|
-
module AmazonProductAdvertisingApi
|
2
|
-
module Operations
|
3
|
-
module BrowseNode
|
1
|
+
module AmazonProductAdvertisingApi #:nodoc:
|
2
|
+
module Operations #:nodoc:
|
3
|
+
module BrowseNode #:nodoc:
|
4
4
|
|
5
|
+
# A class to represent the BrowseNodeLookup Operation. See AmazonProductAdvertisingApi::Operations::Base::Request for info relating to all Requests.
|
5
6
|
class BrowseNodeLookup < AmazonProductAdvertisingApi::Operations::Base::Request
|
6
7
|
|
7
8
|
REQUEST_PARAMETERS = :browse_node_id, :response_group
|
@@ -9,7 +10,8 @@ module AmazonProductAdvertisingApi
|
|
9
10
|
REQUEST_PARAMETERS.each do |param|
|
10
11
|
self.send(:attr_accessor, param)
|
11
12
|
end
|
12
|
-
|
13
|
+
|
14
|
+
# BrowseNodeLookup only requires a browse_node_id to be specified.
|
13
15
|
def initialize(browse_node_id, region = :uk)
|
14
16
|
super()
|
15
17
|
|
@@ -18,6 +20,7 @@ module AmazonProductAdvertisingApi
|
|
18
20
|
self.region = region
|
19
21
|
end
|
20
22
|
|
23
|
+
# BrowseNode methods return xml consisting of a BrowseNodes tag with several BrowseNode tags inside.
|
21
24
|
def parse
|
22
25
|
self.response.add_element("BrowseNodes", AmazonProductAdvertisingApi::Operations::Base::Element.new)
|
23
26
|
|
@@ -29,7 +32,7 @@ module AmazonProductAdvertisingApi
|
|
29
32
|
queue << [new_element, element.containers]
|
30
33
|
|
31
34
|
queue.each do |pair|
|
32
|
-
current_element
|
35
|
+
current_element = pair[0]
|
33
36
|
current_children = pair[1]
|
34
37
|
|
35
38
|
current_children.each do |child|
|
@@ -51,6 +54,8 @@ module AmazonProductAdvertisingApi
|
|
51
54
|
end
|
52
55
|
|
53
56
|
private
|
57
|
+
# This simply looks at the defined parameters and creates a hash of the ones that have values assigned.
|
58
|
+
# Need to work out a way of doing this so I don't need to keep defining exactly the same method in each class.
|
54
59
|
def params
|
55
60
|
REQUEST_PARAMETERS.inject({}) do |parameters, parameter|
|
56
61
|
parameters[parameter] = eval("self.#{parameter}") unless eval("self.#{parameter}.nil?")
|
@@ -1,9 +1,11 @@
|
|
1
|
-
module AmazonProductAdvertisingApi
|
2
|
-
module Operations
|
3
|
-
module Item
|
1
|
+
module AmazonProductAdvertisingApi #:nodoc:
|
2
|
+
module Operations #:nodoc:
|
3
|
+
module Item #:nodoc:
|
4
4
|
|
5
|
+
# Gets mixed into each of the classes in AmazonProductAdvertisingApi::Operations::Item for common behaviours.
|
5
6
|
module Common
|
6
7
|
|
8
|
+
# Item methods return xml consisting of an Items tag with several Item tags inside.
|
7
9
|
def parse
|
8
10
|
self.response.add_element("Items", AmazonProductAdvertisingApi::Operations::Base::Element.new)
|
9
11
|
|
@@ -38,6 +40,9 @@ module AmazonProductAdvertisingApi
|
|
38
40
|
|
39
41
|
end
|
40
42
|
|
43
|
+
# A class to represent the ItemSearch Operation. See AmazonProductAdvertisingApi::Operations::Base::Request for info relating to all Requests.
|
44
|
+
#
|
45
|
+
# It mixes in AmazonProductAdvertisingApi::Operations::Item::Common for it's parse method.
|
41
46
|
class ItemSearch < AmazonProductAdvertisingApi::Operations::Base::Request
|
42
47
|
|
43
48
|
include Common
|
@@ -51,7 +56,8 @@ module AmazonProductAdvertisingApi
|
|
51
56
|
REQUEST_PARAMETERS.each do |param|
|
52
57
|
self.send(:attr_accessor, param)
|
53
58
|
end
|
54
|
-
|
59
|
+
|
60
|
+
# ItemSearch requires keywords and a search index to be specified.
|
55
61
|
def initialize(keywords, search_index = "Books", region = :uk)
|
56
62
|
super()
|
57
63
|
|
@@ -62,6 +68,8 @@ module AmazonProductAdvertisingApi
|
|
62
68
|
end
|
63
69
|
|
64
70
|
private
|
71
|
+
# This simply looks at the defined parameters and creates a hash of the ones that have values assigned.
|
72
|
+
# Need to work out a way of doing this so I don't need to keep defining exactly the same method in each class.
|
65
73
|
def params
|
66
74
|
REQUEST_PARAMETERS.inject({}) do |parameters, parameter|
|
67
75
|
parameters[parameter] = eval("self.#{parameter}") unless eval("self.#{parameter}.nil?")
|
@@ -71,6 +79,9 @@ module AmazonProductAdvertisingApi
|
|
71
79
|
|
72
80
|
end
|
73
81
|
|
82
|
+
# A class to represent the ItemLookup Operation. See AmazonProductAdvertisingApi::Operations::Base::Request for info relating to all Requests.
|
83
|
+
#
|
84
|
+
# It mixes in AmazonProductAdvertisingApi::Operations::Item::Common for it's parse method.
|
74
85
|
class ItemLookup < AmazonProductAdvertisingApi::Operations::Base::Request
|
75
86
|
|
76
87
|
include Common
|
@@ -82,6 +93,7 @@ module AmazonProductAdvertisingApi
|
|
82
93
|
self.send(:attr_accessor, param)
|
83
94
|
end
|
84
95
|
|
96
|
+
# ItemLookup only requires an item id (ASIN) to be specified.
|
85
97
|
def initialize(item_id, region = :uk)
|
86
98
|
super()
|
87
99
|
|
@@ -91,6 +103,8 @@ module AmazonProductAdvertisingApi
|
|
91
103
|
end
|
92
104
|
|
93
105
|
private
|
106
|
+
# This simply looks at the defined parameters and creates a hash of the ones that have values assigned.
|
107
|
+
# Need to work out a way of doing this so I don't need to keep defining exactly the same method in each class.
|
94
108
|
def params
|
95
109
|
REQUEST_PARAMETERS.inject({}) do |parameters, parameter|
|
96
110
|
parameters[parameter] = eval("self.#{parameter}") unless eval("self.#{parameter}.nil?")
|
@@ -99,7 +113,12 @@ module AmazonProductAdvertisingApi
|
|
99
113
|
end
|
100
114
|
|
101
115
|
end
|
102
|
-
|
116
|
+
|
117
|
+
# A class to represent the SimilarityLookup Operation. See AmazonProductAdvertisingApi::Operations::Base::Request for info relating to all Requests.
|
118
|
+
#
|
119
|
+
# Despite not following the same naming convention of other classes in this module, it returns data structured the same way so has been put here.
|
120
|
+
#
|
121
|
+
# It mixes in AmazonProductAdvertisingApi::Operations::Item::Common for it's parse method.
|
103
122
|
class SimilarityLookup < AmazonProductAdvertisingApi::Operations::Base::Request
|
104
123
|
|
105
124
|
include Common
|
@@ -110,6 +129,7 @@ module AmazonProductAdvertisingApi
|
|
110
129
|
self.send(:attr_accessor, param)
|
111
130
|
end
|
112
131
|
|
132
|
+
# SimilarityLookup only requires an item id (ASIN) to be specified.
|
113
133
|
def initialize(item_id, region = :uk)
|
114
134
|
super()
|
115
135
|
|
@@ -119,6 +139,8 @@ module AmazonProductAdvertisingApi
|
|
119
139
|
end
|
120
140
|
|
121
141
|
private
|
142
|
+
# This simply looks at the defined parameters and creates a hash of the ones that have values assigned.
|
143
|
+
# Need to work out a way of doing this so I don't need to keep defining exactly the same method in each class.
|
122
144
|
def params
|
123
145
|
REQUEST_PARAMETERS.inject({}) do |parameters, parameter|
|
124
146
|
parameters[parameter] = eval("self.#{parameter}") unless eval("self.#{parameter}.nil?")
|
@@ -1,6 +1,9 @@
|
|
1
|
-
module AmazonProductAdvertisingApi
|
1
|
+
module AmazonProductAdvertisingApi #:nodoc:
|
2
2
|
|
3
|
+
# Some extensions to the Class class.
|
3
4
|
class Class
|
5
|
+
|
6
|
+
# Pleasant syntax for Class attribute readers.
|
4
7
|
def cattr_reader(sym)
|
5
8
|
class_eval(<<-EOS, __FILE__, __LINE__)
|
6
9
|
unless defined? @@#{sym} # unless defined? @@hair_colors
|
@@ -17,6 +20,7 @@ module AmazonProductAdvertisingApi
|
|
17
20
|
EOS
|
18
21
|
end
|
19
22
|
|
23
|
+
# Pleasant syntax for Class attribute writers.
|
20
24
|
def cattr_writer(sym)
|
21
25
|
class_eval(<<-EOS, __FILE__, __LINE__)
|
22
26
|
unless defined? @@#{sym} # unless defined? @@hair_colors
|
@@ -29,6 +33,7 @@ module AmazonProductAdvertisingApi
|
|
29
33
|
EOS
|
30
34
|
end
|
31
35
|
|
36
|
+
# Pleasant syntax for Class attribute accessors.
|
32
37
|
def cattr_accessor(sym)
|
33
38
|
cattr_reader(sym)
|
34
39
|
cattr_writer(sym)
|
@@ -36,8 +41,10 @@ module AmazonProductAdvertisingApi
|
|
36
41
|
|
37
42
|
end
|
38
43
|
|
44
|
+
# Some extensions to the String class.
|
39
45
|
class String
|
40
46
|
|
47
|
+
# Converts strings from under_score format to CamelCase
|
41
48
|
def camelize(first_letter_in_uppercase = true)
|
42
49
|
if first_letter_in_uppercase
|
43
50
|
self.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
@@ -46,6 +53,7 @@ module AmazonProductAdvertisingApi
|
|
46
53
|
end
|
47
54
|
end
|
48
55
|
|
56
|
+
# Converts strings from CamelCase format to under_score.
|
49
57
|
def underscore
|
50
58
|
self.to_s.gsub(/::/, '/').
|
51
59
|
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: completelynovel-amazon-product-advertising-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Gilbraith
|
@@ -22,6 +22,7 @@ extensions: []
|
|
22
22
|
extra_rdoc_files: []
|
23
23
|
|
24
24
|
files:
|
25
|
+
- Rakefile
|
25
26
|
- EXAMPLE.txt
|
26
27
|
- MIT-LICENSE
|
27
28
|
- README.rdoc
|
@@ -34,7 +35,7 @@ files:
|
|
34
35
|
- lib/amazon_product_advertising_api/operations/item.rb
|
35
36
|
- lib/amazon_product_advertising_api/support.rb
|
36
37
|
- lib/amazon_product_advertising_api.rb
|
37
|
-
has_rdoc:
|
38
|
+
has_rdoc: true
|
38
39
|
homepage: http://github.com/completelynovel/amazon-product-advertising-api
|
39
40
|
post_install_message:
|
40
41
|
rdoc_options:
|