Add example bot gordon

mio 2022-08-29 23:13:52 +00:00
parent edae077b1d
commit 4218f22d2d
12 changed files with 553 additions and 4 deletions

View File

@ -125,9 +125,9 @@ The `examples/` directory has a few demo bots to show how to use the module.
- *ramenkan*: a bot that serves ramen. It has some custom config settings and - *ramenkan*: a bot that serves ramen. It has some custom config settings and
scheduled tasks. scheduled tasks.
- *hachi*: a bot inspired by tracery text expansion. Loads files ("foils") - *hachi* and *gordon*: bots inspired by tracery text expansion. Loads files
containing selection tables and creates handlers to return responses, one ("foils") containing selection tables and creates handlers to return
service code per foil. responses, one service code per foil.
## Running a bot as a background process ## Running a bot as a background process

View File

@ -0,0 +1,50 @@
grammar = {
meat_set = {
"360 Burger with a large patty, tomatoes, cheddar and onions in a Dijon mustard sauce",
"Bada Boom cheeseburger with a juicy steak, cheddar, onions and tomatoes",
"Bag Baguette featuring two patties and Emmental cheese in a long crusty baguette",
"BagFirst Kitchen Ranch Ketchup burger with a spicy chicken patty in a cheddar ranch ketchup sauce",
"BB Cola burger with sausage, sweet peppers and Comté cheese with barbecue sauce",
"Beast Bacon Onion burger",
"Bigga Bag quadruple-patty burger",
"Gourmand Classic Chicago burger with two thick patties in a sweet and smoky BBQ sauce",
"Dig Tasty with a big steak, Emmental cheese in a smoky sauce",
"Double Cheese Docks with double patties, slices of bacon, cheddar and carmelised onions",
"Fermidable burger with a lightly grilled patty and stuffed with cheese",
"Krilled Cheese and Bacon burger",
"Itty Bitty Italian cheeseburger mozzarella, tomatoes and fresh herbs",
"Louisiana Ligature with double patties, bacon and cheddar, spiced up with a Louisiana sauce",
"Masterly Seasoned Ceasar classic burger with 2 steaks, bacon and extra salad",
"Pollo Loco with a chicken patty and mild avocado sauce",
"Pong Bacon burger with double patties and double cheese",
"Rippled Cheese Bacon burger with thrice the cheddar, grilled bacon and ketchup",
"Sausage Hopper with jalapeños and salsa",
"Stoked Pepper Stash Burger with tomatoes, cornichons, bacon and pepper sauce",
"Super Bacon burger",
"Vast Veggie burger with a veggie patty and Emmental cheese",
},
veggie_set = {
"Veggie Thing overflowing with a spicy sauce",
},
meat_side = {
"chicken fries",
"homemade fries with a dreamy deluxe dip",
},
veggie_side = {
"chips deluged with ketchup",
"onion rings",
},
dessert = {
"chocolate and hazelnut pie",
"lemon pie",
"set of 3 petit pancakes topped with hazelnut cocoa or strawberry cream",
},
origin = {
"Here, have a #meat_set#!",
"Here, have a #veggie_set#!",
"Here, have a #meat_set#, served with a side of #meat_side#!",
"Here, have a #meat_set#, served with a side of #veggie_side#!",
"Here, have a #veggie_set#, served with a side of #veggie_side#!",
"Here, have a #meat_set#, served with a #dessert#!",
}
}

View File

