compare_supermarkets 0.2.1 → 0.4.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.
- checksums.yaml +4 -4
- data/bin/console +0 -3
- data/bin/setup +1 -2
- data/config/environment.rb +0 -3
- data/lib/compare_supermarkets/cli.rb +13 -9
- data/lib/compare_supermarkets/product.rb +9 -1
- data/lib/compare_supermarkets/scraper.rb +46 -37
- data/lib/compare_supermarkets/supermarket.rb +44 -23
- data/lib/compare_supermarkets/version.rb +1 -1
- metadata +12 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d8890834ce5a37d23206a1a513f3c57ec0caea90593373662baefdfc2062794
|
4
|
+
data.tar.gz: a6ed1f030433fed9f6cbde6629f384f3e312fb3e3f0edcfa4d193aa4585c4416
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 483653e82b680078090c4b8234086fa8b0bf8a89a8e635902b3b3482f70117f7f1342367a89299c994a3f4029648896191f2a99df417a241a16f9a278d60e47c
|
7
|
+
data.tar.gz: df5dd2e030710133081f2c5d0e4a413daee5e05958bde06d05c90440d4fa23ddc35e953efbaaecaa72fdc55e19f47d4815550de6ee19581bc77cdc5f92d3e501
|
data/bin/console
CHANGED
data/bin/setup
CHANGED
data/config/environment.rb
CHANGED
@@ -2,9 +2,6 @@ require 'pry'
|
|
2
2
|
require 'nokogiri'
|
3
3
|
require 'watir'
|
4
4
|
|
5
|
-
#gem install selenium-webdriver - required for watir to work
|
6
|
-
#brew install --cask chromedriver - required for watir to work
|
7
|
-
|
8
5
|
require_relative '../lib/compare_supermarkets/scraper'
|
9
6
|
require_relative '../lib/compare_supermarkets/product'
|
10
7
|
require_relative '../lib/compare_supermarkets/cli'
|
@@ -1,11 +1,11 @@
|
|
1
1
|
class CompareSupermarkets::CLI
|
2
2
|
def call
|
3
3
|
puts ""
|
4
|
-
puts "Welcome to
|
4
|
+
puts "Welcome to Compare_Supermarkets"
|
5
5
|
puts ""
|
6
6
|
puts "Type q at any time to exit."
|
7
7
|
puts ""
|
8
|
-
puts "Would you like to compare prices between Coles and
|
8
|
+
puts "Would you like to compare prices between Coles and Woolworths (Y/N)"
|
9
9
|
input = gets.strip.downcase
|
10
10
|
puts ""
|
11
11
|
if input == "y"
|
@@ -29,7 +29,7 @@ class CompareSupermarkets::CLI
|
|
29
29
|
def start
|
30
30
|
puts ""
|
31
31
|
puts "Great!"
|
32
|
-
puts "Please enter the name of the item you wish to compare"
|
32
|
+
puts "Please enter the name of the item you wish to compare (example: red tractor oats or purple sweet potato)"
|
33
33
|
input = gets.strip.downcase
|
34
34
|
puts ""
|
35
35
|
puts ""
|
@@ -42,23 +42,25 @@ class CompareSupermarkets::CLI
|
|
42
42
|
self.search_supermarkets(input)
|
43
43
|
puts ""
|
44
44
|
puts ""
|
45
|
-
if CompareSupermarkets::Product.count >
|
45
|
+
if CompareSupermarkets::Product.count > 20
|
46
46
|
puts ""
|
47
47
|
puts "Ooo, jeez, seems like we have a lot of results."
|
48
48
|
puts "We have #{CompareSupermarkets::Product.count} results for you."
|
49
49
|
puts "If you were a little more specific with your search"
|
50
50
|
puts "term, we would have less to sort through..."
|
51
51
|
puts ""
|
52
|
+
puts "If you still want to see all of these results, select N"
|
53
|
+
puts ""
|
52
54
|
change_search_term
|
53
55
|
elsif CompareSupermarkets::Product.count == 0
|
54
56
|
puts ""
|
55
|
-
puts "Ohhh man! Doesn't seem like
|
56
|
-
puts "that product."
|
57
|
+
puts "Ohhh man! Doesn't seem like any of these supermarkets"
|
58
|
+
puts "carry that product."
|
57
59
|
puts ""
|
58
60
|
change_search_term
|
59
61
|
else
|
60
62
|
puts ""
|
61
|
-
puts "Great! We have #{CompareSupermarkets::Product.count} items for you."
|
63
|
+
puts "Great! We have #{CompareSupermarkets::Product.count} items in stock for you."
|
62
64
|
puts ""
|
63
65
|
puts ""
|
64
66
|
puts ""
|
@@ -67,7 +69,8 @@ class CompareSupermarkets::CLI
|
|
67
69
|
end
|
68
70
|
|
69
71
|
def search_supermarkets(input)
|
70
|
-
|
72
|
+
supermarkets = ["Coles", "Woolworths"]
|
73
|
+
CompareSupermarkets::Scraper.search_supermarkets(supermarkets, input)
|
71
74
|
end
|
72
75
|
|
73
76
|
def change_search_term
|
@@ -148,7 +151,7 @@ class CompareSupermarkets::CLI
|
|
148
151
|
|
149
152
|
def finished
|
150
153
|
puts ""
|
151
|
-
puts "Is this what you were looking for?(Y/N)"
|
154
|
+
puts "Is this what you were looking for? (Y/N)"
|
152
155
|
input = gets.strip.downcase
|
153
156
|
if input == "y"
|
154
157
|
puts ""
|
@@ -237,6 +240,7 @@ class CompareSupermarkets::CLI
|
|
237
240
|
def how_to_sort
|
238
241
|
puts ""
|
239
242
|
puts "How would you like your results sorted?"
|
243
|
+
puts ""
|
240
244
|
puts "1 - Cheapest to most expensive"
|
241
245
|
puts "2 - Most expensive to cheapest"
|
242
246
|
puts ""
|
@@ -10,7 +10,7 @@ class CompareSupermarkets::Product
|
|
10
10
|
@unit_size = unit_size
|
11
11
|
@dollar_value = dollar_value
|
12
12
|
@cent_value = cent_value
|
13
|
-
@url =
|
13
|
+
@url = url
|
14
14
|
@@all << self
|
15
15
|
end
|
16
16
|
|
@@ -54,6 +54,14 @@ class CompareSupermarkets::Product
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
+
def self.iga_sorted_by_price
|
58
|
+
iga_items = self.all.select{|product| product.supermarket_name == "IGA"}
|
59
|
+
iga_items.sort_by! do |s|
|
60
|
+
price_to_sort = s.dollar_value + '.' + s.cent_value
|
61
|
+
price_to_sort.to_f
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
57
65
|
def self.clear_all
|
58
66
|
@@all.clear
|
59
67
|
end
|
@@ -6,56 +6,65 @@ class CompareSupermarkets::Scraper
|
|
6
6
|
@search_term = search_term
|
7
7
|
end
|
8
8
|
|
9
|
-
def self.search_supermarkets(search_term)
|
10
|
-
|
11
|
-
|
9
|
+
def self.search_supermarkets(supermarkets, search_term)
|
10
|
+
supermarkets.each do |supermarket|
|
11
|
+
new_supermarket = Kernel.const_get("CompareSupermarkets::#{supermarket}Scraper").new(search_term)
|
12
|
+
new_supermarket.search_browser
|
13
|
+
end
|
12
14
|
end
|
13
15
|
|
14
|
-
def
|
16
|
+
def handle_waiting(supermarket, class_name, all_products, search, search_term, check)
|
15
17
|
browser = Watir::Browser.new :chrome
|
16
|
-
browser.goto("https://shop.coles.com.au/a/national/everything/search/#{search_term}")
|
17
18
|
begin
|
18
|
-
|
19
|
+
browser.goto(search+search_term)
|
20
|
+
js_doc = browser.element(class: class_name).wait_until(&:present?)
|
19
21
|
rescue
|
20
|
-
puts "
|
21
|
-
puts ""
|
22
|
-
puts "Let's check Woolworths"
|
23
|
-
puts ""
|
22
|
+
puts "This product cannot be found"
|
24
23
|
puts ""
|
25
24
|
else
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
coles.add_product(product)
|
25
|
+
products = Nokogiri::HTML(js_doc.inner_html)
|
26
|
+
products.css(all_products).each do |product|
|
27
|
+
if product.css(check).text != ""
|
28
|
+
new_supermarket = Kernel.const_get("CompareSupermarkets::#{supermarket}").new(product)
|
29
|
+
new_supermarket.add_product
|
32
30
|
end
|
33
31
|
end
|
32
|
+
if Kernel.const_get("CompareSupermarkets::#{supermarket}").all_products.count == 0
|
33
|
+
puts "#{supermarket} do not have this item"
|
34
|
+
end
|
34
35
|
ensure
|
35
36
|
browser.close
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
39
|
-
def
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
40
|
+
def search_browser
|
41
|
+
handle_waiting(@supermarket, @class_name, @all_products, @search, @search_term, @check)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class CompareSupermarkets::ColesScraper < CompareSupermarkets::Scraper
|
46
|
+
|
47
|
+
def initialize(search_term)
|
48
|
+
@supermarket = 'Coles'
|
49
|
+
@search = "https://shop.coles.com.au/a/national/everything/search/"
|
50
|
+
@search_term = search_term
|
51
|
+
@class_name = "products"
|
52
|
+
@all_products = ".product"
|
53
|
+
@check = ".product-name"
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
class CompareSupermarkets::WoolworthsScraper < CompareSupermarkets::Scraper
|
59
|
+
|
60
|
+
def initialize(search_term)
|
61
|
+
@supermarket = 'Woolworths'
|
62
|
+
@search = "https://www.woolworths.com.au/shop/search/products?searchTerm="
|
63
|
+
@search_term = search_term
|
64
|
+
@class_name = "layoutWrapper"
|
65
|
+
@all_products = ".shelfProductTile-content"
|
66
|
+
@check = ".shelfProductTile-descriptionLink"
|
60
67
|
end
|
68
|
+
|
61
69
|
end
|
70
|
+
|
@@ -2,35 +2,22 @@ class CompareSupermarkets::Supermarket
|
|
2
2
|
attr_accessor :name
|
3
3
|
|
4
4
|
@@all = []
|
5
|
+
@@products = []
|
5
6
|
|
6
7
|
def initialize(name=nil)
|
7
8
|
@name = name
|
8
9
|
@@all << self
|
9
|
-
@products = []
|
10
|
-
end
|
11
|
-
|
12
|
-
def add_product(product)
|
13
|
-
if self.name == "Coles"
|
14
|
-
new_product = CompareSupermarkets::Product.new(self,
|
15
|
-
product.css(".product-name").text,
|
16
|
-
product.css(".package-price").text.delete_prefix('$').gsub('per', '/'),
|
17
|
-
product.css(".package-size.accessibility-inline").text,
|
18
|
-
product.css(".product-image-link").attribute('href'),
|
19
|
-
product.css(".dollar-value").text,
|
20
|
-
product.css(".cent-value").text.delete_prefix('.'))
|
21
|
-
else
|
22
|
-
new_product = CompareSupermarkets::Product.new(self,
|
23
|
-
product.css(".shelfProductTile-descriptionLink").text,
|
24
|
-
product.css(".shelfProductTile-cupPrice.ng-star-inserted").text.delete_prefix(' $').chomp(" "),
|
25
|
-
product.css(".shelfProductTile-descriptionLink").text.split(" ").last,
|
26
|
-
product.css(".shelfProductTile-descriptionLink").attribute('href').value,
|
27
|
-
product.css(".price-dollars").text,
|
28
|
-
product.css(".price-cents").text)
|
29
|
-
end
|
30
|
-
@products << new_product
|
31
10
|
end
|
32
11
|
|
33
|
-
def
|
12
|
+
def self.all
|
13
|
+
@@all
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.all_products
|
17
|
+
@@products
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.products
|
34
21
|
CompareSupermarkets::Product.all.select{|product| product.supermarket == self}
|
35
22
|
end
|
36
23
|
|
@@ -38,4 +25,38 @@ class CompareSupermarkets::Supermarket
|
|
38
25
|
@@all.clear
|
39
26
|
end
|
40
27
|
|
28
|
+
def add_product
|
29
|
+
if @dollar_value != "0" && @cent_value != "0"
|
30
|
+
new_product = CompareSupermarkets::Product.new(@supermarket, @name, @price, @unit_size, @url, @dollar_value, @cent_value)
|
31
|
+
@@products << new_product
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class CompareSupermarkets::Coles < CompareSupermarkets::Supermarket
|
37
|
+
|
38
|
+
def initialize(product)
|
39
|
+
@product = product
|
40
|
+
@supermarket = self
|
41
|
+
@name = @product.css(".product-name").text
|
42
|
+
@price = @product.css(".package-price").text.delete_prefix('$').gsub('per', '/')
|
43
|
+
@unit_size = @product.css(".package-size.accessibility-inline").text.chomp(' ')
|
44
|
+
@url = "https://shop.coles.com.au#{@product.css(".product-image-link").attribute('href')}"
|
45
|
+
@dollar_value = @product.css(".dollar-value").text
|
46
|
+
@cent_value = @product.css(".cent-value").text.delete_prefix('.')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class CompareSupermarkets::Woolworths < CompareSupermarkets::Supermarket
|
51
|
+
|
52
|
+
def initialize(product)
|
53
|
+
@product = product
|
54
|
+
@supermarket = self
|
55
|
+
@name = @product.css(".shelfProductTile-descriptionLink").text
|
56
|
+
@price = @product.css(".shelfProductTile-cupPrice.ng-star-inserted").text.delete_prefix(' $').chomp(" ")
|
57
|
+
@unit_size = @product.css(".shelfProductTile-descriptionLink").text.split(" ").last
|
58
|
+
@url = "https://www.woolworths.com.au#{@product.css(".shelfProductTile-descriptionLink").attribute('href').value}"
|
59
|
+
@dollar_value = @product.css(".price-dollars").text
|
60
|
+
@cent_value = @product.css(".price-cents").text
|
61
|
+
end
|
41
62
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: compare_supermarkets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Berger Howes
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-10-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -53,33 +53,33 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 3.10.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: pry
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
62
|
-
type: :
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: nokogiri
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
76
|
-
type: :
|
75
|
+
version: 1.10.8
|
76
|
+
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 1.10.8
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: watir
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: 6.19.1
|
90
|
-
type: :
|
90
|
+
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
@@ -101,7 +101,7 @@ dependencies:
|
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: 3.142.7
|
104
|
-
type: :
|
104
|
+
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|