tychus 0.0.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 +7 -0
- data/.gitignore +22 -0
- data/.rspec +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +49 -0
- data/Rakefile +2 -0
- data/lib/tychus.rb +12 -0
- data/lib/tychus/parser_selector.rb +17 -0
- data/lib/tychus/parsers.rb +17 -0
- data/lib/tychus/parsers/allrecipes_parser.rb +18 -0
- data/lib/tychus/parsers/base.rb +157 -0
- data/lib/tychus/parsers/food_network_parser.rb +38 -0
- data/lib/tychus/parsers/kraft_recipes_parser.rb +55 -0
- data/lib/tychus/parsers/schema_org_parser.rb +41 -0
- data/lib/tychus/recipe.rb +0 -0
- data/lib/tychus/uri_parser.rb +40 -0
- data/lib/tychus/uri_resolver.rb +40 -0
- data/lib/tychus/utilities/url_parser.rb +0 -0
- data/lib/tychus/version.rb +3 -0
- data/questions.md +10 -0
- data/spec/fixtures/allrecipes.html +3003 -0
- data/spec/fixtures/campbellskitchen.html +2190 -0
- data/spec/fixtures/food_network_double_ingredients_group.html +3725 -0
- data/spec/fixtures/food_network_single_ingredients_group.html +4930 -0
- data/spec/fixtures/kraftrecipes.html +2722 -0
- data/spec/parser_selector.rb +14 -0
- data/spec/parsers/allrecipes_parser_spec.rb +44 -0
- data/spec/parsers/base_spec.rb +3 -0
- data/spec/parsers/food_network_parser_spec.rb +89 -0
- data/spec/parsers/kraft_recipes_parser_spec.rb +67 -0
- data/spec/parsers/schema_org_parser_spec.rb +17 -0
- data/spec/spec_helper.rb +89 -0
- data/spec/tychus_spec.rb +3 -0
- data/spec/uri_resolver_spec.rb +25 -0
- data/tychus.gemspec +29 -0
- metadata +233 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
describe Tychus::ParserSelector do
|
2
|
+
subject(:parser_selector) { Tychus::ParserSelector.new(uri) }
|
3
|
+
|
4
|
+
context "allrecipes.com uris" do
|
5
|
+
let(:uri) { "http://allrecipes.com/Recipe/Chicken-Pot-Pie-IX/Detail.aspx?soid=recs_recipe_2" }
|
6
|
+
|
7
|
+
specify "resolves to the AllrecipesParser" do
|
8
|
+
expect(subject.resolve_parser).to eq(Tychus::Parsers::AllrecipesParser)
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
describe Tychus::Parsers::AllrecipesParser do
|
2
|
+
subject { Tychus.parse(allrecipes_uri) }
|
3
|
+
# 7/26/14 source:
|
4
|
+
# http://allrecipes.com/Recipe/Chicken-Pot-Pie-IX/Detail.aspx?soid=recs_recipe_2
|
5
|
+
let(:allrecipes_uri) { File.expand_path("../../fixtures/allrecipes.html", __FILE__) }
|
6
|
+
let(:ingredients) {
|
7
|
+
[
|
8
|
+
"1 pound skinless, boneless chicken breast halves - cubed",
|
9
|
+
"1 cup sliced carrots",
|
10
|
+
"1 cup frozen green peas",
|
11
|
+
"1/2 cup sliced celery",
|
12
|
+
"1/3 cup butter",
|
13
|
+
"1/3 cup chopped onion",
|
14
|
+
"1/3 cup all-purpose flour",
|
15
|
+
"1/2 teaspoon salt",
|
16
|
+
"1/4 teaspoon black pepper",
|
17
|
+
"1/4 teaspoon celery seed",
|
18
|
+
"1 3/4 cups chicken broth",
|
19
|
+
"2/3 cup milk",
|
20
|
+
"2 (9 inch) unbaked pie crusts"
|
21
|
+
]
|
22
|
+
}
|
23
|
+
let(:instructions) {
|
24
|
+
[
|
25
|
+
"Preheat oven to 425 degrees F (220 degrees C.)",
|
26
|
+
"In a saucepan, combine chicken, carrots, peas, and celery. Add water to cover and boil for 15 minutes. Remove from heat, drain and set aside.",
|
27
|
+
"In the saucepan over medium heat, cook onions in butter until soft and translucent. Stir in flour, salt, pepper, and celery seed. Slowly stir in chicken broth and milk. Simmer over medium-low heat until thick. Remove from heat and set aside.",
|
28
|
+
"Place the chicken mixture in bottom pie crust. Pour hot liquid mixture over. Cover with top crust, seal edges, and cut away excess dough. Make several small slits in the top to allow steam to escape.",
|
29
|
+
"Bake in the preheated oven for 30 to 35 minutes, or until pastry is golden brown and filling is bubbly. Cool for 10 minutes before serving."
|
30
|
+
]
|
31
|
+
}
|
32
|
+
|
33
|
+
its(:name) { is_expected.to eq("Chicken Pot Pie IX") }
|
34
|
+
its(:author) { is_expected.to eq("Robbie Rice") }
|
35
|
+
its(:prep_time) { is_expected.to eq("PT20M") }
|
36
|
+
its(:cook_time) { is_expected.to eq("PT50M") }
|
37
|
+
its(:total_time) { is_expected.to eq("PT1H10M") }
|
38
|
+
its(:yield) { is_expected.to eq("1 - 9 inch pie") }
|
39
|
+
its(:ingredients) { is_expected.to eq(ingredients) }
|
40
|
+
its(:instructions) { is_expected.to eq(instructions) }
|
41
|
+
its(:image) { is_expected.to eq("http://images.media-allrecipes.com/userphotos/250x250/00/14/23/142350.jpg") }
|
42
|
+
its(:description) { is_expected.to eq("\"A delicious chicken pie made from scratch with carrots, peas and celery.\"") }
|
43
|
+
end
|
44
|
+
|
@@ -0,0 +1,89 @@
|
|
1
|
+
describe Tychus::Parsers::FoodNetworkParser do
|
2
|
+
subject { Tychus::Parsers::FoodNetworkParser.new(food_network_uri) }
|
3
|
+
|
4
|
+
context "When the page has a single ingredients group" do
|
5
|
+
# NOTE: this specific uri has an author who's hidden in an anchor
|
6
|
+
# tag that also references her TV show and episode the recipe
|
7
|
+
# appeared. #parse_author may be complex for this edge case
|
8
|
+
# NOTE: author is formatted using schema.org/Person
|
9
|
+
|
10
|
+
# 7/26/14 source: http://www.foodnetwork.com/recipes/ina-garten/grilled-panzanella-recipe.html?ic1=obinsite^
|
11
|
+
let(:food_network_uri) { File.expand_path("../../fixtures/food_network_single_ingredients_group.html", __FILE__) }
|
12
|
+
let(:ingredients) {
|
13
|
+
[
|
14
|
+
"Good olive oil",
|
15
|
+
"1 teaspoon minced garlic",
|
16
|
+
"1/2 teaspoon Dijon mustard",
|
17
|
+
"2 tablespoons champagne vinegar",
|
18
|
+
"Kosher salt and freshly ground black pepper",
|
19
|
+
"1/2 hothouse cucumber, unpeeled, seeded and sliced 1/2-inch thick",
|
20
|
+
"1 large ripe tomato, cut into 1-inch cubes",
|
21
|
+
"10 large basil leaves",
|
22
|
+
"3 tablespoons capers, drained",
|
23
|
+
"1 red onion, sliced into 1/4 inch rounds",
|
24
|
+
"1 red bell pepper, seeded and cut into 3 large pieces",
|
25
|
+
"1 yellow bell pepper, seeded and cut into 3 large pieces",
|
26
|
+
"1/2 small ficelle, cut into 1-inch thick slices"
|
27
|
+
]
|
28
|
+
}
|
29
|
+
let(:instructions) {
|
30
|
+
[
|
31
|
+
"Prepare a charcoal grill with hot coals. Brush the grilling rack with olive oil.",
|
32
|
+
"In a small bowl, whisk together the garlic, mustard, vinegar, 1/4 cup olive oil, 1/2 teaspoon salt and 1/4 teaspoon pepper. Set aside.",
|
33
|
+
"Place the cucumber, tomato, basil and capers in a large bowl, sprinkle with salt and pepper and toss together. Set aside.",
|
34
|
+
"When the grill is ready, brush 1 side of the onion slices and the peppers with olive oil. Place them, olive oil side down, on the grill and cook for 4 minutes. Brush the other side with olive oil, turn them over and continue cooking an additional 4 minutes. Remove the vegetables from the grill and place on a cutting board. Slice the peppers 1/2-inch thick, separate the onion rings and add them both to the cucumber mixture.",
|
35
|
+
"Brush the bread slices on both sides with olive oil and toast them on the grill until golden. Add them to the cucumber mixture. Pour the reserved vinaigrette over the vegetables and toss together. Serve warm."
|
36
|
+
]
|
37
|
+
}
|
38
|
+
|
39
|
+
it "parses the name of the recipe" do
|
40
|
+
expect(subject.parse_name).to eq("Grilled Panzanella")
|
41
|
+
end
|
42
|
+
|
43
|
+
it "parses the author" do
|
44
|
+
expect(subject.parse_author).to eq("Ina Garten")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "parses the prep time" do
|
48
|
+
expect(subject.parse_prep_time).to eq("PT0H25M")
|
49
|
+
end
|
50
|
+
|
51
|
+
it "parses the cook time" do
|
52
|
+
expect(subject.parse_cook_time).to eq("PT0H20M")
|
53
|
+
end
|
54
|
+
|
55
|
+
it "parses the total time" do
|
56
|
+
expect(subject.parse_total_time).to eq("PT0H45M")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "parses the yield" do
|
60
|
+
expect(subject.parse_recipe_yield).to eq("6 servings")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "parses the ingredients" do
|
64
|
+
expect(subject.parse_ingredients).to eq(ingredients)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "parses the instructions" do
|
68
|
+
expect(subject.parse_recipe_instructions).to eq(instructions)
|
69
|
+
end
|
70
|
+
|
71
|
+
xit "parses the image" do
|
72
|
+
# currently two item properties with "image" exist:
|
73
|
+
# one of which comes from a microformat for Person, which
|
74
|
+
# references the author, and is the image of the author,
|
75
|
+
# and another which is the correct image
|
76
|
+
#
|
77
|
+
# Cannot just remove the microformat for Person, like we do for
|
78
|
+
# VideoObject and for Review, because in this case, the Person
|
79
|
+
# microformat contains the author name which must not be deleted
|
80
|
+
# before parsing
|
81
|
+
end
|
82
|
+
|
83
|
+
it "parses the description" do
|
84
|
+
expect(subject.parse_description).to eq("Get this all-star, easy-to-follow Grilled Panzanella recipe from Ina Garten.")
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
describe Tychus::Parsers::KraftRecipesParser do
|
2
|
+
def null_object
|
3
|
+
Tychus::Parsers::NullObject
|
4
|
+
end
|
5
|
+
|
6
|
+
subject { Tychus::Parsers::KraftRecipesParser.new(kraft_recipes_uri) }
|
7
|
+
|
8
|
+
let(:kraft_recipes_uri) { File.expand_path("../../fixtures/kraftrecipes.html", __FILE__) }
|
9
|
+
|
10
|
+
let(:ingredients) {
|
11
|
+
[
|
12
|
+
"1 lb. boneless skinless chicken breasts, cut into 1-1/2-inch pieces",
|
13
|
+
"2 cups fresh pineapple chunks (1-1/2 inch)",
|
14
|
+
#NOTE: This is an escaped whitespace I'm punting on
|
15
|
+
"1 each red and green pepper, cut into 1-1/2-inch pieces",
|
16
|
+
"1/2 cup KRAFT Original Barbecue Sauce",
|
17
|
+
"3 Tbsp. frozen orange juice concentrate, thawed"
|
18
|
+
]
|
19
|
+
}
|
20
|
+
|
21
|
+
let(:instructions) {
|
22
|
+
[
|
23
|
+
"HEAT grill to medium-high heat.",
|
24
|
+
"THREAD chicken alternately with pineapple and peppers onto 8 long wooden skewers, using 2 skewers placed side-by-side for each kabob.",
|
25
|
+
"MIX barbecue sauce and juice concentrate; brush half evenly onto kabobs.",
|
26
|
+
"GRILL 8 to 10 min. or until chicken is done, turning and brushing occasionally with remaining sauce."
|
27
|
+
]
|
28
|
+
}
|
29
|
+
|
30
|
+
it "parses the name of the recipe" do
|
31
|
+
expect(subject.parse_name).to eq("Sweet BBQ Chicken Kabobs")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "parses the author" do
|
35
|
+
expect(subject.parse_author).to be_a null_object
|
36
|
+
end
|
37
|
+
|
38
|
+
it "parses the prep time" do
|
39
|
+
expect(subject.parse_prep_time).to eq("PT25M")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "parses the cook time" do
|
43
|
+
expect(subject.parse_cook_time).to be_a null_object
|
44
|
+
end
|
45
|
+
|
46
|
+
it "parses the total time" do
|
47
|
+
expect(subject.parse_total_time).to eq("PT25M")
|
48
|
+
end
|
49
|
+
|
50
|
+
it "parses the yield" do
|
51
|
+
expect(subject.parse_recipe_yield).to eq("4 servings")
|
52
|
+
end
|
53
|
+
|
54
|
+
xit "parses the ingredients (bug with escaped backspace that cant be stripped)" do
|
55
|
+
expect(subject.parse_ingredients).to eq(ingredients)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "parses the instructions" do
|
59
|
+
expect(subject.parse_recipe_instructions).to eq(instructions)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "parses the description" do
|
63
|
+
expect(subject.parse_description).to eq("These better-for-you BBQ chicken kabobs have an island vibe going on. Think OJ, fresh pineapple and peppers. Now all you need is a drink with an umbrella.")
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
describe Tychus::Parsers::SchemaOrgParser do
|
2
|
+
context "on creation" do
|
3
|
+
let(:allrecipes_uri) { File.expand_path("../../fixtures/allrecipes.html", __FILE__) }
|
4
|
+
let(:parser) { Tychus::Parsers::AllrecipesParser.new(allrecipes_uri) }
|
5
|
+
|
6
|
+
it "strips the Review microformat from node to prevent name collisions with item properties of different microformats" do
|
7
|
+
expect(parser.recipe_doc.css(parser.class.review_doc)).to be_empty
|
8
|
+
end
|
9
|
+
|
10
|
+
it "strips the videoObject microformat from node to prevent name collisions with item properties of different microformats" do
|
11
|
+
expect(parser.recipe_doc.css(parser.class.video_object_doc)).to be_empty
|
12
|
+
end
|
13
|
+
|
14
|
+
pending "find a non schema org recipe to test that it does not attempt to call #strip_review_microformat"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'tychus'
|
2
|
+
require 'webmock/rspec'
|
3
|
+
require 'rspec/its'
|
4
|
+
require 'vcr'
|
5
|
+
require 'pry'
|
6
|
+
|
7
|
+
VCR.configure do |c|
|
8
|
+
c.cassette_library_dir = 'fixtures/cassettes'
|
9
|
+
c.hook_into :webmock
|
10
|
+
end
|
11
|
+
|
12
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
13
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
14
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause this
|
15
|
+
# file to always be loaded, without a need to explicitly require it in any files.
|
16
|
+
#
|
17
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
18
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
19
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
20
|
+
# individual file that may not need all of that loaded. Instead, make a
|
21
|
+
# separate helper file that requires this one and then use it only in the specs
|
22
|
+
# that actually need it.
|
23
|
+
#
|
24
|
+
# The `.rspec` file also contains a few flags that are not defaults but that
|
25
|
+
# users commonly want.
|
26
|
+
#
|
27
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
28
|
+
RSpec.configure do |config|
|
29
|
+
# The settings below are suggested to provide a good initial experience
|
30
|
+
# with RSpec, but feel free to customize to your heart's content.
|
31
|
+
=begin
|
32
|
+
# These two settings work together to allow you to limit a spec run
|
33
|
+
# to individual examples or groups you care about by tagging them with
|
34
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
35
|
+
# get run.
|
36
|
+
config.filter_run :focus
|
37
|
+
config.run_all_when_everything_filtered = true
|
38
|
+
|
39
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
40
|
+
# file, and it's useful to allow more verbose output when running an
|
41
|
+
# individual spec file.
|
42
|
+
if config.files_to_run.one?
|
43
|
+
# Use the documentation formatter for detailed output,
|
44
|
+
# unless a formatter has already been configured
|
45
|
+
# (e.g. via a command-line flag).
|
46
|
+
config.default_formatter = 'doc'
|
47
|
+
end
|
48
|
+
|
49
|
+
# Print the 10 slowest examples and example groups at the
|
50
|
+
# end of the spec run, to help surface which specs are running
|
51
|
+
# particularly slow.
|
52
|
+
config.profile_examples = 10
|
53
|
+
|
54
|
+
# Run specs in random order to surface order dependencies. If you find an
|
55
|
+
# order dependency and want to debug it, you can fix the order by providing
|
56
|
+
# the seed, which is printed after each run.
|
57
|
+
# --seed 1234
|
58
|
+
config.order = :random
|
59
|
+
|
60
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
61
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
62
|
+
# test failures related to randomization by passing the same `--seed` value
|
63
|
+
# as the one that triggered the failure.
|
64
|
+
Kernel.srand config.seed
|
65
|
+
|
66
|
+
# rspec-expectations config goes here. You can use an alternate
|
67
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
68
|
+
# assertions if you prefer.
|
69
|
+
config.expect_with :rspec do |expectations|
|
70
|
+
# Enable only the newer, non-monkey-patching expect syntax.
|
71
|
+
# For more details, see:
|
72
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
73
|
+
expectations.syntax = :expect
|
74
|
+
end
|
75
|
+
|
76
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
77
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
78
|
+
config.mock_with :rspec do |mocks|
|
79
|
+
# Enable only the newer, non-monkey-patching expect syntax.
|
80
|
+
# For more details, see:
|
81
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
82
|
+
mocks.syntax = :expect
|
83
|
+
|
84
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
85
|
+
# a real object. This is generally recommended.
|
86
|
+
mocks.verify_partial_doubles = true
|
87
|
+
end
|
88
|
+
=end
|
89
|
+
end
|
data/spec/tychus_spec.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# at this point intime, allrecipes/campbellskitchen/kraftrecipes
|
2
|
+
# fixtures all contain both schema.org/recipe canonical uri elements as
|
3
|
+
# well as open graph canonical uri elements
|
4
|
+
#
|
5
|
+
describe Tychus::URIResolver do
|
6
|
+
context "when schema.org and opengraph canonical uri properties exist" do
|
7
|
+
let(:allrecipes_uri) { File.expand_path("../fixtures/allrecipes.html", __FILE__) }
|
8
|
+
let(:campbells_kitchen_uri) { File.expand_path("../fixtures/campbellskitchen.html", __FILE__) }
|
9
|
+
let(:kraft_recipes_uri) { File.expand_path("../fixtures/kraftrecipes.html", __FILE__) }
|
10
|
+
let(:examples) { [
|
11
|
+
[allrecipes_uri, 'allrecipes.com'],
|
12
|
+
[campbells_kitchen_uri, 'campbellskitchen.com'],
|
13
|
+
[kraft_recipes_uri, 'kraftrecipes.com']
|
14
|
+
]}
|
15
|
+
|
16
|
+
it "able to retrieve it" do
|
17
|
+
examples.each do |html|
|
18
|
+
page = html[0]
|
19
|
+
host = Regexp.new(html[1])
|
20
|
+
expect(Tychus::URIResolver.new(page).resolve_uri).to match_regex(host)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
data/tychus.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'tychus/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "tychus"
|
8
|
+
spec.version = Tychus::VERSION
|
9
|
+
spec.authors = ["Wayne Yang"]
|
10
|
+
spec.email = ["waysidekoi@gmail.com"]
|
11
|
+
spec.summary = %q{Web recipe parser}
|
12
|
+
spec.license = "MIT"
|
13
|
+
|
14
|
+
spec.files = `git ls-files -z`.split("\x0")
|
15
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
20
|
+
spec.add_development_dependency "rspec", "~> 3.0.0"
|
21
|
+
spec.add_development_dependency "rspec-its"
|
22
|
+
spec.add_development_dependency "pry"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
spec.add_development_dependency "vcr"
|
25
|
+
spec.add_development_dependency "webmock"
|
26
|
+
spec.add_dependency "nokogiri", "~> 1.6.3"
|
27
|
+
spec.add_dependency "addressable", "~> 2.3.6"
|
28
|
+
spec.add_dependency "activesupport"
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,233 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tychus
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Wayne Yang
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-28 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: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.0.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 3.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec-its
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
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
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: vcr
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: webmock
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: nokogiri
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.6.3
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.6.3
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: addressable
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 2.3.6
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 2.3.6
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: activesupport
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description:
|
154
|
+
email:
|
155
|
+
- waysidekoi@gmail.com
|
156
|
+
executables: []
|
157
|
+
extensions: []
|
158
|
+
extra_rdoc_files: []
|
159
|
+
files:
|
160
|
+
- ".gitignore"
|
161
|
+
- ".rspec"
|
162
|
+
- Gemfile
|
163
|
+
- LICENSE.txt
|
164
|
+
- README.md
|
165
|
+
- Rakefile
|
166
|
+
- lib/tychus.rb
|
167
|
+
- lib/tychus/parser_selector.rb
|
168
|
+
- lib/tychus/parsers.rb
|
169
|
+
- lib/tychus/parsers/allrecipes_parser.rb
|
170
|
+
- lib/tychus/parsers/base.rb
|
171
|
+
- lib/tychus/parsers/food_network_parser.rb
|
172
|
+
- lib/tychus/parsers/kraft_recipes_parser.rb
|
173
|
+
- lib/tychus/parsers/schema_org_parser.rb
|
174
|
+
- lib/tychus/recipe.rb
|
175
|
+
- lib/tychus/uri_parser.rb
|
176
|
+
- lib/tychus/uri_resolver.rb
|
177
|
+
- lib/tychus/utilities/url_parser.rb
|
178
|
+
- lib/tychus/version.rb
|
179
|
+
- questions.md
|
180
|
+
- spec/fixtures/allrecipes.html
|
181
|
+
- spec/fixtures/campbellskitchen.html
|
182
|
+
- spec/fixtures/food_network_double_ingredients_group.html
|
183
|
+
- spec/fixtures/food_network_single_ingredients_group.html
|
184
|
+
- spec/fixtures/kraftrecipes.html
|
185
|
+
- spec/parser_selector.rb
|
186
|
+
- spec/parsers/allrecipes_parser_spec.rb
|
187
|
+
- spec/parsers/base_spec.rb
|
188
|
+
- spec/parsers/food_network_parser_spec.rb
|
189
|
+
- spec/parsers/kraft_recipes_parser_spec.rb
|
190
|
+
- spec/parsers/schema_org_parser_spec.rb
|
191
|
+
- spec/spec_helper.rb
|
192
|
+
- spec/tychus_spec.rb
|
193
|
+
- spec/uri_resolver_spec.rb
|
194
|
+
- tychus.gemspec
|
195
|
+
homepage:
|
196
|
+
licenses:
|
197
|
+
- MIT
|
198
|
+
metadata: {}
|
199
|
+
post_install_message:
|
200
|
+
rdoc_options: []
|
201
|
+
require_paths:
|
202
|
+
- lib
|
203
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
204
|
+
requirements:
|
205
|
+
- - ">="
|
206
|
+
- !ruby/object:Gem::Version
|
207
|
+
version: '0'
|
208
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
209
|
+
requirements:
|
210
|
+
- - ">="
|
211
|
+
- !ruby/object:Gem::Version
|
212
|
+
version: '0'
|
213
|
+
requirements: []
|
214
|
+
rubyforge_project:
|
215
|
+
rubygems_version: 2.2.2
|
216
|
+
signing_key:
|
217
|
+
specification_version: 4
|
218
|
+
summary: Web recipe parser
|
219
|
+
test_files:
|
220
|
+
- spec/fixtures/allrecipes.html
|
221
|
+
- spec/fixtures/campbellskitchen.html
|
222
|
+
- spec/fixtures/food_network_double_ingredients_group.html
|
223
|
+
- spec/fixtures/food_network_single_ingredients_group.html
|
224
|
+
- spec/fixtures/kraftrecipes.html
|
225
|
+
- spec/parser_selector.rb
|
226
|
+
- spec/parsers/allrecipes_parser_spec.rb
|
227
|
+
- spec/parsers/base_spec.rb
|
228
|
+
- spec/parsers/food_network_parser_spec.rb
|
229
|
+
- spec/parsers/kraft_recipes_parser_spec.rb
|
230
|
+
- spec/parsers/schema_org_parser_spec.rb
|
231
|
+
- spec/spec_helper.rb
|
232
|
+
- spec/tychus_spec.rb
|
233
|
+
- spec/uri_resolver_spec.rb
|