aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorterminaldweller <devi@terminaldweller.com>2024-06-03 23:55:52 +0000
committerterminaldweller <devi@terminaldweller.com>2024-06-03 23:55:52 +0000
commit54510fb0c2b70aa3f4ebd00b91f25fef874f293c (patch)
tree8b8f25be96ec36744ec99eea97fea51aa8cf0d7e
parentinitial lua script support, fixes #27, fixes #34 (diff)
downloadmilla-54510fb0c2b70aa3f4ebd00b91f25fef874f293c.tar.gz
milla-54510fb0c2b70aa3f4ebd00b91f25fef874f293c.zip
updated the readme and added example for lua scripting
-rw-r--r--README.md87
-rw-r--r--go.mod3
-rw-r--r--go.sum6
-rw-r--r--plugins.go5
-rw-r--r--plugins/rss.lua57
-rw-r--r--plugins/rss.yaml7
6 files changed, 165 insertions, 0 deletions
diff --git a/README.md b/README.md
index 8573246..d74d7a0 100644
--- a/README.md
+++ b/README.md
@@ -236,6 +236,10 @@ webirc password to use.
webirc address to use.
+### plugins
+
+A list of plugins to load:`plugins = ["./plugins/rss.lua", "./plugins/test.lua"]`
+
## Custom Commands
Custom commands let you define a command that does a SQL query to the database and performs the given task. Here's an example:
@@ -525,6 +529,89 @@ go mod vendor
go build
```
+### Plugins and Scripting
+
+milla can be extended with plugins. The plugins are written in lua and are loaded at runtime. The plugins are loaded after an IRC connection has been made.<br/>
+
+An example plugin is provided under `plugins/rss.lua`.<br/>
+
+```yaml
+rssfeeds:
+ - name: "one"
+ url: "https://www.youtube.com/feeds/videos.xml?channel_id=UCaiL2GDNpLYH6Wokkk1VNcg"
+ - name: "two"
+ url: "https://www.youtube.com/feeds/videos.xml?channel_id=UCd26IHBHcbtxD7pUdnIgiCw"
+ - name: "three"
+ url: "https://www.youtube.com/feeds/videos.xml?channel_id=UCS4FAVeYW_IaZqAbqhlvxlA"
+```
+
+```lua
+local milla = require("milla")
+local yaml = require("yaml")
+local http = require("http")
+local xmlpath = require("xmlpath")
+
+local function read_file(file)
+ local f = assert(io.open(file, "rb"))
+ local content = f:read("*all")
+ f:close()
+ return content
+end
+
+local function get_rss_feed()
+ local yaml_config = read_file("./plugins/rss.yaml")
+ local config = yaml.parse(yaml_config)
+ local titles = {}
+ local author_names = {}
+ local uris = {}
+ local rss_feed_list = {}
+
+ for _, v in pairs(config.rssfeeds) do
+ local response, err = http.request("GET", v.url)
+ local node, err = xmlpath.loadxml(response.body)
+
+ local path, err = xmlpath.compile("//entry/title")
+ local iterator = path:iter(node)
+ for _, match in ipairs(iterator) do
+ table.insert(titles, match:string())
+ end
+
+ path, err = xmlpath.compile("//entry/author/name")
+ iterator = path:iter(node)
+ for _, match in ipairs(iterator) do
+ table.insert(author_names, match:string())
+ end
+
+ path, err = xmlpath.compile("//entry/author/uri")
+ iterator = path:iter(node)
+ for _, match in ipairs(iterator) do
+ table.insert(uris, match:string())
+ end
+ end
+
+ for i = 1, #titles do
+ table.insert(rss_feed_list,
+ author_names[i] .. ": " .. titles[i] .. " -- " .. uris[i])
+ end
+
+ return rss_feed_list
+end
+
+local function rss_feed()
+ local rss_feeds = get_rss_feed()
+ for _, v in pairs(rss_feeds) do milla.send_message(v, "#rssfeed") end
+end
+
+rss_feed()
+```
+More of milla's functionality will be available over time.<br/>'
+
+The following libraries are loaded by milla by default:
+* [gluaxmlpath](https://github.com/ailncode/gluaxmlpath)
+* [gluahttp](https://github.com/cjoudrey/gluahttp)
+* [gluayaml](https://github.com/kohkimakimoto/gluayaml)
+* [gluasocket](https://gitlab.com/megalithic-llc/gluasocket)
+
## FAQ
- I end up with color escape sequences getting printed at the end of a line/begging of the next line. What gives?
diff --git a/go.mod b/go.mod
index e37a96f..f9076b8 100644
--- a/go.mod
+++ b/go.mod
@@ -6,8 +6,10 @@ require (
github.com/BurntSushi/toml v0.3.1
github.com/ailncode/gluaxmlpath v0.0.0-20161126153117-6ce478ecb4a6
github.com/alecthomas/chroma/v2 v2.12.0
+ github.com/cjoudrey/gluahttp v0.0.0-20201111170219-25003d9adfa9
github.com/google/generative-ai-go v0.11.2
github.com/jackc/pgx/v5 v5.5.5
+ github.com/kohkimakimoto/gluayaml v0.0.0-20160815032708-6fe413d49d73
github.com/lrstanley/girc v0.0.0-20240125042120-9add3166e52e
github.com/sashabaranov/go-openai v1.19.3
github.com/yuin/gopher-lua v1.1.1
@@ -55,4 +57,5 @@ require (
google.golang.org/grpc v1.63.2 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/xmlpath.v2 v2.0.0-20150820204837-860cbeca3ebc // indirect
+ gopkg.in/yaml.v2 v2.4.0 // indirect
)
diff --git a/go.sum b/go.sum
index 5b9fb59..7fea354 100644
--- a/go.sum
+++ b/go.sum
@@ -22,6 +22,8 @@ github.com/alecthomas/chroma/v2 v2.12.0/go.mod h1:4TQu7gdfuPjSh76j78ietmqh9LiurG
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cjoudrey/gluahttp v0.0.0-20201111170219-25003d9adfa9 h1:rdWOzitWlNYeUsXmz+IQfa9NkGEq3gA/qQ3mOEqBU6o=
+github.com/cjoudrey/gluahttp v0.0.0-20201111170219-25003d9adfa9/go.mod h1:X97UjDTXp+7bayQSFZk2hPvCTmTZIicUjZQRtkwgAKY=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
@@ -86,6 +88,8 @@ github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
+github.com/kohkimakimoto/gluayaml v0.0.0-20160815032708-6fe413d49d73 h1:e2UU76WBjv6W0QUuPHe2QfSAXLR1kouek1fcSUtnSrk=
+github.com/kohkimakimoto/gluayaml v0.0.0-20160815032708-6fe413d49d73/go.mod h1:I+YgUp/uc0hF+H4RuQjR+uzDJNjUz7Sm21e63UCLWWQ=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -201,6 +205,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/xmlpath.v2 v2.0.0-20150820204837-860cbeca3ebc h1:LMEBgNcZUqXaP7evD1PZcL6EcDVa2QOFuI+cqM3+AJM=
gopkg.in/xmlpath.v2 v2.0.0-20150820204837-860cbeca3ebc/go.mod h1:N8UOSI6/c2yOpa/XDz3KVUiegocTziPiqNkeNTMiG1k=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/plugins.go b/plugins.go
index 69b3622..45c2847 100644
--- a/plugins.go
+++ b/plugins.go
@@ -2,9 +2,12 @@ package main
import (
"log"
+ "net/http"
"reflect"
"github.com/ailncode/gluaxmlpath"
+ "github.com/cjoudrey/gluahttp"
+ "github.com/kohkimakimoto/gluayaml"
"github.com/lrstanley/girc"
lua "github.com/yuin/gopher-lua"
"gitlab.com/megalithic-llc/gluasocket"
@@ -235,6 +238,8 @@ func RunScript(scriptPath string, client *girc.Client) {
luaState.PreloadModule("milla", millaModuleLoaderClosure(luaState, client))
gluasocket.Preload(luaState)
gluaxmlpath.Preload(luaState)
+ luaState.PreloadModule("http", gluahttp.NewHttpModule(&http.Client{}).Loader)
+ luaState.PreloadModule("yaml", gluayaml.Loader)
log.Print("Running script: ", scriptPath)
diff --git a/plugins/rss.lua b/plugins/rss.lua
new file mode 100644
index 0000000..b78329f
--- /dev/null
+++ b/plugins/rss.lua
@@ -0,0 +1,57 @@
+local milla = require("milla")
+local yaml = require("yaml")
+local http = require("http")
+local xmlpath = require("xmlpath")
+
+local function read_file(file)
+ local f = assert(io.open(file, "rb"))
+ local content = f:read("*all")
+ f:close()
+ return content
+end
+
+local function get_rss_feed()
+ local yaml_config = read_file("./plugins/rss.yaml")
+ local config = yaml.parse(yaml_config)
+ local titles = {}
+ local author_names = {}
+ local uris = {}
+ local rss_feed_list = {}
+
+ for _, v in pairs(config.rssfeeds) do
+ local response, err = http.request("GET", v.url)
+ local node, err = xmlpath.loadxml(response.body)
+
+ local path, err = xmlpath.compile("//entry/title")
+ local iterator = path:iter(node)
+ for _, match in ipairs(iterator) do
+ table.insert(titles, match:string())
+ end
+
+ path, err = xmlpath.compile("//entry/author/name")
+ iterator = path:iter(node)
+ for _, match in ipairs(iterator) do
+ table.insert(author_names, match:string())
+ end
+
+ path, err = xmlpath.compile("//entry/author/uri")
+ iterator = path:iter(node)
+ for _, match in ipairs(iterator) do
+ table.insert(uris, match:string())
+ end
+ end
+
+ for i = 1, #titles do
+ table.insert(rss_feed_list,
+ author_names[i] .. ": " .. titles[i] .. " -- " .. uris[i])
+ end
+
+ return rss_feed_list
+end
+
+local function rss_feed()
+ local rss_feeds = get_rss_feed()
+ for _, v in pairs(rss_feeds) do milla.send_message(v, "#rssfeed") end
+end
+
+rss_feed()
diff --git a/plugins/rss.yaml b/plugins/rss.yaml
new file mode 100644
index 0000000..aee5bcf
--- /dev/null
+++ b/plugins/rss.yaml
@@ -0,0 +1,7 @@
+rssfeeds:
+ - name: "one"
+ url: "https://www.youtube.com/feeds/videos.xml?channel_id=UCaiL2GDNpLYH6Wokkk1VNcg"
+ - name: "two"
+ url: "https://www.youtube.com/feeds/videos.xml?channel_id=UCd26IHBHcbtxD7pUdnIgiCw"
+ - name: "three"
+ url: "https://www.youtube.com/feeds/videos.xml?channel_id=UCS4FAVeYW_IaZqAbqhlvxlA"