diff --git a/docs/README.md b/docs/README.md index b68d0f3..7a0b9aa 100644 --- a/docs/README.md +++ b/docs/README.md @@ -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 diff --git a/examples/gordon/commands/borgar.lua b/examples/gordon/commands/borgar.lua new file mode 100644 index 0000000..36a1ddc --- /dev/null +++ b/examples/gordon/commands/borgar.lua @@ -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#!", + } +} diff --git a/examples/gordon/commands/cofe.lua b/examples/gordon/commands/cofe.lua new file mode 100644 index 0000000..e23d7aa --- /dev/null +++ b/examples/gordon/commands/cofe.lua @@ -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#!" + } +} diff --git a/examples/gordon/commands/pie.lua b/examples/gordon/commands/pie.lua new file mode 100644 index 0000000..f2ba3df --- /dev/null +++ b/examples/gordon/commands/pie.lua @@ -0,0 +1,5 @@ +grammar = { + origin = { + "Here's your lemon pie!" + } +} diff --git a/examples/gordon/folia.lua b/examples/gordon/folia.lua new file mode 100644 index 0000000..d99af35 --- /dev/null +++ b/examples/gordon/folia.lua @@ -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+)#" + 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 diff --git a/examples/gordon/gordon.config.lua b/examples/gordon/gordon.config.lua new file mode 100644 index 0000000..014f4e3 --- /dev/null +++ b/examples/gordon/gordon.config.lua @@ -0,0 +1,38 @@ +local irc = require("itte") +local folia = require("folia") + +itte_config = { + debug = false, + messages = { + help = "Casa's Kitchen commands: {{codes}}", + quit = "Machef under maintenance.", + reload = "Config reloaded.", + }, +} + +itte_handlers = {} + +folia.foils_dir = arg[0] .. "/commands" + + +local gordon = {} + + +-- Show help message +function itte_handlers.botland(cxt, msg) + irc._h.help(cxt, msg) +end + + +-- 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 +end + + +gordon.generate_handlers(itte_handlers, folia.foils_dir) diff --git a/examples/gordon/gordon.lua b/examples/gordon/gordon.lua new file mode 100644 index 0000000..3d5784e --- /dev/null +++ b/examples/gordon/gordon.lua @@ -0,0 +1,4 @@ +local gordon = require("itte") +gordon.confs.prefix = "gordon" + +gordon.run() diff --git a/examples/gordon/gordon.service b/examples/gordon/gordon.service new file mode 100644 index 0000000..5a3e69d --- /dev/null +++ b/examples/gordon/gordon.service @@ -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