class Cocktail
Constants
- API_BASE
- DEFAULT_MAX_ATTEMPTS
- NO_COCKTAIL_MESSAGE
- PREFERRED_SPIRITS
- RANDOM_URL
- STYLE_TITLE
- USER_AGENT
Public Class Methods
Source
# File plugins/cocktail.rb, line 122 def self.build_suggestion(drink, spirit) { text: format_suggestion(drink, spirit: spirit), id: drink["idDrink"].to_s } end
Source
# File plugins/cocktail.rb, line 29 def self.extract_ingredients(drink) (1..15).filter_map do |index| drink["strIngredient#{index}"]&.strip end.reject(&:empty?) end
Source
# File plugins/cocktail.rb, line 54 def self.format_ingredient_lines(drink) (1..15).filter_map do |index| ingredient = drink["strIngredient#{index}"]&.strip next if ingredient.nil? || ingredient.empty? measure = drink["strMeasure#{index}"]&.strip.to_s entry = [measure, ingredient].reject(&:empty?).join(" ") " • #{entry}" end end
Source
# File plugins/cocktail.rb, line 81 def self.format_suggestion(drink, spirit:) name = drink["strDrink"].to_s.strip glass = drink["strGlass"].to_s.strip instructions = trim_instructions(drink["strInstructions"]) ingredient_lines = format_ingredient_lines(drink) lines = [header(name)] lines << label_line("Spirit", spirit) lines << label_line("Glass", glass) unless glass.empty? lines << "Ingredients:" unless ingredient_lines.empty? lines.concat(ingredient_lines) lines << label_line("How to", instructions) unless instructions.empty? lines << IrcFormat.report_footer("TheCocktailDB") lines.join("\n") end
Source
# File plugins/cocktail.rb, line 77 def self.header(drink_name) IrcFormat.report_header(tag: "COCKTAIL", title: drink_name.to_s, style: STYLE_TITLE) end
Source
# File plugins/cocktail.rb, line 73 def self.label_line(label, value) "#{label} — #{value}" end
Source
# File plugins/cocktail.rb, line 35 def self.matching_spirit(drink) ingredients = extract_ingredients(drink).map(&:downcase) PREFERRED_SPIRITS.find { |spirit| ingredients.include?(spirit.downcase) } end
Source
# File plugins/cocktail.rb, line 44 def self.pick_random_drink(fetch_json:) data = fetch_json.call(RANDOM_URL) drinks = data["drinks"] return nil if drinks.nil? || drinks.empty? drinks.first rescue StandardError nil end
Source
# File plugins/cocktail.rb, line 40 def self.preferred_spirit?(drink) !matching_spirit(drink).nil? end
Source
# File plugins/cocktail.rb, line 97 def self.suggest(rng: Random, fetch_json:, max_attempts: DEFAULT_MAX_ATTEMPTS) target_spirit = PREFERRED_SPIRITS[rng.rand(PREFERRED_SPIRITS.length)] fallback = nil max_attempts.times do drink = pick_random_drink(fetch_json: fetch_json) next unless drink spirit = matching_spirit(drink) next unless spirit fallback ||= [drink, spirit] return build_suggestion(drink, spirit) if spirit == target_spirit end if fallback drink, spirit = fallback return build_suggestion(drink, spirit) end { error: NO_COCKTAIL_MESSAGE } rescue StandardError { error: NO_COCKTAIL_MESSAGE } end
Source
# File plugins/cocktail.rb, line 65 def self.trim_instructions(text, max_sentences: 2) normalized = text.to_s.strip.gsub(/\s+/, " ") return "" if normalized.empty? sentences = normalized.split(/(?<=[.!?])\s+/) sentences.first(max_sentences).join(" ").strip end
Public Instance Methods
Source
# File plugins/cocktail.rb, line 137 def execute(m, _match = nil) result = suggest(fetch_json: method(:fetch_json)) if result[:error] themed_flood_safe_reply(m, result[:error]) return end themed_flood_safe_reply(m, result[:text]) end
Source
# File plugins/cocktail.rb, line 133 def fetch_json(url) RabbotHttp.fetch_json(url, user_agent: USER_AGENT) end
Source
# File plugins/cocktail.rb, line 129 def suggest(**options) self.class.suggest(**options) end