From 309de82960b717f61dd90b908c2c28955955f504 Mon Sep 17 00:00:00 2001 From: terminaldweller Date: Sun, 9 Jun 2024 10:38:00 -0400 Subject: added a load and unload command for plugins --- README.md | 8 +++++++ main.go | 24 +++++++++++++++++++++ plugins.go | 7 ++++++ plugins/rss.lua | 42 +++++++++++++++++++++++++++++++++--- plugins/rss.yaml | 2 ++ types.go | 66 ++++++++++++++++++++++++++++++++++++++++---------------- 6 files changed, 128 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index ecb4a7c..646bb02 100644 --- a/README.md +++ b/README.md @@ -362,6 +362,14 @@ Joins a channel: `/join #channel` Leaves a channel: `/leave #channel` +#### load + +Load a plugin: `/load /plugins/rss.lua` + +#### unload + +Unload a plugin: `/unload /plugins/rss.lua` + ## Deploy ### Docker diff --git a/main.go b/main.go index 2911ed7..b7f47e3 100644 --- a/main.go +++ b/main.go @@ -474,6 +474,30 @@ func runCommand( } handleCustomCommand(args, client, event, appConfig) + case "load": + if !isFromAdmin(appConfig.Admins, event) { + break + } + + if len(args) < 2 { //nolint: mnd,gomnd + client.Cmd.Reply(event, errNotEnoughArgs.Error()) + + break + } + + RunScript(args[1], client, appConfig) + case "unload": + if !isFromAdmin(appConfig.Admins, event) { + break + } + + if len(args) < 2 { //nolint: mnd,gomnd + client.Cmd.Reply(event, errNotEnoughArgs.Error()) + + break + } + + appConfig.deleteLstate(args[1]) default: client.Cmd.Reply(event, errUnknCmd.Error()) } diff --git a/plugins.go b/plugins.go index 75273a6..cd99081 100644 --- a/plugins.go +++ b/plugins.go @@ -1,6 +1,7 @@ package main import ( + "context" "log" "net/http" "reflect" @@ -285,6 +286,12 @@ func RunScript(scriptPath string, client *girc.Client, appConfig *TomlConfig) { luaState := lua.NewState() defer luaState.Close() + ctx, cancel := context.WithCancel(context.Background()) + + luaState.SetContext(ctx) + + appConfig.insertLState(scriptPath, luaState, cancel) + luaState.PreloadModule("milla", millaModuleLoaderClosure(luaState, client, appConfig)) gluasocket.Preload(luaState) gluaxmlpath.Preload(luaState) diff --git a/plugins/rss.lua b/plugins/rss.lua index b78329f..aa9c757 100644 --- a/plugins/rss.lua +++ b/plugins/rss.lua @@ -1,3 +1,5 @@ +#!/usr/bin/env lua5.1 + local milla = require("milla") local yaml = require("yaml") local http = require("http") @@ -10,9 +12,15 @@ local function read_file(file) return content end -local function get_rss_feed() +local function sleep(n) os.execute("sleep " .. tonumber(n)) end + +local function get_config() local yaml_config = read_file("./plugins/rss.yaml") local config = yaml.parse(yaml_config) + return config +end + +local function get_rss_feed(config) local titles = {} local author_names = {} local uris = {} @@ -20,25 +28,48 @@ local function get_rss_feed() for _, v in pairs(config.rssfeeds) do local response, err = http.request("GET", v.url) + if err ~= nil then + milla.send_message(err, "") + goto continue + end local node, err = xmlpath.loadxml(response.body) + if err ~= nil then + milla.send_message(err, "") + goto continue + end local path, err = xmlpath.compile("//entry/title") + if err ~= nil then + milla.send_message(err, "") + goto continue + end local iterator = path:iter(node) for _, match in ipairs(iterator) do table.insert(titles, match:string()) end path, err = xmlpath.compile("//entry/author/name") + -- local path, err = xmlpath.compile("//entry/title") + if err ~= nil then + milla.send_message(err, "") + goto continue + end iterator = path:iter(node) for _, match in ipairs(iterator) do table.insert(author_names, match:string()) end path, err = xmlpath.compile("//entry/author/uri") + -- local path, err = xmlpath.compile("//entry/title") + if err ~= nil then + milla.send_message(err, "") + goto continue + end iterator = path:iter(node) for _, match in ipairs(iterator) do table.insert(uris, match:string()) end + ::continue:: end for i = 1, #titles do @@ -50,8 +81,13 @@ local function get_rss_feed() end local function rss_feed() - local rss_feeds = get_rss_feed() - for _, v in pairs(rss_feeds) do milla.send_message(v, "#rssfeed") end + local config = get_config() + while true do + for _, v in pairs(get_rss_feed(config)) do + milla.send_message(v, config.channel) + sleep(config.period) + end + end end rss_feed() diff --git a/plugins/rss.yaml b/plugins/rss.yaml index aee5bcf..ade31d9 100644 --- a/plugins/rss.yaml +++ b/plugins/rss.yaml @@ -1,3 +1,5 @@ +period: 3600 +channel: "#rssfeed" rssfeeds: - name: "one" url: "https://www.youtube.com/feeds/videos.xml?channel_id=UCaiL2GDNpLYH6Wokkk1VNcg" diff --git a/types.go b/types.go index ded95ec..3b7f3ff 100644 --- a/types.go +++ b/types.go @@ -1,9 +1,11 @@ package main import ( + "context" "time" "github.com/jackc/pgx/v5/pgxpool" + lua "github.com/yuin/gopher-lua" ) type LogModel struct { @@ -20,6 +22,11 @@ type CustomCommand struct { Prompt string `toml:"prompt"` } +type LuaLstates struct { + LuaState *lua.LState + Cancel context.CancelFunc +} + type TomlConfig struct { IrcServer string `toml:"ircServer"` IrcNick string `toml:"ircNick"` @@ -49,30 +56,53 @@ type TomlConfig struct { WebIRCAddress string `toml:"webIRCAddress"` Plugins []string `toml:"plugins"` CustomCommands map[string]CustomCommand `toml:"customCommands"` - Temp float64 `toml:"temp"` - RequestTimeout int `toml:"requestTimeout"` - MillaReconnectDelay int `toml:"millaReconnectDelay"` - IrcPort int `toml:"ircPort"` - KeepAlive int `toml:"keepAlive"` - MemoryLimit int `toml:"memoryLimit"` - PingDelay int `toml:"pingDelay"` - PingTimeout int `toml:"pingTimeout"` - TopP float32 `toml:"topP"` - TopK int32 `toml:"topK"` - EnableSasl bool `toml:"enableSasl"` - SkipTLSVerify bool `toml:"skipTLSVerify"` - UseTLS bool `toml:"useTLS"` - DisableSTSFallback bool `toml:"disableSTSFallback"` - AllowFlood bool `toml:"allowFlood"` - Debug bool `toml:"debug"` - Out bool `toml:"out"` - AdminOnly bool `toml:"adminOnly"` + LuaStates map[string]LuaLstates + Temp float64 `toml:"temp"` + RequestTimeout int `toml:"requestTimeout"` + MillaReconnectDelay int `toml:"millaReconnectDelay"` + IrcPort int `toml:"ircPort"` + KeepAlive int `toml:"keepAlive"` + MemoryLimit int `toml:"memoryLimit"` + PingDelay int `toml:"pingDelay"` + PingTimeout int `toml:"pingTimeout"` + TopP float32 `toml:"topP"` + TopK int32 `toml:"topK"` + EnableSasl bool `toml:"enableSasl"` + SkipTLSVerify bool `toml:"skipTLSVerify"` + UseTLS bool `toml:"useTLS"` + DisableSTSFallback bool `toml:"disableSTSFallback"` + AllowFlood bool `toml:"allowFlood"` + Debug bool `toml:"debug"` + Out bool `toml:"out"` + AdminOnly bool `toml:"adminOnly"` pool *pgxpool.Pool Admins []string `toml:"admins"` IrcChannels []string `toml:"ircChannels"` ScrapeChannels []string `toml:"scrapeChannels"` } +func (config *TomlConfig) insertLState( + name string, + luaState *lua.LState, + cancel context.CancelFunc, +) { + if config.LuaStates == nil { + config.LuaStates = make(map[string]LuaLstates) + } + config.LuaStates[name] = LuaLstates{ + LuaState: luaState, + Cancel: cancel, + } +} + +func (config *TomlConfig) deleteLstate(name string) { + if config.LuaStates == nil { + return + } + config.LuaStates[name].Cancel() + delete(config.LuaStates, name) +} + type AppConfig struct { Ircd map[string]TomlConfig `toml:"ircd"` } -- cgit v1.2.3