amazonparser 0.0.1

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.
@@ -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