completelynovel-amazon-product-advertising-api 0.0.2

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/EXAMPLE.rdoc ADDED
@@ -0,0 +1,81 @@
1
+ require 'rubygems'
2
+ require 'amazon_product_advertising_api'
3
+ # Setup your API key - in an initializer or something like that
4
+ AmazonProductAdvertisingApi::Base.api_key = "<insert api key here>"
5
+
6
+ # Setup Associates IDs for whichever regions you're selling to
7
+ AmazonProductAdvertisingApi::Base.associate_ids.uk = "<insert UK Associate ID here>"
8
+ AmazonProductAdvertisingApi::Base.associate_ids.us = "<insert US Associate ID here>"
9
+
10
+ lookup = AmazonProductAdvertisingApi::Operations::Item::ItemLookup.new("0201485419")
11
+ lookup.run
12
+
13
+ # Returned XML, tidied
14
+ # <?xml version="1.0"?>
15
+ # <ItemLookupResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2005-10-05">
16
+ # <OperationRequest>
17
+ # <RequestId>d6c19392-7710-4b05-ad9c-1637755170d8</RequestId>
18
+ # <Arguments>
19
+ # <Argument Name="Operation" Value="ItemLookup"/>
20
+ # <Argument Name="Service" Value="AWSECommerceService"/>
21
+ # <Argument Name="ItemId" Value="0201485419"/>
22
+ # <Argument Name="AWSAccessKeyId" Value="<your api key>"/>
23
+ # </Arguments>
24
+ # <RequestProcessingTime>0.0376290000000000</RequestProcessingTime>
25
+ # </OperationRequest>
26
+ # <Items>
27
+ # <Request>
28
+ # <IsValid>True</IsValid>
29
+ # <ItemLookupRequest>
30
+ # <Condition>New</Condition>
31
+ # <DeliveryMethod>Ship</DeliveryMethod>
32
+ # <IdType>ASIN</IdType>
33
+ # <MerchantId>Amazon</MerchantId>
34
+ # <OfferPage>1</OfferPage>
35
+ # <ItemId>0201485419</ItemId>
36
+ # <ResponseGroup>Small</ResponseGroup>
37
+ # <ReviewPage>1</ReviewPage>
38
+ # </ItemLookupRequest>
39
+ # </Request>
40
+ # <Item>
41
+ # <ASIN>0201485419</ASIN>
42
+ # <DetailPageURL>http://www.amazon.co.uk/Art-Computer-Programming-Information-Processing/dp/0201485419%3FSubscriptionId%3D<your api key>%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0201485419</DetailPageURL>
43
+ # <ItemAttributes>git
44
+ # <Author>Donald E. Knuth</Author>
45
+ # <Manufacturer>Addison Wesley</Manufacturer>
46
+ # <ProductGroup>Book</ProductGroup>
47
+ # <Title>The Art of Computer Programming: v. 1-3: Vol 1-3 (Series in Computer Science &amp; Information Processing)</Title>
48
+ # </ItemAttributes>
49
+ # </Item>
50
+ # </Items>
51
+ # </ItemLookupResponse>
52
+
53
+ lookup.response.items.size
54
+ => 1
55
+
56
+ lookup.response.items.first
57
+ => #<AmazonProductAdvertisingApi::Item:0x139154c @detail_page_url="http://www.amazon.co.uk/Art-Computer-Programming-Information-Processing/dp/0201485419%3FSubscriptionId%3D<your api key>%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0201485419", @item_attributes=#<AmazonProductAdvertisingApi::Container:0x1391448 @manufacturer="Addison Wesley", @product_group="Book", @title="The Art of Computer Programming: v. 1-3: Vol 1-3 (Series in Computer Science &amp; Information Processing)", @author="Donald E. Knuth">, @asin="0201485419">
58
+
59
+ lookup.response.items.first.asin
60
+ => "0201485419"
61
+
62
+ # ItemAttributes is a container element, doesn't return a string
63
+ lookup.response.items.first.item_attributes
64
+ => #<AmazonProductAdvertisingApi::Container:0x1391448 @manufacturer="Addison Wesley", @product_group="Book", @title="The Art of Computer Programming: v. 1-3: Vol 1-3 (Series in Computer Science &amp; Information Processing)", @author="Donald E. Knuth">
65
+
66
+ lookup.response.items.first.item_attributes.title
67
+ => "The Art of Computer Programming: v. 1-3: Vol 1-3 (Series in Computer Science &amp; Information Processing)"
68
+
69
+ lookup.response.items.first.item_attributes.author
70
+ => "Donald E. Knuth"
71
+
72
+ # If you need to debug, you can access all the xml data easily
73
+ lookup.raw_data
74
+ => <XML string, straight from the request body>
75
+
76
+ lookup.hpricot_data
77
+ => <the xml data, having been fed into Hpricot>
78
+
79
+ # And also the request uri
80
+ irb(main):022:0> lookup.request_uri
81
+ => #<URI::HTTP:0x1c7021c URL:http://ecs.amazonaws.co.uk/onca/xml?Service=AWSECommerceService&Operation=ItemLookup&ItemId=0201485419&AWSAccessKeyId=%3Cinsert%20api%20key%20here%3E>
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Jon Gilbraith, CompletelyNovel Ltd
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,94 @@
1
+ = amazon-product-advertising-api
2
+
3
+ == Introduction
4
+ A nice rubyish interface to the Amazon Product Advertising API, formerly
5
+ known as the Associates Web Service and before that the Amazon E-Commerce
6
+ Service.
7
+
8
+ The basic design philosophy is the 'Principle of least surprise', so it's:
9
+ - a dsl that should feel familiar to ruby folk.
10
+ - structured generally like the API.
11
+
12
+ == Prerequisites
13
+ It's assumed you're reasonably familiar with Ruby as a language, and the
14
+ typical coding patterns and styles employed by the community.
15
+
16
+ It's also assumed that you're familiar with the API. If not go RTFM for a bit,
17
+ it's all pretty straight forward.
18
+
19
+ == Overview
20
+ As mentioned before, the idea behind this is to model the API so that once
21
+ you're familiar with this library and the API, you'll find this an easy way to
22
+ navigate around it. You should then be able to just refer to the lists of
23
+ Operations, Response Groups and Response Elements in the appendices for all
24
+ you need to know.
25
+
26
+ You initiate requests by instantiating classes representing api Operations and
27
+ named the same way, i.e. ItemSearch, ItemLookup, etc. The request parameters
28
+ are represented by attributes on those objects and can be manipulated as you
29
+ wish. If a parameter is required it'll be required or defaulted on
30
+ initialization, but everywhere else we defer to the defaults provided by the
31
+ api.
32
+
33
+ Once setup, you call 'run' on the operation which will send the request and
34
+ return a response object (and after that also available as operation.response).
35
+
36
+ The response has a bit less structure than the request operations. There is no
37
+ representation for Response Groups as beyond one level deep there is no clear
38
+ pattern for how returned XML is structured (at least not without going down the
39
+ route trying to define custom handling for each of them). So, instead we group
40
+ the Operations into broad groups which return the same collections of data.
41
+ ItemSearch, ItemLookup and SimilarityLookup all return a Items container
42
+ element with one or more Item tag in it, etc.
43
+
44
+ Everything beyond one level deep is done with a recursive sweep instantiating
45
+ Element objects as we go.
46
+
47
+ == Things to know
48
+ - Amazon uses a lot of Camel case in their XML, but to suit Ruby / Rails
49
+ conventions attributes, etc are converted to underscore style.
50
+ - One gotcha - Response Elements can either be a simple value or a container
51
+ with more elements inside. We recognise this situation by simply comparing
52
+ the parent and child names (plural parent, singular child) though that isn't
53
+ always the pattern so we also look for multiple children of the same name.
54
+
55
+ That means that some situations might creep through and not work as expected.
56
+ If the parent and child don't follow the same naming convention and there is
57
+ also only one child element you'd find the child would be defined as
58
+ parent.child rather than parent.children.first.
59
+
60
+ This is a bug and will have to be addressed (probably by making a list of
61
+ container elements to check against).
62
+
63
+ == Having problems?
64
+ After running the request uri, returned raw xml and hpricot data will be
65
+ available in operation.raw_data and operation.hpricot_data which should tell
66
+ you all you need to know about the response.
67
+
68
+ == Test coverage
69
+ There aren't any tests at the moment but I'll try to add some.
70
+
71
+ For the most part there isn't really all that much to test though as it's all
72
+ largely just making http requests, however the XML parsing is quite convoluted
73
+ so some tests would be good there to make sure the parsing is following the
74
+ intended rules.
75
+
76
+
77
+ = TODO
78
+ - Implement the rest of the Operations (Cart*, Customer*, Help, List*, Seller*,
79
+ Tag*, Transaction* and Vehicle*).
80
+ - Clean handling of routine errors such as rate limiting, etc.
81
+ - Implement HMAC before the authentication requirement kicks in in August 2009.
82
+ - Implement batch and multiple operation requests, abstracted away from the
83
+ user within the dsl.
84
+ - Some sort of internal caching mechanism.
85
+ - Ability to bind to different IP addresses, in order to circumvent API rate
86
+ limiting.
87
+
88
+
89
+ = Credits
90
+ Created by Jon Gilbraith, jon@completelynovel.com, while working with
91
+ CompletelyNovel.
92
+
93
+ Contents of support.rb are basically taken and adapted from Rails'
94
+ ActiveSupport.
@@ -0,0 +1,36 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{amazon-product-advertising-api}
5
+ s.version = "0.0.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Jon Gilbraith"]
9
+ s.date = %q{2009-06-11}
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
+ s.email = %q{jon@completelynovel.com}
12
+ s.files = ["EXAMPLE.rdoc", "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 = false
14
+ s.homepage = %q{http://github.com/completelynovel/amazon-product-advertising-api}
15
+ s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{amazon-pa-api}
18
+ s.rubygems_version = %q{1.3.0}
19
+ s.summary = %q{A nice rubyish interface to the Amazon Product Advertising API.}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 2
24
+
25
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
+ s.add_runtime_dependency(%q<mime-types>, [">= 1.15"])
27
+ s.add_runtime_dependency(%q<diff-lcs>, [">= 1.1.2"])
28
+ else
29
+ s.add_dependency(%q<mime-types>, [">= 1.15"])
30
+ s.add_dependency(%q<diff-lcs>, [">= 1.1.2"])
31
+ end
32
+ else
33
+ s.add_dependency(%q<mime-types>, [">= 1.15"])
34
+ s.add_dependency(%q<diff-lcs>, [">= 1.1.2"])
35
+ end
36
+ end
@@ -0,0 +1,8 @@
1
+ require 'net/http'
2
+ require 'hpricot'
3
+
4
+ require 'amazon_product_advertising_api/support'
5
+ require 'amazon_product_advertising_api/base'
6
+ require 'amazon_product_advertising_api/operations/base'
7
+ require 'amazon_product_advertising_api/operations/browse_node'
8
+ require 'amazon_product_advertising_api/operations/item'
@@ -0,0 +1,12 @@
1
+ module AmazonProductAdvertisingApi
2
+
3
+ class Base
4
+
5
+ cattr_accessor :api_key
6
+
7
+ cattr_accessor :associate_ids
8
+ @@associate_ids = Struct.new(:ca, :de, :fr, :jp, :uk, :us).new
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,131 @@
1
+ module AmazonProductAdvertisingApi
2
+ module Operations
3
+ module Base
4
+
5
+ class Request
6
+
7
+ attr_accessor :aws_access_key_id
8
+
9
+ attr_accessor :region
10
+
11
+ attr_accessor :operation
12
+
13
+ attr_accessor :request_uri
14
+
15
+ attr_accessor :raw_data
16
+
17
+ attr_accessor :hpricot_data
18
+
19
+ attr_accessor :response
20
+
21
+ SERVICE_URLS = {
22
+ :us => 'http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService',
23
+ :uk => 'http://ecs.amazonaws.co.uk/onca/xml?Service=AWSECommerceService',
24
+ :ca => 'http://ecs.amazonaws.ca/onca/xml?Service=AWSECommerceService',
25
+ :de => 'http://ecs.amazonaws.de/onca/xml?Service=AWSECommerceService',
26
+ :jp => 'http://ecs.amazonaws.jp/onca/xml?Service=AWSECommerceService',
27
+ :fr => 'http://ecs.amazonaws.fr/onca/xml?Service=AWSECommerceService'
28
+ }
29
+
30
+ def initialize
31
+ self.response = AmazonProductAdvertisingApi::Operations::Base::Element.new
32
+ end
33
+
34
+ def query_amazon(params)
35
+ request_params = {}
36
+ request_params["AWSAccessKeyId"] = AmazonProductAdvertisingApi::Base.api_key
37
+ request_params["Operation"] = self.operation
38
+ request_params["AssociateTag"] = AmazonProductAdvertisingApi::Base.associate_ids.send(self.region) unless AmazonProductAdvertisingApi::Base.associate_ids.send(self.region).nil?
39
+ request_params.merge!(params)
40
+
41
+ self.request_uri = "#{SERVICE_URLS[self.region]}&#{request_params.collect { |var, val| var.to_s.camelize + "=" + val.to_s }.join("&")}"
42
+ self.request_uri = URI.parse(URI.escape(self.request_uri))
43
+
44
+ result = Net::HTTP::get_response(self.request_uri)
45
+ raise("Error connecting to Amazon") if !result.kind_of?(Net::HTTPSuccess)
46
+
47
+ # Store away the raw data for debugging or if more direct access is required
48
+ self.raw_data = result.body
49
+ self.hpricot_data = Hpricot.XML(self.raw_data)
50
+
51
+ # Now parse the xml and build out the reponse elements
52
+ self.parse
53
+ end
54
+
55
+ def parse
56
+ raise "This should be being overridden by it's subclass to provide custom parsing for the particular operation concerned."
57
+ end
58
+
59
+ def run
60
+ self.query_amazon(params)
61
+ end
62
+
63
+ private
64
+ # When passed an hpricot element it returns true or false based on whether this item is thought to be inside a Container Element.
65
+ # It does this in the rather crude way of seeing if the parent's name is the pluralized form of it's own, or it is one of
66
+ # several with the same name. This isn't 100% fool proof so I think at some point using a definitive list of the container elements
67
+ # would be a better way to go.
68
+ #
69
+ # The pluralisation could also do with something a bit more sophisticated.
70
+ def parent_a_container?(hpricot_element)
71
+ hpricot_element.parent.name == hpricot_element.name + "s" || hpricot_element.parent.search("> #{hpricot_element.name}").size > 1
72
+ end
73
+
74
+ end
75
+
76
+ class Element
77
+
78
+ include Enumerable
79
+
80
+ def initialize
81
+ @contained_elements = []
82
+ end
83
+
84
+ def add_element(name, value = nil)
85
+ name = name.underscore
86
+
87
+ self.instance_eval %{
88
+ def self.#{name}
89
+ @#{name}
90
+ end
91
+ def self.#{name}=(value)
92
+ @#{name} ||= value
93
+ end
94
+ }
95
+
96
+ if !value.nil?
97
+ value = value.to_s if value.is_a?(Symbol)
98
+ self.send("#{name}=", value)
99
+ end
100
+
101
+ # Return the element
102
+ self.instance_eval("self.#{name}")
103
+ end
104
+
105
+ def << element
106
+ @contained_elements << element
107
+ end
108
+
109
+ def each(&block)
110
+ @contained_elements.each do |element|
111
+ yield element
112
+ end
113
+ end
114
+
115
+ def [] position
116
+ @contained_elements[position]
117
+ end
118
+
119
+ def first
120
+ @contained_elements.first
121
+ end
122
+
123
+ def size
124
+ @contained_elements.size
125
+ end
126
+
127
+ end
128
+
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,65 @@
1
+ module AmazonProductAdvertisingApi
2
+ module Operations
3
+ module BrowseNode
4
+
5
+ class BrowseNodeLookup < AmazonProductAdvertisingApi::Operations::Base::Request
6
+
7
+ REQUEST_PARAMETERS = :browse_node_id, :response_group
8
+
9
+ REQUEST_PARAMETERS.each do |param|
10
+ self.send(:attr_accessor, param)
11
+ end
12
+
13
+ def initialize(browse_node_id, region = :uk)
14
+ super()
15
+
16
+ self.browse_node_id = browse_node_id
17
+ self.operation = "BrowseNodeLookup"
18
+ self.region = region
19
+ end
20
+
21
+ def parse
22
+ self.response.add_element("BrowseNodes", AmazonProductAdvertisingApi::Operations::Base::Element.new)
23
+
24
+ (self.hpricot_data/'BrowseNodes > BrowseNode').each do |element|
25
+ new_element = AmazonProductAdvertisingApi::Operations::Base::Element.new
26
+ self.response.browse_nodes << new_element
27
+
28
+ queue = []
29
+ queue << [new_element, element.containers]
30
+
31
+ queue.each do |pair|
32
+ current_element = pair[0]
33
+ current_children = pair[1]
34
+
35
+ current_children.each do |child|
36
+ if child.containers.size == 0
37
+ current_element.add_element(child.name, child.inner_html)
38
+ else
39
+ if parent_a_container?(child)
40
+ new_element = AmazonProductAdvertisingApi::Operations::Base::Element.new
41
+ current_element << new_element
42
+ queue << [new_element, child.containers]
43
+ else
44
+ new_element = current_element.add_element(child.name, AmazonProductAdvertisingApi::Operations::Base::Element.new)
45
+ queue << [new_element, child.containers]
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ private
54
+ def params
55
+ REQUEST_PARAMETERS.inject({}) do |parameters, parameter|
56
+ parameters[parameter] = eval("self.#{parameter}") unless eval("self.#{parameter}.nil?")
57
+ parameters
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,133 @@
1
+ module AmazonProductAdvertisingApi
2
+ module Operations
3
+ module Item
4
+
5
+ module Common
6
+
7
+ def parse
8
+ self.response.add_element("Items", AmazonProductAdvertisingApi::Operations::Base::Element.new)
9
+
10
+ (self.hpricot_data/'Items > Item').each do |element|
11
+ new_element = AmazonProductAdvertisingApi::Operations::Base::Element.new
12
+ self.response.items << new_element
13
+
14
+ queue = []
15
+ queue << [new_element, element.containers]
16
+
17
+ queue.each do |pair|
18
+ current_element = pair[0]
19
+ current_children = pair[1]
20
+
21
+ current_children.each do |child|
22
+ if child.containers.size == 0
23
+ current_element.add_element(child.name, child.inner_html)
24
+ else
25
+ if parent_a_container?(child)
26
+ new_element = AmazonProductAdvertisingApi::Operations::Base::Element.new
27
+ current_element << new_element
28
+ queue << [new_element, child.containers]
29
+ else
30
+ new_element = current_element.add_element(child.name, AmazonProductAdvertisingApi::Operations::Base::Element.new)
31
+ queue << [new_element, child.containers]
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ class ItemSearch < AmazonProductAdvertisingApi::Operations::Base::Request
42
+
43
+ include Common
44
+
45
+ REQUEST_PARAMETERS = :actor, :artist, :audience_rating, :author, :availability, :brand, :browse_node, :city,
46
+ :composer, :condition, :conductor, :director, :item_page, :keywords, :manufacturer, :maximum_price,
47
+ :merchant_id, :minimum_price, :neighborhood, :orchestra, :postal_code, :power, :publisher, :related_items_page,
48
+ :relationship_type, :review_sort, :search_index, :sort, :tag_page, :tags_per_page, :tag_sort, :text_stream, :title,
49
+ :variation_page, :response_group
50
+
51
+ REQUEST_PARAMETERS.each do |param|
52
+ self.send(:attr_accessor, param)
53
+ end
54
+
55
+ def initialize(keywords, search_index = "Books", region = :uk)
56
+ super()
57
+
58
+ self.keywords = keywords
59
+ self.search_index = search_index
60
+ self.operation = "ItemSearch"
61
+ self.region = region
62
+ end
63
+
64
+ private
65
+ def params
66
+ REQUEST_PARAMETERS.inject({}) do |parameters, parameter|
67
+ parameters[parameter] = eval("self.#{parameter}") unless eval("self.#{parameter}.nil?")
68
+ parameters
69
+ end
70
+ end
71
+
72
+ end
73
+
74
+ class ItemLookup < AmazonProductAdvertisingApi::Operations::Base::Request
75
+
76
+ include Common
77
+
78
+ REQUEST_PARAMETERS = :condition, :id_type, :item_id, :merchant_id, :offer_page, :related_items_page, :relationship_type, :review_page,
79
+ :review_sort, :search_index, :tag_page, :tags_per_page, :tag_sort, :variation_page, :response_group
80
+
81
+ REQUEST_PARAMETERS.each do |param|
82
+ self.send(:attr_accessor, param)
83
+ end
84
+
85
+ def initialize(item_id, region = :uk)
86
+ super()
87
+
88
+ self.item_id = item_id
89
+ self.operation = "ItemLookup"
90
+ self.region = region
91
+ end
92
+
93
+ private
94
+ def params
95
+ REQUEST_PARAMETERS.inject({}) do |parameters, parameter|
96
+ parameters[parameter] = eval("self.#{parameter}") unless eval("self.#{parameter}.nil?")
97
+ parameters
98
+ end
99
+ end
100
+
101
+ end
102
+
103
+ class SimilarityLookup < AmazonProductAdvertisingApi::Operations::Base::Request
104
+
105
+ include Common
106
+
107
+ REQUEST_PARAMETERS = :condition, :item_id, :merchant_id, :similarity_type, :response_group
108
+
109
+ REQUEST_PARAMETERS.each do |param|
110
+ self.send(:attr_accessor, param)
111
+ end
112
+
113
+ def initialize(item_id, region = :uk)
114
+ super()
115
+
116
+ self.item_id = item_id
117
+ self.operation = "SimilarityLookup"
118
+ self.region = region
119
+ end
120
+
121
+ private
122
+ def params
123
+ REQUEST_PARAMETERS.inject({}) do |parameters, parameter|
124
+ parameters[parameter] = eval("self.#{parameter}") unless eval("self.#{parameter}.nil?")
125
+ parameters
126
+ end
127
+ end
128
+
129
+ end
130
+
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,55 @@
1
+ class Class
2
+ def cattr_reader(sym)
3
+ class_eval(<<-EOS, __FILE__, __LINE__)
4
+ unless defined? @@#{sym} # unless defined? @@hair_colors
5
+ @@#{sym} = nil # @@hair_colors = nil
6
+ end # end
7
+ #
8
+ def self.#{sym} # def self.hair_colors
9
+ @@#{sym} # @@hair_colors
10
+ end # end
11
+ #
12
+ def #{sym} # def hair_colors
13
+ @@#{sym} # @@hair_colors
14
+ end # end
15
+ EOS
16
+ end
17
+
18
+ def cattr_writer(sym)
19
+ class_eval(<<-EOS, __FILE__, __LINE__)
20
+ unless defined? @@#{sym} # unless defined? @@hair_colors
21
+ @@#{sym} = nil # @@hair_colors = nil
22
+ end # end
23
+ #
24
+ def self.#{sym}=(obj) # def self.hair_colors=(obj)
25
+ @@#{sym} = obj # @@hair_colors = obj
26
+ end # end
27
+ EOS
28
+ end
29
+
30
+ def cattr_accessor(sym)
31
+ cattr_reader(sym)
32
+ cattr_writer(sym)
33
+ end
34
+
35
+ end
36
+
37
+ class String
38
+
39
+ def camelize(first_letter_in_uppercase = true)
40
+ if first_letter_in_uppercase
41
+ self.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
42
+ else
43
+ self.first + camelize(self)[1..-1]
44
+ end
45
+ end
46
+
47
+ def underscore
48
+ self.to_s.gsub(/::/, '/').
49
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
50
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
51
+ tr("-", "_").
52
+ downcase
53
+ end
54
+
55
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: completelynovel-amazon-product-advertising-api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Jon Gilbraith
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-11 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: mime-types
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "1.15"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: diff-lcs
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.1.2
34
+ version:
35
+ description: 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.
36
+ email: jon@completelynovel.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - EXAMPLE.rdoc
45
+ - MIT-LICENSE
46
+ - README.rdoc
47
+ - amazon-product-advertising-api.gemspec
48
+ - lib/amazon_product_advertising_api
49
+ - lib/amazon_product_advertising_api/base.rb
50
+ - lib/amazon_product_advertising_api/operations
51
+ - lib/amazon_product_advertising_api/operations/base.rb
52
+ - lib/amazon_product_advertising_api/operations/browse_node.rb
53
+ - lib/amazon_product_advertising_api/operations/item.rb
54
+ - lib/amazon_product_advertising_api/support.rb
55
+ - lib/amazon_product_advertising_api.rb
56
+ has_rdoc: false
57
+ homepage: http://github.com/completelynovel/amazon-product-advertising-api
58
+ post_install_message:
59
+ rdoc_options:
60
+ - --inline-source
61
+ - --charset=UTF-8
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ version:
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "0"
75
+ version:
76
+ requirements: []
77
+
78
+ rubyforge_project: amazon-pa-api
79
+ rubygems_version: 1.2.0
80
+ signing_key:
81
+ specification_version: 2
82
+ summary: A nice rubyish interface to the Amazon Product Advertising API.
83
+ test_files: []
84
+