amazonparser 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6a2ad50f84dd3ca4032d984afdc279d6118e8a2e
4
+ data.tar.gz: 8ba4fcc35500d566c8fa6fd0f6b4a4a7ec359cdf
5
+ SHA512:
6
+ metadata.gz: 2255da99a8b6fb3cf5011da44435a99af7262d4aa630169f03a2d140542be0f3072343782a39a0fd5274fb084c19fa98995548783f888852e06ac79febeab68a
7
+ data.tar.gz: 5c94103d69e021a0db11684a3204722170ded95544b3c3995615b65d54da8a77d7b2a7c283a3a57e565805492452c790d0c019a34ca9a4c2f90914af5f20fadf
@@ -0,0 +1,3 @@
1
+ ## Simple parser for Vacuum
2
+
3
+ Example: TODO
@@ -0,0 +1,13 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |test|
4
+ test.libs << 'test'
5
+ test.test_files = FileList['test/*_test.rb']
6
+ end
7
+
8
+ task default: :test
9
+
10
+ desc "Open an irb session preloaded with this library"
11
+ task :console do
12
+ sh "irb -rubygems -I lib -r amazonparser.rb"
13
+ end
@@ -0,0 +1,18 @@
1
+ Gem::Specification.new do |gem|
2
+ gem.name = 'amazonparser'
3
+ gem.version = '0.0.1'
4
+ gem.summary = 'Amazon item lookup parser'
5
+ gem.description = 'Amazon item lookup parser powered by Vacuum'
6
+ gem.authors = ['Matias Fernandez']
7
+ gem.email = 'matiasfmolinari@gmail.com'
8
+ gem.homepage = 'https://github.com/MatiasFMolinari/amazonparser'
9
+ gem.license = 'MIT'
10
+ gem.files = `git ls-files`.split("\n")
11
+ gem.test_files = `git ls-files -- test/*`.split("\n")
12
+
13
+ gem.add_runtime_dependency 'plissken', '>= 1.2.0', '< 2.0'
14
+ gem.add_runtime_dependency 'recursive-open-struct', '>= 1.0.5', '< 2.0'
15
+
16
+ gem.add_development_dependency 'vacuum', '>= 1.5.0', '< 2.0'
17
+ gem.add_development_dependency 'minitest', '>= 5.10.3', '< 6.0'
18
+ end
@@ -0,0 +1,162 @@
1
+ require 'recursive-open-struct'
2
+ require 'plissken'
3
+
4
+ module AmazonParser
5
+ class << self
6
+ def parse(product_hash:)
7
+ # 1. convert hash keys to snakecase
8
+ product_hash = product_hash.to_snake_keys
9
+
10
+ # 2. convert hash to open struct
11
+ product = RecursiveOpenStruct.new(product_hash, recurse_over_arrays: true)
12
+
13
+ # 3. setup basic scopes
14
+ item = product.item_lookup_response.items.item
15
+ item_attributes = item.item_attributes
16
+ images = item.image_sets.image_set
17
+ categories = item.browse_nodes
18
+ main_category = item.browse_nodes.browse_node
19
+ offer_summary = item.offer_summary
20
+ offers = item.offers
21
+ promotions = item.offers.offer.promotions
22
+
23
+ # 4. copy attributes into root struct
24
+
25
+ # a. main response groups
26
+ product.item = item
27
+ product.item_attributes = item_attributes
28
+ product.images = images
29
+ product.categories = categories
30
+ product.main_category = main_category
31
+ product.offer_summary = offer_summary
32
+ product.offers = offers
33
+ product.promotions = promotions
34
+
35
+ # b. item
36
+ product.asin = item.asin
37
+ product.parent_asin = item.parent_asin
38
+ product.sales_rank = item.sales_rank
39
+
40
+ # c. category
41
+ product.category = main_category.is_a?(Array) ? main_category[0].name : main_category.name
42
+
43
+ # d. item attributes
44
+ product.actor = item_attributes.actor
45
+ product.artist = item_attributes.artist
46
+ product.aspect_ratio = item_attributes.aspect_ratio
47
+ product.audience_rating = item_attributes.audience_rating
48
+ product.audio_format = item_attributes.audio_format
49
+ product.author = item_attributes.author
50
+ product.brand = item_attributes.brand
51
+ product.catalog_number_list = item_attributes.catalog_number_list
52
+ product.clothing_size = item_attributes.clothing_size
53
+ product.creator = item_attributes.creator
54
+ product.department = item_attributes.department
55
+ product.director = item_attributes.director
56
+ product.ean = item_attributes.ean
57
+ product.ean_list = item_attributes.ean_list
58
+ product.edition = item_attributes.edition
59
+ product.eisbn = item_attributes.eisbn
60
+ product.esrb_age_rating = item_attributes.esrb_age_rating
61
+ product.feature = item_attributes.feature
62
+ product.format = item_attributes.format
63
+ product.genre = item_attributes.genre
64
+ product.hardware_platform = item_attributes.hardware_platform
65
+ product.hazardous_material_type = item_attributes.hazardous_material_type
66
+ product.is_adult_product = to_bool item_attributes.is_adult_product
67
+ product.is_autographed = to_bool item_attributes.is_autographed
68
+ product.isbn = item_attributes.isbn
69
+ product.is_memorabilia = to_bool item_attributes.is_memorabilia
70
+ product.issues_per_year = item_attributes.issues_per_year
71
+ product.label = item_attributes.label
72
+ product.legal_disclaimer = item_attributes.legal_disclaimer
73
+ product.list_price = item_attributes.list_price.amount&.to_i
74
+ product.manufacturer = item_attributes.manufacturer
75
+ product.max_use_age = item_attributes.manufacturer_maximum_age
76
+ product.min_use_age = item_attributes.manufacturer_minimum_age
77
+ product.manufacturer_warranty = item_attributes.manufacturer_parts_warranty_description
78
+ product.material_type = item_attributes.material_type
79
+ product.media_type = item_attributes.media_type
80
+ product.meta_type = item_attributes.metal_type
81
+ product.model = item_attributes.model
82
+ product.mpn = item_attributes.mpn
83
+ product.number_of_discs = item_attributes.number_of_discs&.to_i
84
+ product.number_of_issues = item_attributes.number_of_issues&.to_i
85
+ product.number_of_items = item_attributes.number_of_items&.to_i
86
+ product.number_of_pages = item_attributes.number_of_pages&.to_i
87
+ product.number_of_tracks = item_attributes.number_of_tracks&.to_i
88
+ product.operating_system = item_attributes.operating_system
89
+ product.package_quantity = item_attributes.package_quantity&.to_i
90
+ product.part_number = item_attributes.part_number
91
+ product.platform = item_attributes.platform
92
+ product.group = item_attributes.product_group
93
+ product.product_type_name = item_attributes.product_type_name
94
+ product.publication_date = item_attributes.publication_date
95
+ product.publisher = item_attributes.publisher
96
+ product.region_code = item_attributes.region_code
97
+ product.release_date = item_attributes.release_date
98
+ product.running_time = item_attributes.running_time
99
+ product.seikodo_product_code = item_attributes.seikodo_product_code
100
+ product.size = item_attributes.size
101
+ product.sku = item_attributes.sku
102
+ product.studio = item_attributes.studio
103
+ product.subscription_length = item_attributes.subscription_length
104
+ product.title = item_attributes.title
105
+ product.trade_in_value = item_attributes.trade_in_value
106
+ product.upc = item_attributes.upc
107
+ product.upc_list = item_attributes.upc_list
108
+ product.warranty = item_attributes.warranty
109
+ product.weee_tax_value = item_attributes.weee_tax_value
110
+
111
+ # e. package size
112
+ product.package_height = item_attributes.package_dimensions.height.__content__&.to_i
113
+ product.package_height_units = item_attributes.package_dimensions.height.units
114
+ product.package_width = item_attributes.package_dimensions.width.__content__&.to_i
115
+ product.package_width_units = item_attributes.package_dimensions.width.units
116
+ product.package_length = item_attributes.package_dimensions.length.__content__&.to_i
117
+ product.package_length_units = item_attributes.package_dimensions.length.units
118
+
119
+ # f. offers
120
+ product.offers_count = offers.total_offers&.to_i
121
+ product.price = offers.offer.dig(:offer_listing, :price, :amount)&.to_i
122
+ product.sale_price = offers.offer.dig(:offer_listing, :sale_price, :amount)&.to_i
123
+ product.discount = offers.offer.dig(:offer_listing, :amount_saved, :amount)&.to_i
124
+ product.percent_discount = offers.offer.offer_listing.percentage_saved&.to_i
125
+ product.has_super_saver_shipping = to_bool offers.offer.offer_listing.is_eligible_for_super_saver_shipping
126
+ product.has_prime = to_bool offers.offer.offer_listing.is_eligible_for_prime
127
+ product.has_prime_streaming = to_bool offers.offer.offer_listing.is_eligible_for_prime_free_digital_video
128
+ product.can_be_traded_in = to_bool offers.offer.offer_listing.is_eligible_for_trade_in
129
+ product.availability = offers.offer.offer_listing.availability
130
+ product.availability_type = offers.offer.offer_listing.availability_attributes.availability_type
131
+ product.min_hours_until_available = offers.offer.offer_listing.availability_attributes.minimum_hours&.to_i
132
+ product.max_hours_until_available = offers.offer.offer_listing.availability_attributes.maximum_hours&.to_i
133
+
134
+ # g. offer summary
135
+ product.lowest_new_price = offer_summary.dig(:lowest_new_price, :amount)&.to_i
136
+ product.lowest_used_price = offer_summary.dig(:lowest_used_price, :amount)&.to_i
137
+ product.lowest_collectibe_price = offer_summary.dig(:lowest_collectibe_price, :amount)&.to_i
138
+ product.lowest_refurbished_price = offer_summary.dig(:lowest_refurbished_price, :amount)&.to_i
139
+ product.new_count = offer_summary.total_new&.to_i
140
+ product.used_count = offer_summary.total_used&.to_i
141
+ product.collectible_count = offer_summary.total_collectible&.to_i
142
+ product.refurbished_count = offer_summary.total_refurbished&.to_i
143
+
144
+ # h. first promo
145
+ product.promo_category = promotions&.promotion&.summary&.category
146
+ product.promo_requirement = promotions&.promotion&.summary&.eligibility_requirement_description
147
+ product.promo_benefit = promotions&.promotion&.summary&.benefit_description
148
+ product.promo_terms = promotions&.promotion&.summary&.terms_and_conditions
149
+
150
+ product
151
+ end
152
+
153
+ private
154
+
155
+ def to_bool(string)
156
+ return nil if string.nil?
157
+ return true if string == true || string == "1"
158
+ return false if string == false || string == "0"
159
+ raise ArgumentError.new("invalid value for Boolean: '#{string}'")
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,66 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/pride'
3
+ require 'amazonparser'
4
+ require 'vacuum'
5
+
6
+ class AmazonParserTest < Minitest::Test
7
+ def test_request
8
+ # 1. init vacuum
9
+ request = Vacuum.new('US', true)
10
+ request.configure(
11
+ aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
12
+ aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
13
+ associate_tag: 'makeuppicker-20',
14
+ version: nil
15
+ )
16
+
17
+ # 2. setup request
18
+ query = {
19
+ 'ItemId' => 'B000V3MGFS',
20
+ 'ResponseGroup' => 'BrowseNodes, Images, ItemAttributes, OfferFull, PromotionSummary, SalesRank'
21
+ }
22
+
23
+ # 3. request item
24
+ response = request.item_lookup(query: query, persistent: true)
25
+ response.parser = nil
26
+
27
+ # 4. convert xml response to hash
28
+ product_hash = response.parse
29
+
30
+ # 5. parse product
31
+ product = AmazonParser.parse(product_hash: product_hash)
32
+
33
+ # display output while transforming into tests
34
+ puts "asin: " + product.asin.inspect
35
+ puts "title: " + product.title.inspect
36
+ puts "category: " + product.category.inspect
37
+ puts "brand: " + product.brand.inspect
38
+
39
+ puts "list_price: " + product.list_price.inspect
40
+ puts "price: " + product.price.inspect
41
+ puts "sale_price: " + product.sale_price.inspect
42
+ puts "discount: " + product.discount.inspect
43
+ puts "lowest_new_price: " + product.lowest_new_price.inspect
44
+ puts "lowest_used_price: " + product.lowest_used_price.inspect
45
+ puts "new_count: " + product.new_count.inspect
46
+ puts "used_count: " + product.used_count.inspect
47
+ puts "percent_discount: " + product.percent_discount.inspect
48
+ puts "availability_message: " + product.availability_message.inspect
49
+ puts "availability_type: " + product.availability_type.inspect
50
+ puts "min_hours_until_available: " + product.min_hours_until_available.inspect
51
+ puts "max_hours_until_available: " + product.max_hours_until_available.inspect
52
+ puts "has_super_saver_shipping: " + product.has_super_saver_shipping.inspect
53
+ puts "has_prime: " + product.has_prime.inspect
54
+
55
+ puts "color: " + product.color.inspect
56
+ puts "size: " + product.size.inspect
57
+ puts "package_quantity: " + product.package_quantity.inspect
58
+ puts "part_number: " + product.part_number.inspect
59
+ puts "group: " + product.group.inspect
60
+ puts "manufacturer: " + product.manufacturer.inspect
61
+ puts "release_date: " + product.release_date.inspect
62
+ puts "number_of_items: " + product.number_of_items.inspect
63
+ puts "publisher: " + product.publisher.inspect
64
+ puts "product_type_name: " + product.type.inspect
65
+ end
66
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: amazonparser
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Matias Fernandez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-07-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: plissken
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.2.0
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 1.2.0
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: recursive-open-struct
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 1.0.5
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '2.0'
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 1.0.5
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '2.0'
53
+ - !ruby/object:Gem::Dependency
54
+ name: vacuum
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 1.5.0
60
+ - - "<"
61
+ - !ruby/object:Gem::Version
62
+ version: '2.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 1.5.0
70
+ - - "<"
71
+ - !ruby/object:Gem::Version
72
+ version: '2.0'
73
+ - !ruby/object:Gem::Dependency
74
+ name: minitest
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: 5.10.3
80
+ - - "<"
81
+ - !ruby/object:Gem::Version
82
+ version: '6.0'
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 5.10.3
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: '6.0'
93
+ description: Amazon item lookup parser powered by Vacuum
94
+ email: matiasfmolinari@gmail.com
95
+ executables: []
96
+ extensions: []
97
+ extra_rdoc_files: []
98
+ files:
99
+ - README.md
100
+ - Rakefile
101
+ - amazonparser.gemspec
102
+ - lib/amazonparser.rb
103
+ - test/amazonparser_test.rb
104
+ homepage: https://github.com/MatiasFMolinari/amazonparser
105
+ licenses:
106
+ - MIT
107
+ metadata: {}
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 2.6.11
125
+ signing_key:
126
+ specification_version: 4
127
+ summary: Amazon item lookup parser
128
+ test_files:
129
+ - test/amazonparser_test.rb