aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Dockerfile4
-rw-r--r--Dockerfile_scratch_vendored14
-rw-r--r--go.mod6
-rw-r--r--go.sum43
-rw-r--r--main.go20
-rw-r--r--plugins.go64
-rw-r--r--plugins/hello.lua5
-rw-r--r--plugins/repology.lua33
-rw-r--r--rss.go2
-rw-r--r--types.go14
-rw-r--r--utils.go7
12 files changed, 183 insertions, 31 deletions
diff --git a/.gitignore b/.gitignore
index 3b735ec..fb5df45 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,5 @@
# Go workspace file
go.work
+
+,*
diff --git a/Dockerfile b/Dockerfile
index 0cd1f23..550fd41 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,7 +6,7 @@ COPY *.go /milla/
RUN go build
FROM alpine:3.21
-ENV HOME /home/user
+ENV HOME=/home/user
RUN set -eux; \
adduser -u 1001 -D -h "$HOME" user; \
mkdir "$HOME/.irssi"; \
@@ -14,4 +14,4 @@ RUN set -eux; \
COPY --from=builder /milla/milla "$HOME/milla"
RUN chown user:user "$HOME/milla"
USER user
-ENTRYPOINT ["home/user/milla"]
+ENTRYPOINT ["/home/user/milla"]
diff --git a/Dockerfile_scratch_vendored b/Dockerfile_scratch_vendored
new file mode 100644
index 0000000..34d6b07
--- /dev/null
+++ b/Dockerfile_scratch_vendored
@@ -0,0 +1,14 @@
+FROM golang:1.23-alpine3.21 AS builder
+WORKDIR /milla
+COPY go.sum go.mod /milla/
+COPY vendor /milla/vendor
+COPY *.go /milla/
+RUN CGO_ENABLED=0 go build
+
+FROM alpine:3.21 AS cert
+RUN apk add --no-cache ca-certificates
+
+FROM scratch
+COPY --from=cert /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
+COPY --from=builder /milla/milla "/milla"
+ENTRYPOINT ["/milla"]
diff --git a/go.mod b/go.mod
index a90ae32..ffb4127 100644
--- a/go.mod
+++ b/go.mod
@@ -16,7 +16,7 @@ require (
github.com/layeh/gopher-json v0.0.0-20201124131017-552bb3c4c3bf
github.com/lrstanley/girc v0.0.0-20240125042120-9add3166e52e
github.com/mmcdole/gofeed v1.3.0
- github.com/sashabaranov/go-openai v1.19.3
+ github.com/sashabaranov/go-openai v1.36.0
github.com/yuin/gluare v0.0.0-20170607022532-d7c94f1a80ed
github.com/yuin/gopher-lua v1.1.1
gitlab.com/megalithic-llc/gluasocket v0.3.1
@@ -31,8 +31,8 @@ require (
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
cloud.google.com/go/compute/metadata v0.3.0 // indirect
cloud.google.com/go/longrunning v0.5.7 // indirect
- github.com/PuerkitoBio/goquery v1.8.0 // indirect
- github.com/andybalholm/cascadia v1.3.1 // indirect
+ github.com/PuerkitoBio/goquery v1.9.2 // indirect
+ github.com/andybalholm/cascadia v1.3.2 // indirect
github.com/dlclark/regexp2 v1.10.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.4.1 // indirect
diff --git a/go.sum b/go.sum
index 3501135..c0cee7c 100644
--- a/go.sum
+++ b/go.sum
@@ -13,8 +13,8 @@ cloud.google.com/go/longrunning v0.5.7 h1:WLbHekDbjK1fVFD3ibpFFVoyizlLRl73I7YKuA
cloud.google.com/go/longrunning v0.5.7/go.mod h1:8GClkudohy1Fxm3owmBGid8W0pSgodEMwEAztp38Xng=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U=
-github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
+github.com/PuerkitoBio/goquery v1.9.2 h1:4/wZksC3KgkQw7SQgkKotmKljk0M6V8TUvA8Wb4yPeE=
+github.com/PuerkitoBio/goquery v1.9.2/go.mod h1:GHPCaP0ODyyxqcNoFGYlAprUFH81NuRPd0GX3Zu2Mvk=
github.com/ailncode/gluaxmlpath v0.0.0-20161126153117-6ce478ecb4a6 h1:FM0WudTZ+xeiXPJcs+X1Zg8JXe4vlb9P2GZYqCYjZkk=
github.com/ailncode/gluaxmlpath v0.0.0-20161126153117-6ce478ecb4a6/go.mod h1:Ti1AvV2KUYtHEBX7eYbdAGEfFyKz9+lHrJPcr79Vkng=
github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink=
@@ -23,8 +23,8 @@ github.com/alecthomas/chroma/v2 v2.12.0 h1:Wh8qLEgMMsN7mgyG8/qIpegky2Hvzr4By6gEF
github.com/alecthomas/chroma/v2 v2.12.0/go.mod h1:4TQu7gdfuPjSh76j78ietmqh9LiurGF0EpseFXdKMBw=
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/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
-github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
+github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
+github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
github.com/cenkalti/backoff/v5 v5.0.1 h1:kGZdCHH1+eW+Yd0wftimjMuhg9zidDvNF5aGdnkkb+U=
github.com/cenkalti/backoff/v5 v5.0.1/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
@@ -121,8 +121,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
-github.com/sashabaranov/go-openai v1.19.3 h1:xJvkU8Tye6MOKLaoqjh7qXYwKiEYGtlmp06cb8179yo=
-github.com/sashabaranov/go-openai v1.19.3/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
+github.com/sashabaranov/go-openai v1.36.0 h1:fcSrn8uGuorzPWCBp8L0aCR95Zjb/Dd+ZSML0YZy9EI=
+github.com/sashabaranov/go-openai v1.36.0/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -133,8 +133,11 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/vitoraguila/forza v0.0.0-20250308133152-28e9d4675774 h1:BCGeQcdyr+aqVU+mS2roqivUzv7d9wy9oeMze43SUe0=
+github.com/vitoraguila/forza v0.0.0-20250308133152-28e9d4675774/go.mod h1:h3MHloI9aeI+xO4S4tpQ+XEAJt370k/g7l6FZaj76Mc=
github.com/yuin/gluare v0.0.0-20170607022532-d7c94f1a80ed h1:I1vcLHWU9m30rA90rMrKPu0eD3NDA4FBlkB8WMaDyUw=
github.com/yuin/gluare v0.0.0-20170607022532-d7c94f1a80ed/go.mod h1:9w6KSdZh23UWqOywWsRLUcJUrUNjRh4Ql3z9uVgnSP4=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
gitlab.com/megalithic-llc/gluasocket v0.3.1 h1:CtsSTZa3G5WnMbhZ3TgvpLwpVlQv6KjO2mqxNOGrhY4=
@@ -153,19 +156,26 @@ go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2L
go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -174,6 +184,8 @@ golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbht
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -181,13 +193,22 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
@@ -197,6 +218,10 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.186.0 h1:n2OPp+PPXX0Axh4GuSsL5QL8xQCTb2oDwyzPnQvqUug=
google.golang.org/api v0.186.0/go.mod h1:hvRbBmgoje49RV3xqVXrmP6w93n6ehGgIVPYrGtBFFc=
diff --git a/main.go b/main.go
index e3b6ed0..db8acad 100644
--- a/main.go
+++ b/main.go
@@ -483,7 +483,7 @@ func runCommand(
appConfig.deleteLstate(args[1])
case "remind":
if len(args) < 2 { //nolint: mnd,gomnd
- client.Cmd.Reply(event, errNotEnoughArgs.Error())
+ client.Cmd.Message(event.Source.Name, errNotEnoughArgs.Error())
break
}
@@ -491,14 +491,15 @@ func runCommand(
seconds, err := strconv.Atoi(args[1])
if err != nil {
client.Cmd.Reply(event, errNotEnoughArgs.Error())
+ client.Cmd.Message(event.Source.Name, errNotEnoughArgs.Error())
break
}
- client.Cmd.Reply(event, "Ok, I'll remind you in "+args[1]+" seconds.")
+ client.Cmd.Message(event.Source.Name, "Ok, I'll remind you in "+args[1]+" seconds.")
time.Sleep(time.Duration(seconds) * time.Second)
- client.Cmd.ReplyTo(event, " Ping!")
+ client.Cmd.Message(event.Source.Name, "Ping!")
case "forget":
client.Cmd.Reply(event, "I no longer even know whether you're supposed to wear or drink a camel.'")
case "whois":
@@ -1380,6 +1381,8 @@ func runIRC(appConfig TomlConfig) {
go LoadAllPlugins(&appConfig, irc)
+ go LoadAllEventPlugins(&appConfig, irc)
+
if appConfig.DatabaseAddress != "" {
context, cancel := context.WithTimeout(context.Background(), time.Duration(appConfig.RequestTimeout)*time.Second)
defer cancel()
@@ -1474,6 +1477,7 @@ func main() {
signal.Notify(quitChannel, syscall.SIGINT, syscall.SIGTERM)
configPath := flag.String("config", "./config.toml", "path to the config file")
+ prof := flag.Bool("prof", false, "enable prof server")
flag.Parse()
@@ -1503,10 +1507,12 @@ func main() {
go runIRC(v)
}
- go func() {
- err := http.ListenAndServe(":6060", nil)
- log.Println(err)
- }()
+ if *prof {
+ go func() {
+ err := http.ListenAndServe(":6060", nil)
+ log.Println(err)
+ }()
+ }
<-quitChannel
}
diff --git a/plugins.go b/plugins.go
index 744ae94..f728e6a 100644
--- a/plugins.go
+++ b/plugins.go
@@ -7,6 +7,7 @@ import (
"net/url"
"os"
"reflect"
+ "strings"
"github.com/ailncode/gluaxmlpath"
"github.com/cjoudrey/gluahttp"
@@ -197,6 +198,17 @@ func sendMessageClosure(luaState *lua.LState, client *girc.Client) func(*lua.LSt
return 0
}
}
+
+func replyToMessageClosure(luaStete *lua.LState, client *girc.Client, event girc.Event) func(*lua.LState) int {
+ return func(luaState *lua.LState) int {
+ message := luaState.CheckString(1)
+
+ client.Cmd.Message(event.Source.Name, message)
+
+ return 0
+ }
+}
+
func registerLuaCommand(luaState *lua.LState, appConfig *TomlConfig) func(*lua.LState) int {
return func(luaState *lua.LState) int {
path := luaState.CheckString(1)
@@ -410,6 +422,37 @@ func millaModuleLoaderClosure(luaState *lua.LState, client *girc.Client, appConf
}
}
+func millaModuleLoaderEventClosure(luaState *lua.LState, client *girc.Client, appConfig *TomlConfig, event girc.Event) func(*lua.LState) int {
+ return func(luaState *lua.LState) int {
+ exports := map[string]lua.LGFunction{
+ "send_message": lua.LGFunction(sendMessageClosure(luaState, client)),
+ "reply_to": lua.LGFunction(replyToMessageClosure(luaState, client, event)),
+ "join_channel": lua.LGFunction(ircJoinChannelClosure(luaState, client)),
+ "part_channel": lua.LGFunction(ircPartChannelClosure(luaState, client)),
+ "send_ollama_request": lua.LGFunction(ollamaRequestClosure(luaState, appConfig)),
+ "send_gemini_request": lua.LGFunction(geminiRequestClosure(luaState, appConfig)),
+ "send_chatgpt_request": lua.LGFunction(chatGPTRequestClosure(luaState, appConfig)),
+ "send_or_request": lua.LGFunction(orRequestClosure(luaState, appConfig)),
+ "query_db": lua.LGFunction(dbQueryClosure(luaState, appConfig)),
+ "register_cmd": lua.LGFunction(registerLuaCommand(luaState, appConfig)),
+ "url_encode": lua.LGFunction(urlEncode(luaState)),
+ }
+ millaModule := luaState.SetFuncs(luaState.NewTable(), exports)
+
+ registerStructAsLuaMetaTable[TomlConfig](luaState, millaModule, checkStruct, TomlConfig{}, "toml_config")
+ registerStructAsLuaMetaTable[CustomCommand](luaState, millaModule, checkStruct, CustomCommand{}, "custom_command")
+ registerStructAsLuaMetaTable[LogModel](luaState, millaModule, checkStruct, LogModel{}, "log_model")
+ registerStructAsLuaMetaTable[girc.Source](luaState, millaModule, checkStruct, girc.Source{}, "girc_source")
+ registerStructAsLuaMetaTable[girc.Event](luaState, millaModule, checkStruct, girc.Event{}, "girc_event")
+
+ luaState.SetGlobal("milla", millaModule)
+
+ luaState.Push(millaModule)
+
+ return 1
+ }
+}
+
func RunScript(scriptPath string, client *girc.Client, appConfig *TomlConfig) {
luaState := lua.NewState()
defer luaState.Close()
@@ -469,6 +512,15 @@ func LoadAllPlugins(appConfig *TomlConfig, client *girc.Client) {
}
}
+func LoadAllEventPlugins(appConfig *TomlConfig, client *girc.Client) {
+ for _, triggeredScript := range appConfig.TriggeredScripts {
+ log.Print("Loading event plugin: ", triggeredScript.Path)
+
+ go RunScript(triggeredScript.Path, client, appConfig)
+ registerTriggeredScripts(client, *appConfig)
+ }
+}
+
func RunLuaFunc(
cmd, args string,
client *girc.Client,
@@ -565,7 +617,7 @@ func RunTriggeredLuaFunc(
appConfig.insertLState(scriptPath, luaState, cancel)
- luaState.PreloadModule("milla", millaModuleLoaderClosure(luaState, client, appConfig))
+ luaState.PreloadModule("milla", millaModuleLoaderEventClosure(luaState, client, appConfig, event))
gluasocket.Preload(luaState)
gluaxmlpath.Preload(luaState)
luaState.PreloadModule("yaml", gluayaml.Loader)
@@ -629,10 +681,18 @@ func RunTriggeredLuaFunc(
func registerTriggeredScripts(irc *girc.Client, appConfig TomlConfig) {
for _, triggeredScript := range appConfig.TriggeredScripts {
- for _, triggerType := range triggeredScript.TriggerType {
+ for _, triggerType := range triggeredScript.TriggerTypes {
switch triggerType {
case girc.PRIVMSG:
irc.Handlers.AddBg(girc.PRIVMSG, func(_ *girc.Client, event girc.Event) {
+ if !strings.HasPrefix(event.Last(), appConfig.IrcNick+": ") {
+ return
+ }
+
+ if appConfig.AdminOnly && !isFromAdmin(appConfig.Admins, event) {
+ return
+ }
+
RunTriggeredLuaFunc(triggeredScript.FuncName, triggeredScript.Path, irc, event, &appConfig)
})
default:
diff --git a/plugins/hello.lua b/plugins/hello.lua
new file mode 100644
index 0000000..b9c5bc2
--- /dev/null
+++ b/plugins/hello.lua
@@ -0,0 +1,5 @@
+local milla = require("milla")
+
+function hello() milla.reply_to("hello") end
+
+milla.register_cmd("/plugins/hello.lua", "hello", "hello")
diff --git a/plugins/repology.lua b/plugins/repology.lua
new file mode 100644
index 0000000..f3de647
--- /dev/null
+++ b/plugins/repology.lua
@@ -0,0 +1,33 @@
+local milla = require("milla")
+local os = require("os")
+local json = require("json")
+
+-- /repology void_x86_64
+function repology(arg)
+ os.setenv("http_proxy", "http://172.17.0.1:8120")
+
+ local http = require("http")
+
+ local url = "https://repology.org/api/v1/repository/" .. arg .. "/problems"
+
+ local response = http.request("GET", url)
+
+ io.write(response.body)
+
+ local json_response, err = json.decode(response.body)
+ io.write(json_response)
+ if err ~= nil then print(err) end
+
+ for _, item in pairs(json_response) do
+ for k, v in ipairs(item) do print(k, v) end
+ end
+
+ local result = ""
+ for key, value in pairs(json_response) do
+ result = result .. key .. ": " .. value .. " -- "
+ end
+
+ return result
+end
+
+milla.register_cmd("/plugins/repology.lua", "repology", "repology")
diff --git a/rss.go b/rss.go
index 8ac96cc..a8c864d 100644
--- a/rss.go
+++ b/rss.go
@@ -65,7 +65,7 @@ func GetFeed(feed FeedConfig,
for _, item := range parsedFeed.Items {
if item.PublishedParsed.Unix() > newestFromDB {
- client.Cmd.Message(channel[0], parsedFeed.Title+": "+item.Title+" >>> "+item.Link)
+ client.Cmd.Message(channel[0], feed.Name[0:Min(20, len(feed.Name))]+": "+parsedFeed.Title+": "+item.Title+" >>> "+item.Link)
}
}
diff --git a/types.go b/types.go
index be8b064..fd37291 100644
--- a/types.go
+++ b/types.go
@@ -54,10 +54,10 @@ type LuaCommand struct {
}
type TriggeredScripts struct {
- Path string
- FuncName string
- Channels [][]string
- TriggerType []string
+ Path string
+ FuncName string
+ Channels [][]string
+ TriggerTypes []string
}
type RssFile struct {
@@ -190,9 +190,9 @@ func (config *TomlConfig) insertTriggeredScript(path, cmd string, triggerType []
config.TriggeredScripts = make(map[string]TriggeredScripts)
}
config.TriggeredScripts[path] = TriggeredScripts{
- Path: path,
- FuncName: cmd,
- TriggerType: triggerType,
+ Path: path,
+ FuncName: cmd,
+ TriggerTypes: triggerType,
}
}
diff --git a/utils.go b/utils.go
index 6bf0015..d990504 100644
--- a/utils.go
+++ b/utils.go
@@ -7,6 +7,13 @@ import (
"github.com/lrstanley/girc"
)
+func Min(x, y int) int {
+ if x < y {
+ return x
+ }
+ return y
+}
+
func IrcJoin(irc *girc.Client, channel []string) {
if len(channel) > 1 && channel[1] != "" {
irc.Cmd.JoinKey(channel[0], channel[1])