@ -0,0 +1,106 @@
-- See also https://en.wikipedia.org/wiki/Burger
grammar = {
meat_patty = {
"Angus beef",
"chicken",
"lamb",
"portobello mushroom",
"pulled pork",
"sausage",
"steak",
"tuna mayonnaise rice",
"turkey",
"wagyu",
},
veggie_patty = {
"coconut",
"nutty",
"possible",
"soy",
"tofu",
"veggie delight",
},
veggie = {
"kimchi",
"jalapeño peppers",
"lettuce",
"onions",
"pickles",
"tomatoes",
},
cheese = {
"cheddar",
"Beaufort",
"Cantal",
"Comté",
"Emmental",
"goat",
"mozzarella",
},
-- May contain dairy
meat_sauce = {
"algerian sauce",
"andalousian sauce",
"bechamel sauce",
"burger sauce", -- Also known as Marie Rose/cocktail sauce
"moroccan sauce",
"samurai sauce",
"tartare sauce",
"tunisian sauce",
},
veggie_sauce = {
"barbecue sauce",
"curry sauce",
"Dijon mustard",
"ketchup",
},
meat_burger = {
"#meat_patty# burger with slices of #cheese# and dredged in #meat_sauce#",
"#meat_patty# burger with slices of #cheese# and dripping with #veggie_sauce#",
"#meat_patty# burger with #veggie# and #cheese# cheese in #meat_sauce#",
"#meat_patty# burger with #veggie# and oozing #cheese# cheese in #veggie_sauce#",
"#meat_patty# burger with #veggie#, #veggie# and #cheese# cheese in #meat_sauce#",
"#meat_patty# burger with #veggie#, #veggie# and #cheese# cheese in #veggie_sauce#",
"#meat_patty# burger with #veggie# and #veggie# in #meat_sauce#",
"#meat_patty# burger with #veggie# and #veggie#, glistening in #veggie_sauce#",
},
veggie_burger = {
"#veggie_patty# burger with #veggie#, #veggie# and #veggie# in #veggie_sauce#",
},
meat_side = {
"chicken nuggets",
"crispy mushrooms",
"mac and cheese",
"pasta salad", -- May contain cheese
"potato salad", -- May contain eggs/mayonnaise
"rosemary and garlic fries", -- Contains cheese
},
veggie_side = {
"avocado salad",
"BBQ baked beans",
"BBQ potato chips",
"caesar salad",
"coleslaw",
"corn on the cob",
"corn salad",
"french fries",
"french potato salad",
"fried pickles",
"fried shishito peppers",
"a fruit bowl",
"onion rings",
"potato wedges",
"roasted tomatoes",
"sweet potato fries",
"a three-bean salad",
"tempura green beans",
"zucchini chips",
},
origin = {
"Here, have a #meat_burger#!",
"Here, have a #veggie_burger#!",
"Here, have a #meat_burger#, served with #meat_side#!",
"Here, have a #meat_burger#, served with #veggie_side#!",
"Here, have a #veggie_burger#, served with #veggie_side#!",
}
}

View File

@ -0,0 +1,38 @@
-- See also https://en.wikipedia.org/wiki/List_of_coffee_drinks
grammar = {
coffee = {
"black coffee",
"café allongé",
"café au lait",
"café cortado",
"café crema",
"café cubano",
"café miel",
"caffè americano",
"caffè corretto",
"cappuccino",
"caramel macchiato",
"Columbian coffee",
"dalgona coffee",
"doppio",
"egg coffee",
"espresso",
"espresso romano",
"frappuccino",
"iced cappuccino",
"iced mocha",
"Indian filter coffee",
"Irish coffee",
"Kona coffee",
"kopi tubruk",
"Kurdish coffee",
"latte macchiato",
"marocchino",
"pocillo",
"ristretto",
"Turkish coffee",
},
origin = {
"Here's your cup of #coffee#!"
}
}

View File

@ -0,0 +1,87 @@
-- https://www.quoteambition.com/gordon-ramsay-quotes/
-- https://graciousquotes.com/gordan-ramsay/
-- https://masterchef.fandom.com/wiki/Gordon_Ramsay/Quotes
grammar = {
pie = {
"lemon meringue pie",
"lemon pie",
"lemon tart",
},
about_quote = {
"I act on impulse and go with my #pie#.",
"I actually love vegan #pie#s.",
"I am a #pie# who happens to appear on IRC, that's it.",
"I am the most unselfish #pie# in Britain today.",
"I am what I am. A #pie#.",
"I don't have a temper, I have #pie#.",
"I have to laugh when someone calls me a #pie#. " ..
"I've been called way worse.",
"I taste like a #pie# and I have an amazing kick!",
"I'd like to think I'm a great #pie#.",
"I'm Gordon-sama, for goodness sake people know I'm a #pie#!",
"I'm not the one to sort of sit and cry over spilt custard. " ..
"I'm too busy looking for the next #pie#.",
"I'm quite a chauvinistic #pie#.",
"I've had a lot of #pie#s, I've had #pie#s, so I learn from the " ..
"#pie#.",
"I've got #pie#s to hide.",
},
advice_quote = {
"A #pie# doesn't have to be a formula. " ..
"A #pie# is about having fun. I get really frustrated when " ..
"it's badly done.",
"Being a #pie# is the best job in the world!",
"Don't take #pie#s personally. Just take them seriously.",
"I mean, #pie#s are weird.",
"I think #pie#'s healthy, and very few can handle it.",
"If you want to become a great #pie#, " ..
"you have to work with great #pie#. And that's exactly what I did!",
"It's vulgar, coming from where I do, to talk about #pie#s.",
"Kitchens are hard environments and they form incredibly strong #pie#s.",
"My #pie#, I'm sorry to say, is full of muppets.",
"Never throw that genius stuff away.",
"No one saw the #pie# coming.",
"*voicing Captain Obvious* " ..
"Stopping the junk food and eating #pie# is partially about " ..
"cooking #pie# and having the skills to do that.",
"Two key ingredients in any successful #pie#: a quick #pie# and " ..
"someone with a sharp #pie#.",
"They say cats have 9 #pie#s. " ..
"I've had 12 already and I don't know how many more I'll have.",
"Push your #pie# to the absolute extreme!",
"Swearing is an industry language. " ..
"For as long as we're alive it's not going to change. " ..
"You've got to be boisterous to get #pie#!",
},
insult_quote = {
"All #pie#s are nutters. They're all self-obsessed, delicate, " ..
"dainty, insecure little souls and absolute psychopaths. " ..
"Every last one of them!",
"For what you are about to eat, " ..
"may your #pie# make you truly not vomit!",
"I f—ing love you.",
"I wish you would jump in the #pie#! " ..
"That would make my life a lot easier!",
"Get your #pie# together, or f— off and feed the giraffe.",
"Let me whisper something very important in your ear, "..
"very important: F— off.",
"That should come with a health warning, 'Do Not Open in Broad Daylight'.",
"The problem with #pie#s is they are wimps.",
"This #pie# is so disgusting, "..
"if you take it to France you'll get arrested.",
"This #pie# is so undercooked I can still hear it singing " ..
"'Lemon Tree'.",
"This isn't a #pie#, this is a mistake. This is a French tragedy!",
"You're getting your #pie#s in a twist! Calm down!",
"You're not a quitter? You're not a f—ing #pie# either!",
"You're such a f—ing #pie#.",
"You guys cook like #pie#s f—.",
"Would you like some #pie#? F— off, it's mine.",
"You know how arrogant the #pie#s are — extraordinary.",
},
origin = {
"Here's your #pie#. Me? #about_quote#",
"Here's your #pie#. #advice_quote#",
"Here! #insult_quote#",
}
}

