TeaLI 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: '058401081b5bed7164b1f22db49aa7533c552a73ad2ec6dc298bbcd173098997'
4
+ data.tar.gz: 6e755df9c2baa820b11627204a75da8099fab163e1b9f433c20c1867b8f49f12
5
+ SHA512:
6
+ metadata.gz: 8d7ea8766dce8e50f0e5d840bd5f06560f1026c02f28209ac11849650b5f9007ac66280dfd10a4ddcc1857787df258cf748f8efd4619b9c268c10ced2ed5bfe1
7
+ data.tar.gz: 63dccf2c4eb44d93011aff6af0c62d53f2191f935ba496b44fe59343ef1fbfb04512d3dd2e955f115cbbc3af42938380e2f871bb6f319f3b5dc8969c2298d50b
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/teaLI.rb"
4
+
5
+ require 'TeaLI'
6
+
7
+ TeaLI.new.call
@@ -0,0 +1,7 @@
1
+ require_relative "../lib/scraper.rb"
2
+ require_relative "../lib/category.rb"
3
+ require_relative "../lib/tea.rb"
4
+
5
+ require 'pry'
6
+ require 'nokogiri'
7
+ require 'open-uri'
@@ -0,0 +1,23 @@
1
+ require_relative "../config/env.rb"
2
+
3
+ class Category
4
+
5
+ attr_reader :name
6
+ attr_accessor :url, :teas
7
+ @@all = []
8
+
9
+ def initialize(name)
10
+ @name = name
11
+ @teas = []
12
+ @@all << self
13
+ end
14
+
15
+ def self.all
16
+ @@all
17
+ end
18
+
19
+ def self.check_for_category(category_name)
20
+ self.all.detect { |cat| cat.name == category_name }
21
+ end
22
+
23
+ end
@@ -0,0 +1,79 @@
1
+ require_relative "../config/env.rb"
2
+
3
+ class Scraper
4
+
5
+ def get_page(url)
6
+ page = Nokogiri::HTML(open(url))
7
+ page
8
+ end
9
+
10
+ def get_categories
11
+ page = get_page("https://www.adagio.com/list/best_sellers.html")
12
+ page.css("div#accountNav.marginLeft.categoryLeft div.hide_768").each do |category|
13
+ if category.values != ["breakVerySmall hide_768"] && category.css("a").text != "Advanced Search" && Category.all.length < 10
14
+ category_name = category.css("a").text
15
+ category_url = category.css("a").attribute("href").value
16
+ new_category = Category.new(category_name)
17
+ new_category.url = "https://www.adagio.com#{category_url}"
18
+ end
19
+ end
20
+ end
21
+
22
+ def get_teas
23
+ get_categories
24
+ Category.all.each do |category|
25
+ page = get_page(category.url)
26
+ page.css("div.productIndexParent").each do |product|
27
+ if category.teas.length < 10
28
+ new_tea = Tea.new(product.css("h6").text)
29
+ new_tea.url = "https://www.adagio.com" + product.css("a").attribute("href").value
30
+ new_tea.category = category
31
+ category.teas << new_tea
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ def get_tea_info(tea)
38
+ page = get_page(tea.url)
39
+ tea.description = page.css("div.description div").text.split(' | ')[0] + "."
40
+ tea.ingredients = page.css("h5.titlepadding.contentTitleItalics").text
41
+ page.css("div#pricesDiv.pricesList div.itemBlock").each do |price|
42
+ item_size = price.css("div.size").text
43
+ item_size_array = item_size.split(/\W/)
44
+ item_size_array.map do |int|
45
+ if int == ""
46
+ item_size_array.delete(int)
47
+ end
48
+ end
49
+ trimmed_item_size = item_size_array.join(" ")
50
+ weird_price = price.css("div.price").text
51
+ item_price = weird_price.split(/\W/).last
52
+ # this checks for out of stock or unavailable
53
+ if price.css("div.notifyMe").text == "NOTIFY ME" || item_price == ""
54
+ tea.pricing[trimmed_item_size] = "out of stock"
55
+ elsif item_price.to_i >= 1 && item_price != ""
56
+ tea.pricing[trimmed_item_size] = "$" + item_price
57
+ end
58
+ end
59
+ end
60
+
61
+ def get_this_teas_info(tea_name)
62
+ # when we only need info about a single tea
63
+ # utilize check_for_tea_info and find_by_name here
64
+ tea = Tea.find_by_name(tea_name)
65
+ if !tea.check_for_tea_info
66
+ get_tea_info(tea)
67
+ end
68
+ end
69
+
70
+ def get_all_tea_info
71
+ Tea.all.each do |tea|
72
+ if !tea.check_for_tea_info
73
+ get_tea_info(tea)
74
+ end
75
+ end
76
+ end
77
+
78
+ end
79
+
@@ -0,0 +1,45 @@
1
+ require_relative "../config/env.rb"
2
+
3
+ class Tea
4
+
5
+ attr_reader :name
6
+ attr_accessor :url, :ingredients, :description, :pricing, :category
7
+ @@all = []
8
+
9
+ def initialize(name)
10
+ @name = name
11
+ @@all << self
12
+ self.description = ""
13
+ self.ingredients = ""
14
+ self.pricing = {}
15
+ end
16
+
17
+ def self.all
18
+ @@all
19
+ end
20
+
21
+ def self.find_by_name(name)
22
+ @@all.detect {|tea| tea.name == name}
23
+ end
24
+
25
+ # checks whether or not we've already scraped the info about this particular tea object
26
+ # returns true if tea info has already been acquired
27
+ def check_for_tea_info
28
+ self.ingredients.length > 0 && self.description.length > 0 && self.pricing.length > 0
29
+ end
30
+
31
+ def self.all_teas_in(tea_category)
32
+ @@all.select {|tea| tea.category.name == tea_category}
33
+ end
34
+
35
+ def self.find_by_ingredient(ingredient)
36
+ @@all.select { |tea| tea.ingredients.include?(ingredient) }
37
+ end
38
+
39
+ def self.get_random_tea
40
+ rand_tea = Tea.all.sample
41
+ rand_tea.name
42
+ end
43
+
44
+ end
45
+
@@ -0,0 +1,205 @@
1
+ require_relative '../config/env.rb'
2
+
3
+ require 'pry'
4
+
5
+ class TeaLI
6
+ attr_accessor :scraper
7
+
8
+ def initialize
9
+ self.scrape_for_tea
10
+ end
11
+
12
+ def scrape_for_tea
13
+ puts "Loading your TeaLI session. Please wait..."
14
+ @scraper = Scraper.new
15
+ @scraper.get_teas
16
+ end
17
+
18
+ def titleize(word)
19
+ title = word.split.map(&:capitalize).join(' ')
20
+ title
21
+ end
22
+
23
+ def display_categories
24
+ puts "Here are all of our available varieties: "
25
+ puts " "
26
+ Category.all.each_with_index do |category, index|
27
+ puts " #{index+1}. #{category.name}"
28
+ end
29
+ end
30
+
31
+ def display_tea_info(tea_name)
32
+ tea = Tea.find_by_name(tea_name)
33
+ puts " "
34
+ puts "Here are the details for our #{titleize(tea.name)} Tea"
35
+ puts "- - - - - - - - - - - - - - - "
36
+ puts " Description: "
37
+ puts " #{tea.description}"
38
+ puts " "
39
+ puts " Ingredients: "
40
+ if tea.ingredients.length > 0
41
+ puts " This tea is #{tea.ingredients}"
42
+ else
43
+ puts " This is a single origin (non-blended) tea."
44
+ end
45
+ puts " "
46
+ puts " Purchasing Options: "
47
+ tea.pricing.each do |size, price|
48
+ puts " #{size.capitalize}: #{price}"
49
+ end
50
+ end
51
+
52
+ def display_category_teas(category)
53
+ category_name = titleize(category)
54
+ category_teas = Tea.all_teas_in(category_name)
55
+ if category_teas.length > 0
56
+ puts "Here are all of our #{category}: "
57
+ category_teas.each_with_index do |tea, index|
58
+ puts " #{index+1}. #{titleize(tea.name)}"
59
+ end
60
+ else
61
+ puts "Sorry that doesn't appear to be a valid category..."
62
+ display_categories
63
+ end
64
+ end
65
+
66
+ def info_for_one_tea(tea)
67
+ @scraper.get_this_teas_info(tea)
68
+ end
69
+
70
+ def menu_options
71
+ puts "1. See all available tea types."
72
+ puts " "
73
+ puts "2. Search by a specific ingredient."
74
+ puts " "
75
+ puts "3. Surprise me with a random tea!"
76
+ puts " "
77
+ puts "Type 1, 2, or 3 and press ENTER."
78
+ puts " "
79
+ puts "If you are done using the TeaLI, just type EXIT and press ENTER."
80
+ puts "- - - - - - - - - - - - - - - "
81
+ end
82
+
83
+ def surprise_tea
84
+ surprise = Tea.get_random_tea
85
+ @scraper.get_this_teas_info(surprise)
86
+ puts "SURPRISE! You got #{titleize(surprise)} Tea!"
87
+ self.display_tea_info(surprise)
88
+ end
89
+
90
+ def run_categories
91
+ input = nil
92
+
93
+ display_categories
94
+ puts "Which type of teas would you like to see?"
95
+ puts "(Ex: Type 'Black Teas' and press ENTER) "
96
+ puts " "
97
+ puts "(to go back type 'back' and press ENTER)"
98
+ puts " "
99
+
100
+ input = gets.strip.downcase
101
+
102
+ if Category.check_for_category(titleize(input))
103
+ display_category_teas(titleize(input))
104
+ puts " "
105
+ puts "Which tea would you like to know more about? (just type its name and press ENTER)"
106
+ puts "(to go back type 'back' and press ENTER)"
107
+ puts " "
108
+
109
+ input = gets.strip.downcase
110
+
111
+ if input == 'back'
112
+ run_categories
113
+ else
114
+ tea = Tea.find_by_name(input)
115
+ if tea != nil
116
+ info_for_one_tea(tea.name)
117
+ display_tea_info(tea.name)
118
+ else
119
+ puts " "
120
+ puts "Bummer! It looks like that isn't a valid tea name."
121
+ puts " "
122
+ end
123
+ end
124
+ elsif input == 'back'
125
+ return
126
+ elsif !Category.all.include?(titleize(input)) && input != 'back'
127
+ puts "Sorry, please choose a valid tea type!"
128
+ puts " "
129
+ run_categories
130
+ end
131
+ end
132
+
133
+ def run_all_info_search
134
+ puts " "
135
+ puts "Great! Please wait while we gather some information. This will take about 60 seconds..."
136
+ puts " "
137
+ @scraper.get_all_tea_info
138
+ puts " "
139
+ puts "Thanks for waiting!"
140
+ end
141
+
142
+ def run_ingredient_search
143
+ puts " "
144
+ puts "What ingredient are you looking for?"
145
+ puts "(to go back, please type 'back' and press ENTER)"
146
+ user_input = nil
147
+ user_input = gets.strip.downcase
148
+ if user_input == 'back'
149
+ return
150
+ else
151
+ teas = Tea.find_by_ingredient(user_input)
152
+ if teas.length > 0
153
+ puts " "
154
+ puts "Here are all the teas we have that contain #{user_input}"
155
+ puts " "
156
+ teas.each_with_index do |tea, index|
157
+ puts "#{index+1}. #{titleize(tea.name)}"
158
+ end
159
+ puts " "
160
+ puts "Which tea would you like to know more about? (just type its name and press ENTER)"
161
+ puts "or type 'back' to search for a different ingredient..."
162
+ user_input = gets.strip.downcase
163
+ if user_input == 'back'
164
+ run_ingredient_search
165
+ else
166
+ display_tea_info(user_input)
167
+ end
168
+ else
169
+ puts "Sorry, it looks like we don't carry any teas with that ingredient"
170
+ run_ingredient_search
171
+ end
172
+ end
173
+ end
174
+
175
+ def call
176
+ puts " "
177
+ puts "Welcome to the TeaLI! A CLI for finding teas you never knew you needed..."
178
+ user_input = nil
179
+ until user_input == 'exit'
180
+ puts "- - - - - - - - - - - - - - - "
181
+ puts "What would you like to do?"
182
+ puts " "
183
+ menu_options
184
+ user_input = gets.strip.downcase
185
+ if user_input.to_i == 1
186
+ run_categories
187
+ elsif user_input.to_i == 2
188
+ run_all_info_search
189
+ run_ingredient_search
190
+ elsif user_input.to_i == 3
191
+ surprise_tea
192
+ end
193
+ end
194
+ goodbye
195
+ end
196
+
197
+ def goodbye
198
+ puts " "
199
+ puts "Thanks for using TeaLI! Happy Sipping!"
200
+ puts " "
201
+ end
202
+
203
+ end
204
+
205
+
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: TeaLI
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Emily Harber
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-11-01 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A simple CLI application to scrape and search for teas using the Adagio
14
+ Teas website
15
+ email: theoriginalpixi@gmail.com
16
+ executables:
17
+ - TeaLI
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - bin/TeaLI
22
+ - config/env.rb
23
+ - lib/category.rb
24
+ - lib/scraper.rb
25
+ - lib/tea.rb
26
+ - lib/teaLI.rb
27
+ homepage: https://rubygems.org/profiles/TheCodePixi
28
+ licenses:
29
+ - MIT
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubygems_version: 3.0.6
47
+ signing_key:
48
+ specification_version: 4
49
+ summary: A simple scrape/search Tea CLI app
50
+ test_files: []