compare_supermarkets 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: dfb65bfbef6bc53ed2b46dcb75a2f220e2808696e283872d2107b2355990841f
4
+ data.tar.gz: '08a3c207418b171c4ef45a962faec2a30eb5e27ee8e42058a0c76e611362cec8'
5
+ SHA512:
6
+ metadata.gz: 95a927635dfba228799c2ae4c9f9bcd270a5f0cad7e3562f2cf5c9c6b0b8abffe0c74e12586dda1770a753b88fcc50a3cd7b52bdcde8f9172a2ef136adf59eda
7
+ data.tar.gz: bca1f45e957152491e021d27123307dd4ad94f130ecd586ddf6b8bb1c255a59e6f96991f0404c4e2949549c8a54e41fe54a4e8208adbcb639cff755a45534534
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2021-09-26
4
+
5
+ - Initial release
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in compare_supermarkets.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Justin Berger Howes
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # CompareSupermarkets
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/compare_supermarkets`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'compare_supermarkets'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle install
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install compare_supermarkets
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/compare_supermarkets.
36
+
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ task default: %i[]
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/compare_supermarkets'
4
+
5
+
6
+ CompareSupermarkets::CLI.new.call
data/bin/console ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "pry"
5
+ Pry.start
6
+
7
+ # require "irb"
8
+ # IRB.start
data/bin/setup ADDED
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+
3
+ set -euo pipefail
4
+ IFS=$'\n\t'
5
+
6
+ bundle install
@@ -0,0 +1,13 @@
1
+ require 'pry'
2
+ require 'nokogiri'
3
+ require 'watir'
4
+
5
+ #gem install selenium-webdriver - required for watir to work
6
+ #brew install --cask chromedriver - required for watir to work
7
+
8
+ require_relative '../lib/compare_supermarkets/scraper'
9
+ require_relative '../lib/compare_supermarkets/product'
10
+ require_relative '../lib/compare_supermarkets/cli'
11
+ require_relative '../lib/compare_supermarkets/version'
12
+
13
+ Watir.default_timeout = 0
@@ -0,0 +1,276 @@
1
+ class CompareSupermarkets::CLI
2
+ def call
3
+ puts ""
4
+ puts "Welcome to The Supermarket Comparer"
5
+ puts ""
6
+ puts "Type q at any time to exit."
7
+ puts ""
8
+ puts "Would you like to compare prices between Coles and Woolies? (Y/N)"
9
+ input = gets.strip.downcase
10
+ puts ""
11
+ if input == "y"
12
+ start
13
+ elsif input == "n"
14
+ puts ""
15
+ puts "No worries, have a good one!"
16
+ puts ""
17
+ exit
18
+ elsif input.empty?
19
+ invalid_input
20
+ call
21
+ elsif input == "q"
22
+ exit
23
+ else
24
+ invalid_input
25
+ call
26
+ end
27
+ end
28
+
29
+ def start
30
+ puts ""
31
+ puts "Great!"
32
+ puts "Please enter the name of the item you wish to compare"
33
+ input = gets.strip.downcase
34
+ puts ""
35
+ puts ""
36
+ puts "Thank you, we will now search for this product"
37
+ puts "This will open the browser, don't panic!"
38
+ puts ""
39
+ puts ""
40
+ puts ""
41
+ puts ""
42
+ self.search_supermarkets(input)
43
+ puts ""
44
+ puts ""
45
+ if CompareSupermarkets::Product.all_count > 10
46
+ puts ""
47
+ puts "Ooo, jeez, seems like we have a lot of results."
48
+ puts "We have #{CompareSupermarkets::Product.all_count} results for you."
49
+ puts "If you were a little more specific with your search"
50
+ puts "term, we would have less to sort through..."
51
+ puts ""
52
+ change_search_term
53
+ elsif CompareSupermarkets::Product.all_count == 0
54
+ puts ""
55
+ puts "Ohhh man! Doesn't seem like either supermarket carry"
56
+ puts "that product."
57
+ puts ""
58
+ change_search_term
59
+ else
60
+ puts ""
61
+ puts "Great! We have #{CompareSupermarkets::Product.all_count} items for you."
62
+ puts ""
63
+ puts ""
64
+ puts ""
65
+ how_to_display
66
+ end
67
+ end
68
+
69
+ def search_supermarkets(input)
70
+ CompareSupermarkets::Scraper.search_supermarkets(input)
71
+ end
72
+
73
+ def change_search_term
74
+ puts "Would you like to change your search term? (Y/N)"
75
+ input = gets.strip.downcase
76
+ if input == "y"
77
+ start
78
+ elsif input == "n"
79
+ puts ""
80
+ puts "No worries"
81
+ puts ""
82
+ if CompareSupermarkets::Product.all_count > 0
83
+ how_to_display
84
+ else
85
+ puts ""
86
+ puts "Have a great day!"
87
+ puts ""
88
+ exit
89
+ end
90
+ elsif input.empty?
91
+ invalid_input
92
+ change_search_term
93
+ elsif input == "q"
94
+ exit
95
+ else
96
+ invalid_input
97
+ change_search_term
98
+ end
99
+ end
100
+
101
+ def how_to_display
102
+ puts "How would you like your items displayed? (1-5)"
103
+ puts ""
104
+ puts "1 - First 10 Cheapest items"
105
+ puts ""
106
+ puts "2 - First 10 Most expensive items"
107
+ puts ""
108
+ puts "3 - All items"
109
+ puts ""
110
+ puts "4 - Only Coles items"
111
+ puts ""
112
+ puts "5 - Only Woolworths items"
113
+ puts ""
114
+ input = gets.strip
115
+ puts ""
116
+ if input == "1"
117
+ choice = CompareSupermarkets::Product.all_top_10_sorted_by_price
118
+ print_items(choice, "asc")
119
+ elsif input == "2"
120
+ choice = CompareSupermarkets::Product.all_top_10_sorted_by_price
121
+ print_items(choice, "desc")
122
+ elsif input == "3"
123
+ how_to_sort ? direction = "asc" : direction = "desc"
124
+ choice = CompareSupermarkets::Product.all_items_sorted_by_price
125
+ print_items(choice, direction)
126
+ elsif input == "4"
127
+ how_to_sort ? direction = "asc" : direction = "desc"
128
+ choice = CompareSupermarkets::Product.coles_sorted_by_price
129
+ print_items(choice, direction)
130
+ elsif input == "5"
131
+ how_to_sort ? direction = "asc" : direction = "desc"
132
+ choice = CompareSupermarkets::Product.woolworths_sorted_by_price
133
+ print_items(choice, direction)
134
+ elsif input == ""
135
+ invalid_input
136
+ how_to_display
137
+ elsif input == "q"
138
+ exit
139
+ else
140
+ invalid_input
141
+ how_to_display
142
+ end
143
+
144
+ end
145
+
146
+ def finished
147
+ puts ""
148
+ puts "Is this what you were looking for?(Y/N)"
149
+ input = gets.strip.downcase
150
+ if input == "y"
151
+ puts ""
152
+ puts "Great!"
153
+ anything_else
154
+ elsif input == "n"
155
+ puts ""
156
+ try_again
157
+ elsif input == ""
158
+ invalid_input
159
+ finished
160
+ elsif input == "q"
161
+ exit
162
+ else
163
+ invalid_input
164
+ finished
165
+ end
166
+ end
167
+
168
+ def try_again
169
+ puts "Oh damn, would you like to try something else? (Y/N)"
170
+ input = gets.strip.downcase
171
+ if input == "n"
172
+ puts ""
173
+ puts "I'm sorry we couldn't help you today. Have a wonderful day!"
174
+ puts ""
175
+ exit
176
+ elsif input == "y"
177
+ sort_or_compare
178
+ elsif input == "q"
179
+ exit
180
+ elsif input == ""
181
+ invalid_input
182
+ try_again
183
+ else
184
+ invalid_input
185
+ end
186
+ end
187
+
188
+ def sort_or_compare
189
+ puts ""
190
+ puts "Please pick from one of these options:"
191
+ puts ""
192
+ puts "1 - Change the which results you would like to see"
193
+ puts ""
194
+ puts "2 - Search for a new item"
195
+ input = gets.strip
196
+ if input == "1"
197
+ how_to_display
198
+ elsif input == "2"
199
+ CompareSupermarkets::Product.clear_all
200
+ start
201
+ elsif input == ""
202
+ invalid_input
203
+ sort_or_compare
204
+ else
205
+ invalid_input
206
+ sort_or_compare
207
+ end
208
+ end
209
+
210
+ def anything_else
211
+ puts "Can we help you compare anything else today? (Y/N)"
212
+ answer = gets.strip.downcase
213
+ if answer == "n"
214
+ puts ""
215
+ puts "Okay, thank you! Have a great day!"
216
+ puts ""
217
+ exit
218
+ elsif answer == "y"
219
+ start
220
+ else
221
+ invalid_input
222
+ anything_else
223
+ end
224
+ end
225
+
226
+ def invalid_input
227
+ puts ""
228
+ puts "Oh, I don't understand that input"
229
+ puts ""
230
+ puts "Please try again"
231
+ end
232
+
233
+ def how_to_sort
234
+ puts ""
235
+ puts "How would you like your results sorted?"
236
+ puts "1 - Cheapest to most expensive"
237
+ puts "2 - Most expensive to cheapest"
238
+ puts ""
239
+ input = gets.strip
240
+ if input == "1"
241
+ puts ""
242
+ puts "Okay! Here we go!"
243
+ puts ""
244
+ return true
245
+ elsif input == "2"
246
+ puts ""
247
+ puts "Okay! Here we go!"
248
+ puts ""
249
+ return false
250
+ elsif input == ""
251
+ puts ""
252
+ puts "Please enter a command"
253
+ how_to_sort
254
+ else
255
+ invalid_input
256
+ how_to_sort
257
+ end
258
+ end
259
+
260
+ def print_items(choice, direction)
261
+ direction == "asc" ? choice = choice : choice = choice.reverse
262
+ choice.each do |item|
263
+ p "Supermarket: #{item.supermarket}"
264
+ p "Item name: #{item.name}"
265
+ p "Item price: $#{item.dollar_value}.#{item.cent_value}"
266
+ p "Item unit size: #{item.unit_size}"
267
+ p item.price.empty? ? "Unit price: $#{item.dollar_value}.#{item.cent_value} / #{item.unit_size}" : "Unit price: $#{item.price}"
268
+ p "#{item.url}"
269
+ puts ""
270
+ end
271
+ puts ""
272
+ puts ""
273
+ finished
274
+ end
275
+
276
+ end
@@ -0,0 +1,81 @@
1
+ class CompareSupermarkets::Product
2
+ attr_writer :price
3
+ attr_reader :supermarket, :name, :price, :unit_size, :url, :dollar_value, :cent_value
4
+
5
+ @@all = []
6
+ @@coles_all = []
7
+ @@woolworths_all = []
8
+
9
+ def initialize (supermarket = nil, name = nil, price=nil, unit_size = nil, url = nil, dollar_value=nil, cent_value=nil)
10
+ @supermarket = supermarket
11
+ @name = name
12
+ @price = price
13
+ @unit_size = unit_size
14
+ @dollar_value = dollar_value
15
+ @cent_value = cent_value
16
+ @url = @supermarket == "Coles" ? "https://shop.coles.com.au#{url}" : "https://www.woolworths.com.au#{url}"
17
+ @@all << self
18
+ if @supermarket == "Coles"
19
+ @@coles_all << self
20
+ else
21
+ @@woolworths_all << self
22
+ end
23
+ end
24
+
25
+ def self.all
26
+ @all
27
+ end
28
+
29
+ def self.all_count
30
+ @@all.count
31
+ end
32
+
33
+ def self.coles_new_from_search(product)
34
+ product_to_compare = self.new("Coles",
35
+ product.css(".product-name").text,
36
+ product.css(".package-price").text.delete_prefix('$').gsub('per', '/'),
37
+ product.css(".package-size.accessibility-inline").text,
38
+ product.css(".product-image-link").attribute('href'),
39
+ product.css(".dollar-value").text,
40
+ product.css(".cent-value").text.delete_prefix('.'))
41
+ end
42
+
43
+ def self.woolworths_new_from_search(product)
44
+ product_to_compare = self.new("Woolworths",
45
+ product.css(".shelfProductTile-descriptionLink").text,
46
+ product.css(".shelfProductTile-cupPrice.ng-star-inserted").text.delete_prefix(' $').chomp(" "),
47
+ product.css(".shelfProductTile-descriptionLink").text.split(" ").last,
48
+ product.css(".shelfProductTile-descriptionLink").attribute('href').value,
49
+ product.css(".price-dollars").text,
50
+ product.css(".price-cents").text)
51
+ end
52
+
53
+ def self.all_items_sorted_by_price
54
+ sorted = @@all.sort_by! do |s|
55
+ price_to_sort = s.dollar_value + '.' + s.cent_value
56
+ price_to_sort.to_f
57
+ end
58
+ end
59
+
60
+ def self.all_top_10_sorted_by_price
61
+ self.all_items_sorted_by_price.first(10)
62
+ end
63
+
64
+ def self.coles_sorted_by_price
65
+ @@coles_all.sort_by! do |s|
66
+ price_to_sort = s.dollar_value + '.' + s.cent_value
67
+ price_to_sort.to_f
68
+ end
69
+ end
70
+
71
+ def self.woolworths_sorted_by_price
72
+ @@woolworths_all.sort_by! do |s|
73
+ price_to_sort = s.dollar_value + '.' + s.cent_value
74
+ price_to_sort.to_f
75
+ end
76
+ end
77
+
78
+ def self.clear_all
79
+ @@all.clear
80
+ end
81
+ end
@@ -0,0 +1,59 @@
1
+ class CompareSupermarkets::Scraper
2
+
3
+ attr_accessor :search_term
4
+
5
+ def initialize(search_term)
6
+ @search_term = search_term
7
+ end
8
+
9
+ def self.search_supermarkets(search_term)
10
+ self.search_coles_for(search_term)
11
+ self.search_woolworths_for(search_term)
12
+ end
13
+
14
+ def self.search_coles_for(search_term)
15
+ browser = Watir::Browser.new :chrome
16
+ browser.goto("https://shop.coles.com.au/a/national/everything/search/#{search_term}")
17
+ begin
18
+ coles_js_doc = browser.element(class: "products").wait_until(&:present?)
19
+ rescue
20
+ puts "Coles does not have this product"
21
+ puts ""
22
+ puts "Let's check Woolworths"
23
+ puts ""
24
+ puts ""
25
+ else
26
+ coles_products = Nokogiri::HTML(coles_js_doc.inner_html)
27
+ all_coles_products = coles_products.css(".product")
28
+ all_coles_products.each do |product|
29
+ if product.css(".product-name").text != ""
30
+ CompareSupermarkets::Product.coles_new_from_search(product)
31
+ end
32
+ end
33
+ ensure
34
+ browser.close
35
+ end
36
+ end
37
+
38
+ def self.search_woolworths_for(search_term)
39
+ browser = Watir::Browser.new :chrome
40
+ browser.goto("https://www.woolworths.com.au/shop/search/products?searchTerm=#{search_term}")
41
+ begin
42
+ woolworths_js_doc = browser.element(class: "layoutWrapper").wait_until(&:present?)
43
+ rescue
44
+ puts "Woolworths does not have this product"
45
+ else
46
+ woolworths_products = Nokogiri::HTML(woolworths_js_doc.inner_html)
47
+ woolworths_all_products = woolworths_products.css(".shelfProductTile-content")
48
+ woolworths_all_products.each do |product|
49
+ if product.css(".shelfProductTile-descriptionLink").text != ""
50
+ if product.css(".unavailableSection.width-full.ng-star-inserted").empty?
51
+ CompareSupermarkets::Product.woolworths_new_from_search(product)
52
+ end
53
+ end
54
+ end
55
+ ensure
56
+ browser.close
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CompareSupermarkets
4
+ VERSION = "0.1.1"
5
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+ module CompareSupermarkets
3
+ class Error < StandardError; end
4
+ end
5
+ require_relative "../config/environment"
6
+
7
+
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: compare_supermarkets
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Justin Berger Howes
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-09-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.2.28
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.2.28
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 13.0.6
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 13.0.6
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.10.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.10.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: nokogiri
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 1.10.8
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 1.10.8
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Will search Woolworths and Coles online stores for prices based on an
84
+ input search parameter
85
+ email:
86
+ - howes.j.j@gmail.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - CHANGELOG.md
92
+ - Gemfile
93
+ - LICENSE.txt
94
+ - README.md
95
+ - Rakefile
96
+ - bin/compare_supermarkets
97
+ - bin/console
98
+ - bin/setup
99
+ - config/environment.rb
100
+ - lib/compare_supermarkets.rb
101
+ - lib/compare_supermarkets/cli.rb
102
+ - lib/compare_supermarkets/product.rb
103
+ - lib/compare_supermarkets/scraper.rb
104
+ - lib/compare_supermarkets/version.rb
105
+ homepage: http://rubygems.org/gems/compare_supermarkets
106
+ licenses:
107
+ - MIT
108
+ metadata:
109
+ homepage_uri: http://rubygems.org/gems/compare_supermarkets
110
+ source_code_uri: https://github.com/happymelonbox/ruby_portfolio_project_gem
111
+ changelog_uri: https://github.com/happymelonbox/ruby_portfolio_project_gem/blob/main/CHANGELOG.md
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ - config
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: 2.4.0
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubygems_version: 3.2.16
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: Compare supermarket prices
132
+ test_files: []