just-the-recipe 0.1.0
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 +7 -0
- data/.DS_Store +0 -0
- data/.gitignore +10 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +27 -0
- data/README.md +34 -0
- data/Rakefile +4 -0
- data/bin/console +15 -0
- data/bin/just-the-recipe +5 -0
- data/bin/setup +8 -0
- data/just-the-recipe.gemspec +38 -0
- data/lib/environment.rb +14 -0
- data/lib/just-the-recipe/cli.rb +122 -0
- data/lib/just-the-recipe/cookbook.rb +61 -0
- data/lib/just-the-recipe/recipe.rb +72 -0
- data/lib/just-the-recipe/scraper.rb +88 -0
- data/lib/just-the-recipe/searcher.rb +49 -0
- data/lib/just-the-recipe/version.rb +3 -0
- metadata +105 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: dd7b63f04dd0ef8e6536a0a1ec23db9e26491a2e778d4033615ea7630338a527
|
|
4
|
+
data.tar.gz: 27de77e4c6e546a51ed51ef226abd1c85351af531725d093724e0f33c0af0028
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 2e91e8971c95aada57382c7c799d887c0257fb03d43f81f0b3a2c84704e9a9070033b567416c88212cf8b6e47a79da04316fbf69d595c9e6fff513d2e81f05ef
|
|
7
|
+
data.tar.gz: f267754a184f11536aa1f4c96933cdd1d70c333720e66088d66b51bbda2bcad10968e46a62cd26d0c3742c044dfeed1d7ba93f8c32bf8741921e4e63951f6cc5
|
data/.DS_Store
ADDED
|
Binary file
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
just-the-recipe (0.1.0)
|
|
5
|
+
dotenv
|
|
6
|
+
nokogiri
|
|
7
|
+
open-uri
|
|
8
|
+
|
|
9
|
+
GEM
|
|
10
|
+
remote: https://rubygems.org/
|
|
11
|
+
specs:
|
|
12
|
+
dotenv (2.7.6)
|
|
13
|
+
nokogiri (1.11.2-x86_64-darwin)
|
|
14
|
+
racc (~> 1.4)
|
|
15
|
+
open-uri (0.1.0)
|
|
16
|
+
racc (1.5.2)
|
|
17
|
+
rake (13.0.3)
|
|
18
|
+
|
|
19
|
+
PLATFORMS
|
|
20
|
+
x86_64-darwin-20
|
|
21
|
+
|
|
22
|
+
DEPENDENCIES
|
|
23
|
+
just-the-recipe!
|
|
24
|
+
rake (~> 13.0)
|
|
25
|
+
|
|
26
|
+
BUNDLED WITH
|
|
27
|
+
2.2.14
|
data/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Just::The::Recipe
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
Add this line to your application's Gemfile:
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
gem 'just-the-recipe'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
And then execute:
|
|
12
|
+
|
|
13
|
+
$ bundle install
|
|
14
|
+
|
|
15
|
+
Or install it yourself as:
|
|
16
|
+
|
|
17
|
+
$ gem install just-the-recipe
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
To use this gem, you'll need to obtain a free APP ID and APP Key from https://www.edamam.com. Once you have these, create a dotenv file and add these lines at the top:
|
|
22
|
+
|
|
23
|
+
APP_ID = {{APP ID}}
|
|
24
|
+
APP_KEY = {{APP KEY}}
|
|
25
|
+
|
|
26
|
+
## Development
|
|
27
|
+
|
|
28
|
+
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.
|
|
29
|
+
|
|
30
|
+
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).
|
|
31
|
+
|
|
32
|
+
## Contributing
|
|
33
|
+
|
|
34
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/george-dilthey/just-the-recipe.
|
data/Rakefile
ADDED
data/bin/console
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "bundler/setup"
|
|
5
|
+
require "./lib/environment.rb"
|
|
6
|
+
|
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
9
|
+
|
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
11
|
+
# require "pry"
|
|
12
|
+
# Pry.start
|
|
13
|
+
|
|
14
|
+
require "irb"
|
|
15
|
+
IRB.start(__FILE__)
|
data/bin/just-the-recipe
ADDED
data/bin/setup
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "./lib/environment.rb"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "just-the-recipe"
|
|
7
|
+
spec.version = JustTheRecipe::VERSION
|
|
8
|
+
spec.authors = ["George Dilthey"]
|
|
9
|
+
spec.email = ["george.dilthey@gmail.com"]
|
|
10
|
+
|
|
11
|
+
spec.summary = "A recipe and cookbook CLI application."
|
|
12
|
+
spec.description = "A small CLI application to search for recipes and create simple cookbooks."
|
|
13
|
+
spec.homepage = "https://github.com/george-dilthey/just-the-recipe"
|
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
|
|
15
|
+
|
|
16
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org/"
|
|
17
|
+
|
|
18
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
19
|
+
spec.metadata["source_code_uri"] = "https://github.com/george-dilthey/just-the-recipe"
|
|
20
|
+
spec.metadata["changelog_uri"] = "https://github.com/george-dilthey/just-the-recipe"
|
|
21
|
+
|
|
22
|
+
# Specify which files should be added to the gem when it is released.
|
|
23
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
24
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
25
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
|
26
|
+
end
|
|
27
|
+
spec.bindir = "exe"
|
|
28
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
29
|
+
spec.require_paths = ["lib"]
|
|
30
|
+
|
|
31
|
+
# Uncomment to register a new dependency of your gem
|
|
32
|
+
spec.add_dependency "open-uri"
|
|
33
|
+
spec.add_dependency "dotenv"
|
|
34
|
+
spec.add_dependency "nokogiri"
|
|
35
|
+
|
|
36
|
+
# For more information and examples about making a new gem, checkout our
|
|
37
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
|
38
|
+
end
|
data/lib/environment.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'dotenv/load'
|
|
2
|
+
require 'open-uri'
|
|
3
|
+
require 'nokogiri'
|
|
4
|
+
require 'JSON'
|
|
5
|
+
require 'net/http'
|
|
6
|
+
|
|
7
|
+
require './lib/just-the-recipe/version.rb'
|
|
8
|
+
require './lib/just-the-recipe/cli.rb'
|
|
9
|
+
require './lib/just-the-recipe/cookbook.rb'
|
|
10
|
+
require './lib/just-the-recipe/recipe.rb'
|
|
11
|
+
require './lib/just-the-recipe/scraper.rb'
|
|
12
|
+
require './lib/just-the-recipe/searcher.rb'
|
|
13
|
+
|
|
14
|
+
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
require_relative '../environment.rb'
|
|
2
|
+
|
|
3
|
+
class JustTheRecipe::CLI
|
|
4
|
+
|
|
5
|
+
def call
|
|
6
|
+
JustTheRecipe::Cookbook.create_from_files
|
|
7
|
+
puts "Welcome to Just the Recipe! What would you like to do?"
|
|
8
|
+
list_options
|
|
9
|
+
choose_option
|
|
10
|
+
goodbye
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def list_options
|
|
14
|
+
puts "\n\nEnter a number 1-3 or type exit."
|
|
15
|
+
puts "1. Search for a new recipe."
|
|
16
|
+
puts "2. Get a recipe from a url."
|
|
17
|
+
puts "3. View your cookbooks."
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def choose_option
|
|
21
|
+
input = nil
|
|
22
|
+
while input != "exit"
|
|
23
|
+
input = gets.chomp
|
|
24
|
+
if input == "1"
|
|
25
|
+
search
|
|
26
|
+
elsif input == "2"
|
|
27
|
+
scrape_url
|
|
28
|
+
elsif input == "3"
|
|
29
|
+
cookbook_menu
|
|
30
|
+
elsif input == "exit"
|
|
31
|
+
break
|
|
32
|
+
elsif input == "options"
|
|
33
|
+
list_options
|
|
34
|
+
else
|
|
35
|
+
puts "Whoops! Choose a number 1-3, type options to view your options again, or type exit."
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def scrape_url
|
|
41
|
+
puts "Enter your url:"
|
|
42
|
+
url = gets.chomp
|
|
43
|
+
if JustTheRecipe::Scraper.new(url).valid_url?
|
|
44
|
+
recipe = JustTheRecipe::Scraper.new(url).get_recipe_by_schema
|
|
45
|
+
recipe.display_recipe
|
|
46
|
+
add_recipe(recipe)
|
|
47
|
+
list_options
|
|
48
|
+
else
|
|
49
|
+
puts ""
|
|
50
|
+
puts "Sorry, it doesn't look like we can get the recipe from that URL. Try something else."
|
|
51
|
+
list_options
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def add_recipe(recipe)
|
|
56
|
+
puts "Would you like to add this recipe to a cookbook? (y/n)"
|
|
57
|
+
input = gets.chomp
|
|
58
|
+
if input == "y"
|
|
59
|
+
puts "Ok! Which cookbook would you like to add this recipe to? Type an existing cookbook name, or type anything to create a new one!"
|
|
60
|
+
cookbook = gets.chomp
|
|
61
|
+
recipe.add_to_cookbook(cookbook)
|
|
62
|
+
puts "Great choice. We added this recipe to the cookbook called #{cookbook}"
|
|
63
|
+
elsif input == "n"
|
|
64
|
+
puts "No problem. This recipe wasn't added to a cookbook."
|
|
65
|
+
else
|
|
66
|
+
puts "Sorry, you'll have to answer with either 'y' or 'n'."
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def search
|
|
71
|
+
puts "Enter your search term:"
|
|
72
|
+
search_term = gets.chomp
|
|
73
|
+
recipe = JustTheRecipe::Searcher.new(search_term).api_get
|
|
74
|
+
if recipe.class == JustTheRecipe::Recipe
|
|
75
|
+
recipe.display_recipe
|
|
76
|
+
add_recipe(recipe)
|
|
77
|
+
list_options
|
|
78
|
+
else
|
|
79
|
+
list_options
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def cookbook_menu
|
|
84
|
+
if JustTheRecipe::Cookbook.all.length > 0
|
|
85
|
+
puts "Type the name of the cookbook you'd like to view, type \"create\" to create a new one, type \"delete\" to delete a cookbook, or type \"exit\" to return to the main menu.\n\n"
|
|
86
|
+
JustTheRecipe::Cookbook.list_cookbooks
|
|
87
|
+
else
|
|
88
|
+
puts "It looks like you don't have any cookbooks yet. Type \"create\" to create a new one, or type \"exit\" to return to the main menu."
|
|
89
|
+
end
|
|
90
|
+
input = gets.chomp
|
|
91
|
+
|
|
92
|
+
if JustTheRecipe::Cookbook.find_by_name(input)
|
|
93
|
+
puts "Here's what's in the cookbook called #{input}:"
|
|
94
|
+
puts JustTheRecipe::Cookbook.find_by_name(input).return_cookbook
|
|
95
|
+
list_options
|
|
96
|
+
elsif input == "create"
|
|
97
|
+
puts "Ok! What would you like to name your new cookbook?"
|
|
98
|
+
cookbook = gets.chomp
|
|
99
|
+
JustTheRecipe::Cookbook.new(cookbook)
|
|
100
|
+
puts "Great! We created a new cookbook for you. Find some recipes to add to it!"
|
|
101
|
+
list_options
|
|
102
|
+
elsif input == "delete"
|
|
103
|
+
puts "Which cookbook would you like to delete? WARNING: THIS CANNOT BE UNDONE!\n\n"
|
|
104
|
+
JustTheRecipe::Cookbook.list_cookbooks
|
|
105
|
+
delete_cookbook = gets.chomp
|
|
106
|
+
JustTheRecipe::Cookbook.delete(delete_cookbook)
|
|
107
|
+
puts "Ok, we deleted that cookbook."
|
|
108
|
+
list_options
|
|
109
|
+
elsif input == "exit"
|
|
110
|
+
list_options
|
|
111
|
+
else
|
|
112
|
+
puts ""
|
|
113
|
+
puts "Sorry, thats not a valid cookbook. Type \"create\" to create a new cookbook or type \"exit\" to return to the main menu"
|
|
114
|
+
list_cookbooks
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def goodbye
|
|
119
|
+
puts "\n\nThanks for stopping by! If you created any cookbooks, they'll be saved as text files so that you can continue using them in the future. See you soon!"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'pry'
|
|
2
|
+
require './lib/environment.rb'
|
|
3
|
+
|
|
4
|
+
class JustTheRecipe::Cookbook
|
|
5
|
+
|
|
6
|
+
attr_accessor :name
|
|
7
|
+
|
|
8
|
+
@@all = []
|
|
9
|
+
|
|
10
|
+
def initialize(name)
|
|
11
|
+
@name = name
|
|
12
|
+
File.write("#{name}.txt", "" , mode: "a")
|
|
13
|
+
@@all << self
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.all
|
|
17
|
+
@@all
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.create_from_files
|
|
21
|
+
files = Dir["*.txt"]
|
|
22
|
+
files.each do |f|
|
|
23
|
+
name = f.gsub(".txt","")
|
|
24
|
+
find_or_create_by_name(name)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.find_by_name(name)
|
|
29
|
+
@@all.find{|i| i.name == name}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.find_or_create_by_name(name)
|
|
33
|
+
find_by_name(name) ? find_by_name(name) : self.new(name)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def get_recipes
|
|
37
|
+
JustTheRecipe::Recipe.all.select {|i| i.cookbook == self}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def write_recipe_to_cookbook(recipe)
|
|
41
|
+
File.write("#{self.name}.txt", recipe.return_recipe , mode: "a")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.list_cookbooks
|
|
45
|
+
@@all.each{|i| puts "#{i.name}"}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def return_cookbook
|
|
49
|
+
File.read("#{self.name}.txt")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.delete(name)
|
|
53
|
+
if find_by_name(name)
|
|
54
|
+
@@all.delete(find_by_name(name))
|
|
55
|
+
File.delete("#{name}.txt")
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# gd_cookbook = JustTheRecipe::Cookbook.new("George's Cookbook")
|
|
61
|
+
# binding.pry
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require 'pry'
|
|
2
|
+
require './lib/environment.rb'
|
|
3
|
+
|
|
4
|
+
class JustTheRecipe::Recipe
|
|
5
|
+
|
|
6
|
+
attr_accessor :title, :description, :ingredients, :steps, :url, :cookbook
|
|
7
|
+
|
|
8
|
+
@@all = []
|
|
9
|
+
|
|
10
|
+
def initialize(title, description, ingredients, steps, url) # ingredients and steps are arrays
|
|
11
|
+
@title = title
|
|
12
|
+
@description = description
|
|
13
|
+
@ingredients = ingredients
|
|
14
|
+
@steps = steps
|
|
15
|
+
@url = url
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.all
|
|
19
|
+
@@all
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def return_recipe
|
|
23
|
+
"\nRecipe: #{@title}\nDescription: #{@description}\nIngredients:\n#{self.return_ingredients}Steps:\n#{self.return_steps}Source URL: #{self.url}\n***********************\n"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def return_ingredients
|
|
27
|
+
string = ""
|
|
28
|
+
@ingredients.each{|i| string<< "• #{i}\n"}
|
|
29
|
+
string
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def return_steps
|
|
33
|
+
string = ""
|
|
34
|
+
step_count = 1
|
|
35
|
+
@steps.each do |i|
|
|
36
|
+
string << " #{step_count}. #{i}\n"
|
|
37
|
+
step_count += 1
|
|
38
|
+
end
|
|
39
|
+
string
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def display_recipe
|
|
43
|
+
puts "#{return_recipe}"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def add_to_cookbook(name)
|
|
47
|
+
self.cookbook = JustTheRecipe::Cookbook.find_or_create_by_name(name)
|
|
48
|
+
self.cookbook.write_recipe_to_cookbook(self)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.display_cookbook
|
|
52
|
+
if @@all.length > 0
|
|
53
|
+
@@all.each {|r|
|
|
54
|
+
r.display_recipe
|
|
55
|
+
}
|
|
56
|
+
else
|
|
57
|
+
puts "You don't have anything in your cookbook!"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# def save_to_cookbook(cookbook_name)
|
|
62
|
+
# File.write("#{cookbook_name}.txt", self.return_recipe, mode: "a")
|
|
63
|
+
# end
|
|
64
|
+
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# new_recipe = JustTheRecipe::Recipe.new('cookies', 'delicious cookies', ['chocolate chips', 'flour'],['make cookie batter', 'cook cookies'], "www.google.com")
|
|
68
|
+
# new_recipe.add_to_cookbook("George's Cookbook")
|
|
69
|
+
# binding.pry
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require 'pry'
|
|
2
|
+
|
|
3
|
+
require './lib/environment.rb'
|
|
4
|
+
|
|
5
|
+
class JustTheRecipe::Scraper
|
|
6
|
+
|
|
7
|
+
attr_accessor :url
|
|
8
|
+
|
|
9
|
+
def initialize(url)
|
|
10
|
+
@url=url
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get_recipe_by_schema
|
|
14
|
+
schema = get_schema
|
|
15
|
+
|
|
16
|
+
schema.key?("name") ? title = schema["name"] : nil
|
|
17
|
+
schema.key?("description") ? description = schema["description"] : nil
|
|
18
|
+
schema.key?("recipeIngredient") ? ingredients = schema["recipeIngredient"] : ingredients = []
|
|
19
|
+
if schema.key?("recipeInstructions")
|
|
20
|
+
if schema["recipeInstructions"][0].class == Hash && schema["recipeInstructions"][0].key?("itemListElement")
|
|
21
|
+
steps = schema["recipeInstructions"].map {|section| section["itemListElement"].map {|instruction| instruction["text"].gsub("\n","")}}.flatten
|
|
22
|
+
elsif schema["recipeInstructions"][0].class == Array
|
|
23
|
+
steps = schema["recipeInstructions"].flatten.map {|instruction| instruction["text"].gsub("\n","")}
|
|
24
|
+
elsif schema["recipeInstructions"].class == Array
|
|
25
|
+
steps = schema["recipeInstructions"].map {|instruction| instruction["text"].gsub("\n","")}
|
|
26
|
+
else
|
|
27
|
+
steps = [schema["recipeInstructions"]]
|
|
28
|
+
end
|
|
29
|
+
else
|
|
30
|
+
steps = []
|
|
31
|
+
end
|
|
32
|
+
create_new_recipe(title,description,ingredients,steps, @url)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def get_schema
|
|
36
|
+
noko = Nokogiri::HTML(open(@url))
|
|
37
|
+
if (noko.css('script[type*="application/ld+json"].yoast-schema-graph')).length > 0
|
|
38
|
+
js = (noko.css('script[type*="application/ld+json"].yoast-schema-graph'))
|
|
39
|
+
parsed = JSON.parse(js.text)
|
|
40
|
+
graph = parsed["@graph"]
|
|
41
|
+
recipe = graph.find{|i| i["@type"] == "Recipe"}
|
|
42
|
+
else
|
|
43
|
+
js = (noko.css('script[type*="application/ld+json"]'))
|
|
44
|
+
if js.length == 1
|
|
45
|
+
parsed = JSON.parse(js.text)
|
|
46
|
+
parsed.class != Array ? parsed = [parsed] : parsed = parsed
|
|
47
|
+
recipe = parsed.find{|i| i["@type"] == "Recipe"}
|
|
48
|
+
else
|
|
49
|
+
parsed = js.map {|i| valid_json?(i.text) ? JSON.parse(i.text) : nil }
|
|
50
|
+
recipe = parsed.find{|i| i["@type"] == "Recipe"}
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def create_new_recipe(title, description, ingredients, steps, url)
|
|
56
|
+
JustTheRecipe::Recipe.new(title,description,ingredients,steps,url)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def valid_json?(json)
|
|
60
|
+
JSON.parse(json)
|
|
61
|
+
return true
|
|
62
|
+
rescue JSON::ParserError => e
|
|
63
|
+
return false
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def valid_url?
|
|
67
|
+
begin
|
|
68
|
+
get_schema
|
|
69
|
+
rescue
|
|
70
|
+
false
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# veg = JustTheRecipe::Scraper.new('https://www.vegrecipesofindia.com/eggless-chocolate-chip-muffins-recipe/').get_recipe_by_schema.display_recipe
|
|
78
|
+
# all_recipe = JustTheRecipe::Scraper.new('https://www.allrecipes.com/recipe/10813/best-chocolate-chip-cookies/').get_recipe_by_schema.display_recipe
|
|
79
|
+
# serious = JustTheRecipe::Scraper.new('https://www.seriouseats.com/recipes/2021/03/orecchiette-con-le-cime-di-rapa.html').get_recipe_by_schema.display_recipe
|
|
80
|
+
# get = JustTheRecipe::Scraper.new('https://getmecooking.com/recipes/gambas-al-ajillo-con-setas/').get_recipe_by_schema.display_recipe
|
|
81
|
+
# big = JustTheRecipe::Scraper.new('https://blog.bigoven.com/category/bigoven-tips/page/15/').get_recipe_by_schema.display_recipe
|
|
82
|
+
# martha = JustTheRecipe::Scraper.new('https://www.marthastewart.com/1511143/potato-galettes').get_recipe_by_schema.display_recipe
|
|
83
|
+
# food52 = JustTheRecipe::Scraper.new('https://food52.com/recipes/2250-potatoe-chipotle-tacos').get_recipe_by_schema.display_recipe
|
|
84
|
+
# chowhound = JustTheRecipe::Scraper.new('https://www.chowhound.com/recipes/tomato-pie-31670').get_recipe_by_schema.display_recipe
|
|
85
|
+
# food52part2 = JustTheRecipe::Scraper.new('https://food52.com/recipes/10168-sugar-pie').get_recipe_by_schema.display_recipe
|
|
86
|
+
# all_recipe.display_recipe
|
|
87
|
+
|
|
88
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'pry'
|
|
2
|
+
|
|
3
|
+
require './lib/environment.rb'
|
|
4
|
+
|
|
5
|
+
class JustTheRecipe::Searcher
|
|
6
|
+
|
|
7
|
+
def initialize(search_term)
|
|
8
|
+
@search_term = search_term
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def api_get
|
|
12
|
+
begin
|
|
13
|
+
base = 'https://api.edamam.com/search'
|
|
14
|
+
q = @search_term
|
|
15
|
+
app_id = ENV["APP_ID"]
|
|
16
|
+
app_key = ENV["APP_KEY"]
|
|
17
|
+
|
|
18
|
+
url = "#{base}?q=#{q}&app_id=#{app_id}&app_key=#{app_key}"
|
|
19
|
+
uri = URI.parse(url)
|
|
20
|
+
|
|
21
|
+
response = Net::HTTP.get_response(uri)
|
|
22
|
+
results = JSON.parse(response.body)
|
|
23
|
+
hits = results["hits"]
|
|
24
|
+
|
|
25
|
+
good_url = ""
|
|
26
|
+
hits.each do |hit|
|
|
27
|
+
url = hit["recipe"]["url"]
|
|
28
|
+
if JustTheRecipe::Scraper.new(url).valid_url?
|
|
29
|
+
good_url = url
|
|
30
|
+
break
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
scrape_recipe(good_url)
|
|
35
|
+
rescue
|
|
36
|
+
puts "Sorry we couldn't find a valid recipe with that search term."
|
|
37
|
+
puts e
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def scrape_recipe(url)
|
|
43
|
+
JustTheRecipe::Scraper.new(url).get_recipe_by_schema
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# JustTheRecipe::Searcher.new('pie').api_get
|
metadata
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: just-the-recipe
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- George Dilthey
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2021-03-22 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: open-uri
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: dotenv
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: nokogiri
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
description: A small CLI application to search for recipes and create simple cookbooks.
|
|
56
|
+
email:
|
|
57
|
+
- george.dilthey@gmail.com
|
|
58
|
+
executables: []
|
|
59
|
+
extensions: []
|
|
60
|
+
extra_rdoc_files: []
|
|
61
|
+
files:
|
|
62
|
+
- ".DS_Store"
|
|
63
|
+
- ".gitignore"
|
|
64
|
+
- Gemfile
|
|
65
|
+
- Gemfile.lock
|
|
66
|
+
- README.md
|
|
67
|
+
- Rakefile
|
|
68
|
+
- bin/console
|
|
69
|
+
- bin/just-the-recipe
|
|
70
|
+
- bin/setup
|
|
71
|
+
- just-the-recipe.gemspec
|
|
72
|
+
- lib/environment.rb
|
|
73
|
+
- lib/just-the-recipe/cli.rb
|
|
74
|
+
- lib/just-the-recipe/cookbook.rb
|
|
75
|
+
- lib/just-the-recipe/recipe.rb
|
|
76
|
+
- lib/just-the-recipe/scraper.rb
|
|
77
|
+
- lib/just-the-recipe/searcher.rb
|
|
78
|
+
- lib/just-the-recipe/version.rb
|
|
79
|
+
homepage: https://github.com/george-dilthey/just-the-recipe
|
|
80
|
+
licenses: []
|
|
81
|
+
metadata:
|
|
82
|
+
allowed_push_host: https://rubygems.org/
|
|
83
|
+
homepage_uri: https://github.com/george-dilthey/just-the-recipe
|
|
84
|
+
source_code_uri: https://github.com/george-dilthey/just-the-recipe
|
|
85
|
+
changelog_uri: https://github.com/george-dilthey/just-the-recipe
|
|
86
|
+
post_install_message:
|
|
87
|
+
rdoc_options: []
|
|
88
|
+
require_paths:
|
|
89
|
+
- lib
|
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
91
|
+
requirements:
|
|
92
|
+
- - ">="
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: 2.4.0
|
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
|
+
requirements:
|
|
97
|
+
- - ">="
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: '0'
|
|
100
|
+
requirements: []
|
|
101
|
+
rubygems_version: 3.2.6
|
|
102
|
+
signing_key:
|
|
103
|
+
specification_version: 4
|
|
104
|
+
summary: A recipe and cookbook CLI application.
|
|
105
|
+
test_files: []
|