completelynovel-amazon-product-advertising-api 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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
+