Created
October 19, 2020 17:07
-
-
Save arthur-littm/6d52e3f84d9831ab028def0646fdbed9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require_relative 'cookbook' # You need to create this file! | |
require_relative 'controller' # You need to create this file! | |
require_relative 'router' | |
csv_file = File.join(__dir__, 'recipes.csv') | |
cookbook = Cookbook.new(csv_file) | |
controller = Controller.new(cookbook) | |
router = Router.new(controller) | |
# Start the app | |
router.run |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'open-uri' | |
require 'nokogiri' | |
require_relative 'recipe' | |
require_relative 'view' | |
class Controller | |
def initialize(cookbook) | |
@view = View.new | |
@cookbook = cookbook | |
end | |
def create | |
# ask user for recipe info | |
name = @view.ask_user_for_recipe('name') | |
description = @view.ask_user_for_recipe('description') | |
prep_time = @view.ask_user_for_recipe('prep time') | |
# create a recipe | |
new_recipe = Recipe.new(name, description, prep_time) | |
#store new recipe in cookbook | |
@cookbook.add_recipe(new_recipe) | |
end | |
def list | |
# ask cookbook for all recipes | |
all_recipes = @cookbook.all | |
# give the recipes to the view to display | |
@view.list_recipes(all_recipes) | |
end | |
def destroy | |
# ask user which recipe to destroy | |
index = @view.which_recipe_to_delete | |
# ask the cookbook to remove that recipe from the list | |
@cookbook.delete_recipe(index) | |
end | |
def import_from_web | |
# PSEUDO CODE | |
# 1. ask the user for a keyword to search | |
keyword = @view.ask_for_keyword | |
# 2. display the results in a list with numbers | |
# 2a. Open the web page and parse the page with Nokogiri | |
url = "https://www.allrecipes.com/search/results/?wt=#{keyword}" | |
html_file = open(url).read | |
html_doc = Nokogiri::HTML(html_file) | |
array_of_recipe_instances = [] | |
html_doc.search('.fixed-recipe-card').first(5).each do |element| | |
name = element.search('.fixed-recipe-card__h3').text.strip | |
description = element.search('.fixed-recipe-card__description').text.strip | |
next_url = element.search('a').attribute('href').value | |
new_html_file = open(next_url).read | |
new_html_doc = Nokogiri::HTML(new_html_file) | |
prep_time = new_html_doc.search('.recipe-meta-item .recipe-meta-item-body').first.text.strip | |
# get the link of each recipe page | |
# open that page | |
# on that page search for prep time | |
array_of_recipe_instances << Recipe.new(name, description, prep_time) | |
end | |
# 2b. Inspect the website to understand what CLASSES we will look for | |
# 2c. Put the results in an array | |
# 2d. display the results | |
# -> array to the view | |
@view.list_recipes(array_of_recipe_instances) | |
# 3. Ask the user which one they would like to import | |
# -> Asking for a number! | |
index = @view.ask_for_index | |
recipe = array_of_recipe_instances[index] | |
# 4. Save the recipe into the cookbook (and the csv) | |
@cookbook.add_recipe(recipe) | |
end | |
end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'csv' | |
class Cookbook | |
def initialize(csv_file_path) | |
@csv_file_path = csv_file_path | |
@recipes = [] # An array of `Recipe` instances | |
CSV.foreach(csv_file_path) do |row| | |
@recipes << Recipe.new(row[0], row[1], row[2]) | |
end | |
end | |
def add_recipe(recipe) | |
@recipes << recipe | |
save_csv | |
end | |
def all | |
@recipes | |
end | |
def delete_recipe(index) | |
@recipes.delete_at(index) | |
save_csv | |
end | |
private | |
def save_csv | |
CSV.open(@csv_file_path, 'wb') do |csv_file| | |
@recipes.each do |recipe| | |
csv_file << [recipe.name, recipe.description, recipe.prep_time] | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Recipe | |
# STATE: | |
# name + description (both are strings) | |
attr_reader :name, :description, :prep_time | |
def initialize(name, description, prep_time) | |
@name = name | |
@description = description | |
@prep_time = prep_time | |
end | |
# def name | |
# @name | |
# end | |
# def description | |
# @description | |
# end | |
end | |
# pesto_pasta = Recipe.new('Pesto Pasta', 'Delicious pasta') | |
# puts "Recipe name: #{pesto_pasta.name} Recipe description: #{pesto_pasta.description}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pasta | good | 1hr |
---|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Router | |
def initialize(controller) | |
@controller = controller | |
@running = true | |
end | |
def run | |
puts "Welcome to the Cookbook!" | |
puts " -- " | |
while @running | |
display_tasks | |
action = gets.chomp.to_i | |
print `clear` | |
route_action(action) | |
end | |
end | |
private | |
def route_action(action) | |
case action | |
when 1 then @controller.list | |
when 2 then @controller.create | |
when 3 then @controller.destroy | |
when 4 then @controller.import_from_web | |
when 5 then stop | |
else | |
puts "Please press 1, 2, 3 or 4" | |
end | |
end | |
def stop | |
@running = false | |
end | |
def display_tasks | |
puts "" | |
puts "What do you want to do next?" | |
puts "1 - List all recipes" | |
puts "2 - Create a new recipe" | |
puts "3 - Destroy a recipe" | |
puts "4 - Import from the web" | |
puts "5 - Stop and exit the program" | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class View | |
def ask_user_for_recipe(attribute) | |
puts "What is the #{attribute} of your recipe?" | |
print '> ' | |
return gets.chomp | |
end | |
def list_recipes(recipes) # <- array of `Recipe` instances!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
recipes.each_with_index do |recipe, index| | |
puts "#{index + 1}. #{recipe.name} : #{recipe.description} (#{recipe.prep_time})" | |
end | |
end | |
def which_recipe_to_delete | |
puts 'Which recipe number would you like to delete?' | |
print '> ' | |
return gets.chomp.to_i - 1 # remember to subtract one. Recipe number 1 | |
# is really recipe at index 0 in our cookbook! | |
end | |
def ask_for_keyword | |
puts "What's the keyword?" | |
return gets.chomp | |
end | |
def ask_for_index | |
puts "What's the index?" | |
return gets.chomp.to_i - 1 | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment