Add example bot gordon

mio 2022-08-29 23:13:52 +00:00
parent edae077b1d
commit b9778b2e3c
9 changed files with 235 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
scheduled tasks.
- *hachi*: a bot inspired by tracery text expansion. Loads files ("foils")
containing selection tables and creates handlers to return responses, one
service code per foil.
- *hachi* and *gordon*: bots inspired by tracery text expansion. Loads files
("foils") containing selection tables and creates handlers to return
responses, one service code per foil.
## Running a bot as a background process

View File

@ -0,0 +1,50 @@
grammar = {
meat_set = {
"360 Burger with a large patty, tomatos, cheddar and onions in a Dijon mustard sauce",
"Bada Boom cheeseburger with a juicy steak, cheddar, onions and tomatos",
"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, tomatos 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 tomatos, 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",
"house fries with a mayonnaise dip",
},
veggie_side = {
"chips deluged with potato sauce",
"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,37 @@
-- 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",
"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,5 @@
grammar = {
origin = {
"Here's your lemon pie!"
}
}

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,45 @@
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("burger") ~= nil then
itte_handlers.borgar = function (cxt, msg)
irc.message(cxt, { msg.reply_to }, folia.output("burger"))
end
end
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
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)
-- Check for expansion objects and replace them until none are found
while string.find(output_str, pattern) ~= nil do