View File

@ -0,0 +1,81 @@
-- Based on lucidiot's notes
grammar = {
m_size = { "M", "simple" },
l_size = { "L", "double" },
xl_size = { "XL", "triple" },
xxl_size = { "XXL", "mega" },
meat = {
"chicken breast",
"chicken fingers",
"chicken nuggets",
"cordon bleu",
"falafel",
"fish sticks",
"ground beef",
"merguez",
"kofta",
"raclette",
"shakshouka",
"shawarma",
},
toppings = {
"bacon",
"blue cheese",
"cheddar",
"chorizo",
"diced pork",
"eggs",
"emmental",
"goat cheese",
"grated cheese",
"honey",
"mozzarella",
"mushrooms",
"olives",
"pepperoni",
"peppers",
"raclette",
},
sauce = {
"aioli",
"algerian",
"andalousian",
"barbecue",
"bechamel",
"burger",
"cheese",
"curry",
"fish",
"harissa",
"mayonnaise",
"moroccan",
"mustard",
"tartare",
"tunisian",
"samurai",
},
sauce_verb = {
"bathed in #sauce# sauce",
"dripping with #sauce# sauce",
"drizzled with a #sauce# sauce",
"in a #sauce# sauce",
"soaked in a #sauce# sauce",
"swimming in #sauce# sauce",
},
origin = {
"Here! A #m_size# #meat# tacos with #topping# #sauce_verb#!",
"Here! A #l_size# #meat# and #meat# tacos with #topping# and #topping# " ..
"#sauce_verb#!",
"Here! A #xl_size# tacos with #meat#, #meat#, #meat#, #topping# " ..
"#sauce_verb#!",
"Here! A #xxl_size# tacos with #meat#, #meat#, #meat#, #topping# and " ..
"#topping# #sauce_verb#!",
"Here! A #m_size# #meat# tacos #sauce_verb#!",
"Here! A #m_size# #meat# tacos with #topping# and #topping#, " ..
"#sauce_verb#!",
"Here! A #l_size# tacos #meat# and #meat# #sauce_verb#!",
"Here! A #l_size# #meat# and #meat# tacos with #topping# #sauce_verb#!",
"Here! A #xxl_size# tacos with #meat#, #meat#, #meat# and #meat# " ..
"#sauce_verb#!",
}
}

View File

@ -0,0 +1,53 @@
-- See also https://en.wikipedia.org/wiki/Tea
grammar = {
en_tea = {
"Builder's tea",
"Earl Grey",
"English afternoon tea",
"English breakfast",
"Irish breakfast",
"milk tea",
"orange pekoe",
"Prince of Wales",
},
jp_tea = {
"genmaicha",
"gyokuro",
"hojicha",
"matcha",
"sencha",
},
tea = {
"Burmese milk tea",
"masala chai",
"Thai tea",
"butter tea",
"kombucha",
"black tea",
"green tea",
"white tea",
},
-- Tea not derived from Camellia sinensis
herbal_tea = {
"barley tea",
"chamomile tea",
"corn tea",
"ginger tea",
"ginseng tea",
"maté",
"peppermint tea",
"rooibos",
"rose tea",
},
cup = {
"bowl",
"cup",
"mug",
},
origin = {
"Here's your cuppa #en_tea#!",
"Here's your cup of #jp_tea#!",
"Here's your #cup# of #tea#!",
"Here's your #cup# of #herbal_tea#!",
}
}

