ramazon_advertising 0.3.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.
Files changed (43) hide show
  1. data/.document +5 -0
  2. data/.gitignore +7 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +46 -0
  5. data/Rakefile +84 -0
  6. data/VERSION +1 -0
  7. data/features/friendly_errors.feature +15 -0
  8. data/features/generate_root_browse_nodes.feature +13 -0
  9. data/features/getting_offer_details.feature +30 -0
  10. data/features/getting_search_bins.feature +22 -0
  11. data/features/retrieve_browse_node_information.feature +16 -0
  12. data/features/retrieving_a_product.feature +32 -0
  13. data/features/searching_for_products.feature +47 -0
  14. data/features/step_definitions/auth_steps.rb +8 -0
  15. data/features/step_definitions/browse_node_steps.rb +55 -0
  16. data/features/step_definitions/error_steps.rb +14 -0
  17. data/features/step_definitions/product_collection_steps.rb +20 -0
  18. data/features/step_definitions/product_steps.rb +75 -0
  19. data/features/step_definitions/ramazon_advertising_steps.rb +0 -0
  20. data/features/support/env.rb +7 -0
  21. data/features/support/ramazon_advertising.example.yml +2 -0
  22. data/lib/ramazon/abstract_element.rb +18 -0
  23. data/lib/ramazon/browse_node.rb +69 -0
  24. data/lib/ramazon/configuration.rb +66 -0
  25. data/lib/ramazon/error.rb +12 -0
  26. data/lib/ramazon/image.rb +18 -0
  27. data/lib/ramazon/merchant.rb +21 -0
  28. data/lib/ramazon/offer.rb +27 -0
  29. data/lib/ramazon/price.rb +18 -0
  30. data/lib/ramazon/product.rb +303 -0
  31. data/lib/ramazon/product_collection.rb +30 -0
  32. data/lib/ramazon/rails_additions.rb +99 -0
  33. data/lib/ramazon/request.rb +82 -0
  34. data/lib/ramazon/search_bin.rb +11 -0
  35. data/lib/ramazon/search_bin_parameter.rb +9 -0
  36. data/lib/ramazon/search_bin_set.rb +11 -0
  37. data/lib/ramazon/signatory.rb +10 -0
  38. data/lib/ramazon_advertising.rb +41 -0
  39. data/lib/root_nodes.yml +64 -0
  40. data/lib/tasks/ramazon.rake +9 -0
  41. data/spec/ramazon/configuration_spec.rb +21 -0
  42. data/spec/spec_helper.rb +11 -0
  43. metadata +157 -0
