module AiRecipeCapture
Constants
- COOKING_SIGNAL_PATTERN
- INGREDIENTS_HEADER
- METHOD_HEADER
- REMOVELAST_COMMAND
- SOURCE
Public Instance Methods
Source
# File lib/ai/recipe_capture.rb, line 83 def append_recipe_saved_hint(reply) hint = recipe_saved_hint lines = reply.to_s.split("\n") return reply if lines.empty? if lines.length == 1 return "#{lines.first} #{hint}" end footer_idx = lines.rindex { |line| line.match?(/\d+\s+tokens/i) } || (lines.length - 1) lines.insert(footer_idx, hint) lines.join("\n") end
Source
# File lib/ai/recipe_capture.rb, line 55 def capture_from_answer!(network:, channel:, nick:, text:, store: RabbotDb, received_at: nil) parsed = parse_recipe_text(text) return { captured: false, recipe: nil } unless parsed title = parsed[:title].to_s.strip return { captured: false, recipe: nil } if title.empty? ingredients = Array(parsed[:ingredients]).map(&:to_s).map(&:strip).reject(&:empty?) return { captured: false, recipe: nil } if ingredients.empty? recipe = RecipeStore.add_recipe( network: network, channel: channel, nick: nick, title: title, ingredients: ingredients, instructions: parsed[:instructions], source: SOURCE, store: store, received_at: received_at ) { captured: true, recipe: recipe } end
Source
# File lib/ai/recipe_capture.rb, line 97 def cooking_signal?(text) text.to_s.match?(COOKING_SIGNAL_PATTERN) end
Source
# File lib/ai/recipe_capture.rb, line 173 def parse_ingredient_line(line) cleaned = line.to_s.strip cleaned = cleaned.sub(/\A[-*โข]\s*/, "") cleaned = cleaned.sub(/\A\d+[.)]\s*/, "").strip return [] if cleaned.empty? if cleaned.include?(",") || cleaned.match?(/\band\b/i) RecipeStore.parse_ingredients(cleaned) else [cleaned] end end
Source
# File lib/ai/recipe_capture.rb, line 124 def parse_pipe_recipe(plain) parsed = RecipeHistory.parse_history_text(plain) { title: parsed[:title], ingredients: RecipeStore.parse_ingredients(parsed[:ingredients]), instructions: parsed[:instructions] } end
Source
# File lib/ai/recipe_capture.rb, line 44 def parse_recipe_text(text) plain = plain_text(text) return nil if plain.empty? if pipe_recipe?(plain) return parse_pipe_recipe(plain) end parse_section_recipe(plain) if section_recipe?(plain) end
Source
# File lib/ai/recipe_capture.rb, line 152 def parse_section_recipe(plain) lines = plain.split("\n").map(&:strip) ing_idx = lines.index { |line| line.match?(INGREDIENTS_HEADER) } meth_idx = lines.index { |line| line.match?(METHOD_HEADER) } return nil unless ing_idx && meth_idx && meth_idx > ing_idx title = lines[0...ing_idx].reject(&:empty?).first.to_s title = title.sub(/\A[-*โข]\s*/, "").strip ingredient_lines = lines[(ing_idx + 1)...meth_idx].reject(&:empty?) ingredients = ingredient_lines.flat_map { |line| parse_ingredient_line(line) }.uniq instructions = lines[(meth_idx + 1)..].reject(&:empty?).join("\n") { title: title, ingredients: ingredients, instructions: instructions } end
Source
# File lib/ai/recipe_capture.rb, line 120 def pipe_ingredient_list?(ingredients) RecipeStore.parse_ingredients(ingredients).length >= 2 end
Source
# File lib/ai/recipe_capture.rb, line 108 def pipe_recipe?(plain) return false unless plain.include?("|") parsed = RecipeHistory.parse_history_text(plain) title = parsed[:title].to_s.strip ingredients = parsed[:ingredients].to_s.strip return false if title.empty? || ingredients.empty? return false unless pipe_ingredient_list?(ingredients) true end
Source
# File lib/ai/recipe_capture.rb, line 101 def plain_text(text) plain = AiChannelLog.strip_irc_codes(text).strip plain.gsub(/\*\*([^*]+)\*\*/, '\1') .gsub(/\*([^*]+)\*/, '\1') .strip end
Source
# File lib/ai/recipe_capture.rb, line 35 def recipe_output?(text) plain = plain_text(text) return false if plain.empty? return true if pipe_recipe?(plain) section_recipe?(plain) end
Source
# File lib/ai/recipe_capture.rb, line 79 def recipe_saved_hint IrcFormat.muted("(saved to cookbook ยท undo: #{REMOVELAST_COMMAND})") end
Source
# File lib/ai/recipe_capture.rb, line 147 def section_cooking_content?(ingredient_lines, method_text) combined = (Array(ingredient_lines) + [method_text.to_s]).join("\n") cooking_signal?(combined) end
Source
# File lib/ai/recipe_capture.rb, line 133 def section_recipe?(plain) lines = plain.split("\n").map(&:strip) ing_idx = lines.index { |line| line.match?(INGREDIENTS_HEADER) } meth_idx = lines.index { |line| line.match?(METHOD_HEADER) } return false unless ing_idx && meth_idx && meth_idx > ing_idx title = lines[0...ing_idx].reject(&:empty?).first return false if title.to_s.strip.empty? ingredient_lines = lines[(ing_idx + 1)...meth_idx].reject(&:empty?) method_text = lines[(meth_idx + 1)..].reject(&:empty?).join("\n") section_cooking_content?(ingredient_lines, method_text) end