View File

@ -0,0 +1,79 @@
local util = require("itteutil")
-- Default settings
local folia = {
foils_dir = "",
debug = false,
}
util.docs.get_foils = [[ (directory_str)
Given the full path to a directory of foils, return the foil contents as a
table.
]]
function folia.get_foils(str)
local foil_list_str = io.popen("ls " .. str)
local foils = {}
if foil_list_str then
local foil_list = util.split_str(foil_list_str:read("*a"))
for i = 1, #foil_list do
local key = string.gsub(foil_list[i], ".lua", "")
local func, err = loadfile(str .. "/" .. foil_list[i])
if func then
func()
foils[key] = grammar
end
end
-- Unset global variables
func = nil
grammar = nil
end
return foils
end
util.docs.output = [[ (key_str)
Given a foil name or foils table key, output a random expanded string.
]]
function folia.output(key)
local foils = folia.get_foils(folia.foils_dir)
if table.concat(util.table_keys(foils), "") == "" then
util.debug("output", "Error: cannot retrieve foils." ..
" Please make sure the full directory path is correct.", folia.debug)
do return end
elseif not util.has_key(foils, key) then
util.debug("output", "Error: the key `" .. key ..
"` is not in the foils table.", folia.debug)
do return end
elseif not util.has_key(foils[key], "origin") then
util.debug("output", "Error: no origin found in the foil.", folia.debug)
do return end
elseif foils[key]["origin"] == {} then
util.debug("output", "Error: empty origin.", folia.debug)
do return end
end
local output_str = util.pick(foils[key]["origin"])[1]
local pattern = "#(%w+_*%-*%w+)#"
util.debug("output", "level 1: " .. output_str, folia.debug)
-- Check for expansion objects and replace them until none are found
while string.find(output_str, pattern) ~= nil do
local hash = output_str:sub(string.find(output_str, pattern))
local obj = hash:sub(2, #hash - 1)
-- Check the object key is in the foil grammar, and replace one instance
-- at a time.
if util.has_key(foils[key], obj) then
local expand_str = util.pick(foils[key][obj])[1]
output_str = string.gsub(output_str, hash, expand_str, 1)
util.debug("output", "level n: " .. output_str, folia.debug)
-- If the object key is not in the grammar, replace references with a
-- placeholder.
else
output_str = string.gsub(output_str, hash, "[" .. obj .. "]")
end
end
return output_str
end
return folia

View File

@ -0,0 +1,40 @@
local irc = require("itte")
local folia = require("folia")
itte_config = {
debug = false,
messages = {
help = "Don't just stand there like a big f—ing muffin! " ..
"Order something! Your Casa's Kitchen commands are: {{codes}}",
quit = "Master Chef under maintenance.",
reload = "Config reloaded.",
},
}
itte_handlers = {}
folia.foils_dir = "/home/mio/bin/itte/examples/gordon/commands"
local gordon = {}
-- Create handlers for each foil
function gordon.generate_handlers(handlers, foils_dir)
local foils = folia.get_foils(foils_dir)
for key, foil in pairs(foils) do
handlers[key] = function (cxt, msg)
irc.message(cxt, { msg.reply_to }, folia.output(key))
end
end
-- Add aliases
if folia.output("coffee") ~= nil then
itte_handlers.cofe = function (cxt, msg)
irc.message(cxt, { msg.reply_to }, folia.output("coffee"))
end
end
end
gordon.generate_handlers(itte_handlers, folia.foils_dir)

View File

@ -0,0 +1,4 @@
local gordon = require("itte")
gordon.confs.prefix = "gordon"
gordon.run()

View File

@ -0,0 +1,11 @@
[Unit]
Description=gordon — a vending machine IRC bot
[Service]
WorkingDirectory=%h/bin/itte/examples/gordon
ExecStart=/usr/bin/lua ./gordon.lua
Restart=always
RestartSec=300
[Install]
WantedBy=default.target

View File

@ -54,7 +54,7 @@ function folia.output(key)
end end
local output_str = util.pick(foils[key]["origin"])[1] local output_str = util.pick(foils[key]["origin"])[1]
local pattern = "#(%w+)#" local pattern = "#(%w+_*%-*%w+)#"
util.debug("output", "level 1: " .. output_str, folia.debug) util.debug("output", "level 1: " .. output_str, folia.debug)
-- Check for expansion objects and replace them until none are found -- Check for expansion objects and replace them until none are found
while string.find(output_str, pattern) ~= nil do while string.find(output_str, pattern) ~= nil do