@@ -0,0 +1,30 @@
1
+ module Ramazon
2
+ class ProductCollection < WillPaginate::Collection
3
+ include HappyMapper
4
+ has_many :search_bin_sets, Ramazon::SearchBinSet, :tag => "SearchBinSets/SearchBinSet"
5
+
6
+ def self.create_from_results(page, per_page, body)
7
+ results = Items.parse(body, {})[0]
8
+ col = create(page, 10, results.total_results || 0) do |pager|
9
+ pager.replace(results.products)
10
+ end
11
+
12
+ col.search_bin_sets = Ramazon::SearchBinSet.parse(body)
13
+ col
14
+ end
15
+
16
+ end
17
+
18
+ class Items
19
+ include HappyMapper
20
+ tag 'Items'
21
+
22
+ element :total_results, Integer, :tag => 'TotalResults'
23
+ element :total_pages, Integer, :tag => 'TotalPages'
24
+
25
+ has_many :products,
26
+ Ramazon::Product,
27
+ :tag => "Item",
28
+ :raw => true
29
+ end
30
+ end
@@ -0,0 +1,99 @@
1
+ #this code courtesy of Pat Allan and Rails Core
2
+ module Ramazon
3
+ module HashExcept
4
+ # Returns a new hash without the given keys.
5
+ def except(*keys)
6
+ rejected = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys)
7
+ reject { |key,| rejected.include?(key) }
8
+ end
9
+
10
+ # Replaces the hash without only the given keys.
11
+ def except!(*keys)
12
+ replace(except(*keys))
13
+ end
14
+ end
15
+ end
16
+
17
+ Hash.send(
18
+ :include, Ramazon::HashExcept
19
+ ) unless Hash.instance_methods.include?("except")
20
+
21
+ module Ramazon
22
+ module ArrayExtractOptions
23
+ def extract_options!
24
+ last.is_a?(::Hash) ? pop : {}
25
+ end
26
+ end
27
+ end
28
+
29
+ Array.send(
30
+ :include, Ramazon::ArrayExtractOptions
31
+ ) unless Array.instance_methods.include?("extract_options!")
32
+
33
+ module Ramazon
34
+ module ClassAttributeMethods
35
+ def cattr_reader(*syms)
36
+ syms.flatten.each do |sym|
37
+ next if sym.is_a?(Hash)
38
+ class_eval(<<-EOS, __FILE__, __LINE__)
39
+ unless defined? @@#{sym}
40
+ @@#{sym} = nil
41
+ end
42
+
43
+ def self.#{sym}
44
+ @@#{sym}
45
+ end
46
+
47
+ def #{sym}
48
+ @@#{sym}
49
+ end
50
+ EOS
51
+ end
52
+ end
53
+
54
+ def cattr_writer(*syms)
55
+ options = syms.extract_options!
56
+ syms.flatten.each do |sym|
57
+ class_eval(<<-EOS, __FILE__, __LINE__)
58
+ unless defined? @@#{sym}
59
+ @@#{sym} = nil
60
+ end
61
+
62
+ def self.#{sym}=(obj)
63
+ @@#{sym} = obj
64
+ end
65
+
66
+ #{"
67
+ def #{sym}=(obj)
68
+ @@#{sym} = obj
69
+ end
70
+ " unless options[:instance_writer] == false }
71
+ EOS
72
+ end
73
+ end
74
+
75
+ def cattr_accessor(*syms)
76
+ cattr_reader(*syms)
77
+ cattr_writer(*syms)
78
+ end
79
+ end
80
+ end
81
+
82
+ Class.extend(
83
+ Ramazon::ClassAttributeMethods
84
+ ) unless Class.respond_to?(:cattr_reader)
85
+
86
+ module Ramazon
87
+ module MetaClass
88
+ def metaclass
89
+ class << self
90
+ self
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ unless Object.new.respond_to?(:metaclass)
97
+ Object.send(:include, Ramazon::MetaClass)
98
+ end
99
+
@@ -0,0 +1,82 @@
1
+ module Ramazon
2
+ #the object used to prepare and submit requests to amazon
3
+ class Request
4
+ include HTTParty
5
+ attr_accessor :options
6
+
7
+ def initialize(options = {})
8
+ self.options = options.merge(default_options)
9
+ end
10
+
11
+ def submit
12
+ @response = self.class.get(signed_url)
13
+ if valid?
14
+ @response.body
15
+ else
16
+ raise self.errors[0], "The following response errors were returned: #{self.errors.collect{|e| e.to_s}}"
17
+ end
18
+ end
19
+
20
+ # Error checking for responses (will return true if errors are present)
21
+ # @returns [boolean] whether the response yielded errors
22
+ def valid?
23
+ @response && errors.empty?
24
+ end
25
+
26
+ #errors returned from amazon
27
+ def errors
28
+ @errors ||= Ramazon::Error.parse(@response.body) || []
29
+ end
30
+
31
+ #use this if any type of caching is desired (TBD)
32
+ def unsigned_path
33
+ qs = ""
34
+
35
+ sorted_params.each do |key, value|
36
+ qs << "&#{key}=#{URI.encode(value.to_s)}"
37
+ end
38
+
39
+ qs.size > 0 ? qs[1..qs.size] : qs
40
+ end
41
+
42
+ def signed_url
43
+ self.options[:timestamp] = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S")
44
+ encoded_param_strings = []
45
+ sorted_params.each do |p|
46
+ encoded_param_strings << "#{p[0]}=#{CGI::escape(p[1].to_s)}"
47
+ end
48
+ string_to_sign =
49
+ "GET
50
+ #{Ramazon::Configuration.base_uri.gsub("http://", "")}
51
+ #{Ramazon::Configuration.path}
52
+ #{encoded_param_strings.join("&")}"
53
+
54
+ signature = Ramazon::Signatory.sign(string_to_sign)
55
+ encoded_param_strings << "Signature=" + signature
56
+
57
+ "#{Ramazon::Configuration.uri}?#{encoded_param_strings.join("&")}"
58
+ end
59
+
60
+ def sorted_params
61
+ params.sort {|a, b| a <=> b}
62
+ end
63
+
64
+ def params
65
+ formatted_params = {}
66
+ self.options.each do |key, value|
67
+ formatted_params[key.to_s.classify] = value.is_a?(Array) ? value.join(",") : value
68
+ end
69
+
70
+ formatted_params
71
+ end
72
+
73
+ private
74
+ def default_options
75
+ {
76
+ :service => "AWSECommerceService",
77
+ :version => "2009-07-01",
78
+ :AWSAccessKeyId => Ramazon::Configuration.access_key
79
+ }
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,11 @@
1
+ module Ramazon
2
+ class SearchBin
3
+ include HappyMapper
4
+
5
+ tag "Bin"
6
+
7
+ has_many :parameters, Ramazon::SearchBinParameter, :tag => "BinParameter"
8
+ element :item_count, Integer, :tag => "BinItemCount"
9
+ element :name, String, :tag => "BinName"
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module Ramazon
2
+ class SearchBinParameter
3
+ include HappyMapper
4
+ tag "BinParameter"
5
+
6
+ element :name, String, :tag => "Name"
7
+ element :value, String, :tag => "Value"
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Ramazon
2
+ class SearchBinSet
3
+ include HappyMapper
4
+
5
+ tag "SearchBinSet"
6
+
7
+ attribute :narrow_by, String, :tag => "NarrowBy"
8
+
9
+ has_many :search_bins, Ramazon::SearchBin, :tag => "Bin"
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module Ramazon
2
+ class Signatory
3
+ def self.sign(string_to_sign)
4
+ sha1 = HMAC::SHA256.digest(Ramazon::Configuration.secret_key, string_to_sign)
5
+
6
+ #Base64 encoding adds a linefeed to the end of the string so chop the last character!
7
+ CGI.escape(Base64.encode64(sha1).chomp)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,41 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+
3
+ require "rubygems"
4
+
5
+ require "fileutils"
6
+ require "base64"
7
+ require "hmac-sha2"
8
+ require "digest/sha1"
9
+ require "digest/sha2"
10
+ require "cgi"
11
+
12
+ require "will_paginate"
13
+ require "httparty"
14
+ require "happymapper"
15
+ require "nokogiri"
16
+ require "configatron"
17
+ require "active_support/inflector"
18
+
19
+ require "ramazon/rails_additions"
20
+
21
+ require "ramazon/abstract_element"
22
+
23
+ require "ramazon/signatory"
24
+ require "ramazon/configuration"
25
+ require "ramazon/error"
26
+ require "ramazon/request"
27
+
28
+ require "ramazon/search_bin_parameter"
29
+ require "ramazon/search_bin"
30
+ require "ramazon/search_bin_set"
31
+
32
+ require "ramazon/image"
33
+ require "ramazon/price"
34
+ require "ramazon/merchant"
35
+ require "ramazon/offer"
36
+
37
+ require "ramazon/product"
38
+ require "ramazon/product_collection"
39
+ require "ramazon/browse_node"
40
+
41
+ configatron.ramazon.locale = :us
@@ -0,0 +1,64 @@
1
+ ---
2
+ Apparel (Kids & Baby): "1040662"
3
+ Baby: "165796011"
4
+ Gourmet Food: "3370831"
5
+ Home Appliances: "361395011"
6
+ Camera & Photo: "502394"
7
+ All Sports & Outdoors: "3375251"
8
+ Health & Personal Care: "3760901"
9
+ Cell Phones & Service: "301185"
10
+ Home Audio & Theater: "667846011"
11
+ Power & Hand Tools: "328182011"
12
+ Golf: "3410851"
13
+ Team Sports: "706809011"
14
+ Action Sports: "706812011"
15
+ Vacuums & Storage: "510080"
16
+ Office Products & Supplies: "1064954"
17
+ Magazines: "1263069011"
18
+ Industrial & Scientific: "16310091"
19
+ Jewelry: "3367581"
20
+ Pet Supplies: "12923371"
21
+ Home Improvement: "228013"
22
+ Bedding & Bath: "1057792"
23
+ TV & Video: "1266092011"
24
+ Computers & Accessories: "541966"
25
+ Books: "4"
26
+ Motorcycle & ATV: "346333011"
27
+ Outdoor Power Equipment: "551242"
28
+ Outdoor Recreation: "706814011"
29
+ Natural & Organic: "51537011"
30
+ "Furniture & D\xC3\xA9cor": "1057794"
31
+ Newspapers: "1263068011"
32
+ MP3 & Media Players: "172630"
33
+ Accessories: "1268192011"
34
+ MP3 Downloads: "163856011"
35
+ Kindle Books: "1286228011"
36
+ Toys & Games: "165793011"
37
+ Beauty: "3760911"
38
+ Grocery: "16310101"
39
+ Blogs: "401358011"
40
+ Video Games: "471306"
41
+ Cycling: "3403201"
42
+ Watches: "377110011"
43
+ Movies: "163414"
44
+ Sewing, Craft & Hobby: "12890711"
45
+ Software: "229548"
46
+ Kindle Store: "133141011"
47
+ Game Downloads: "979455011"
48
+ Video On Demand: "16261631"
49
+ Movies & TV: "130"
50
+ Textbooks: "465600"
51
+ Shoes: "672123011"
52
+ Apparel & Accessories: "1036592"
53
+ Kitchen & Dining: "284507"
54
+ Amazon Shorts: "13993911"
55
+ Blu-ray: "193640011"
56
+ Car Electronics & GPS: "1077068"
57
+ PC Games: "229575"
58
+ Computer Components: "193870011"
59
+ Music: "173425"
60
+ Automotive: "15684181"
61
+ Fan Gear: "3386071"
62
+ Exercise & Fitness: "3407731"
63
+ Patio, Lawn & Garden: "286168"
64
+ Musical Instruments: "11091801"
@@ -0,0 +1,9 @@
1
+ namespace :ramazon do
2
+ desc "Generate the yml file used for looking up root browse nodes"
3
+ task :generate_node_yml do
4
+ puts "Generating root nodes"
5
+ Ramazon::BrowseNode.generate_root_nodes
6
+ puts "Done"
7
+ end
8
+ end
9
+
@@ -0,0 +1,21 @@
1
+ require "spec_helper"
2
+
3
+ describe Ramazon::Configuration do
4
+ it "should default to the us" do
5
+ Ramazon::Configuration.locale.should eql(:us)
6
+ end
7
+
8
+ it "should raise an exception if a set a locale that doesn't exist" do
9
+ lambda {Ramazon::Configuration.locale = :ffsf}.should raise_error
10
+ end
11
+
12
+ it "should derive a url of the locale" do
13
+ Ramazon::Configuration.locale = :de
14
+ Ramazon::Configuration.base_uri.should =~ /#{Ramazon::Configuration.locale.to_s}/
15
+ end
16
+
17
+ it "should use .com for a us address" do
18
+ Ramazon::Configuration.locale = :us
19
+ Ramazon::Configuration.base_uri.should =~ /\.com/
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'ramazon_advertising'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+
8
+ Spec::Runner.configure do |config|
9
+
10
+ end
11
+
metadata ADDED
@@ -0,0 +1,157 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ramazon_advertising
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.2
5
+ platform: ruby
6
+ authors:
7
+ - Dan Pickett
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-28 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: jnunemaker-httparty
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.4.3
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: jnunemaker-happymapper
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.5
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: mislav-will_paginate
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 2.3.11
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: nokogiri
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.3.3
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: configatron
57
+ type: :runtime
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 2.4.1
64
+ version:
65
+ - !ruby/object:Gem::Dependency
66
+ name: ruby-hmac
67
+ type: :runtime
68
+ version_requirement:
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: 0.3.2
74
+ version:
75
+ description: " \t Amazon Advertising Wrapper - Use nokogiri to target the elements you want. An object oriented approach"
76
+ email: dpickett@enlightsolutions.com
77
+ executables: []
78
+
79
+ extensions: []
80
+
81
+ extra_rdoc_files:
82
+ - LICENSE
83
+ - README.rdoc
84
+ files:
85
+ - .document
86
+ - .gitignore
87
+ - LICENSE
88
+ - README.rdoc
89
+ - Rakefile
90
+ - VERSION
91
+ - features/friendly_errors.feature
92
+ - features/generate_root_browse_nodes.feature
93
+ - features/getting_offer_details.feature
94
+ - features/getting_search_bins.feature
95
+ - features/retrieve_browse_node_information.feature
96
+ - features/retrieving_a_product.feature
97
+ - features/searching_for_products.feature
98
+ - features/step_definitions/auth_steps.rb
99
+ - features/step_definitions/browse_node_steps.rb
100
+ - features/step_definitions/error_steps.rb
101
+ - features/step_definitions/product_collection_steps.rb
102
+ - features/step_definitions/product_steps.rb
103
+ - features/step_definitions/ramazon_advertising_steps.rb
104
+ - features/support/env.rb
105
+ - features/support/ramazon_advertising.example.yml
106
+ - lib/ramazon/abstract_element.rb
107
+ - lib/ramazon/browse_node.rb
108
+ - lib/ramazon/configuration.rb
109
+ - lib/ramazon/error.rb
110
+ - lib/ramazon/image.rb
111
+ - lib/ramazon/merchant.rb
112
+ - lib/ramazon/offer.rb
113
+ - lib/ramazon/price.rb
114
+ - lib/ramazon/product.rb
115
+ - lib/ramazon/product_collection.rb
116
+ - lib/ramazon/rails_additions.rb
117
+ - lib/ramazon/request.rb
118
+ - lib/ramazon/search_bin.rb
119
+ - lib/ramazon/search_bin_parameter.rb
120
+ - lib/ramazon/search_bin_set.rb
121
+ - lib/ramazon/signatory.rb
122
+ - lib/ramazon_advertising.rb
123
+ - lib/root_nodes.yml
124
+ - lib/tasks/ramazon.rake
125
+ - spec/ramazon/configuration_spec.rb
126
+ - spec/spec_helper.rb
127
+ has_rdoc: true
128
+ homepage: http://github.com/dpickett/ramazon_advertising
129
+ licenses: []
130
+
131
+ post_install_message:
132
+ rdoc_options:
133
+ - --charset=UTF-8
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: "0"
141
+ version:
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: "0"
147
+ version:
148
+ requirements: []
149
+
150
+ rubyforge_project:
151
+ rubygems_version: 1.3.5
152
+ signing_key:
153
+ specification_version: 3
154
+ summary: Amazon Advertising Wrapper - Use nokogiri to target the elements you want
155
+ test_files:
156
+ - spec/ramazon/configuration_spec.rb
157
+ - spec/spec_helper.rb