aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md8
-rw-r--r--main.go24
-rw-r--r--plugins.go7
-rw-r--r--plugins/rss.lua42
-rw-r--r--plugins/rss.yaml2
-rw-r--r--types.go66
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"`
}