initial commit
This commit is contained in:
parent
b9656c91bb
commit
d928a681f9
1
.gitignore
vendored
1
.gitignore
vendored
@ -21,3 +21,4 @@
|
|||||||
# Go workspace file
|
# Go workspace file
|
||||||
go.work
|
go.work
|
||||||
|
|
||||||
|
config.ini
|
||||||
|
114
chatbot/chatbot.go
Normal file
114
chatbot/chatbot.go
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
package chatbot
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/xmppo/go-xmpp"
|
||||||
|
"gopkg.in/ini.v1"
|
||||||
|
|
||||||
|
"gitea.dmz.rs/bauljamic123arlijam/neko-u-krovu-bot/ping"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NekoUKrovuBot struct {
|
||||||
|
cl *xmpp.Client
|
||||||
|
host string
|
||||||
|
user string
|
||||||
|
mcuJid string
|
||||||
|
nick string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNekoUKrovuBot() (*NekoUKrovuBot, error) {
|
||||||
|
cfg, err := ini.Load("config.ini")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to load INI file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
host := cfg.Section("credentials").Key("HOST").String()
|
||||||
|
user := cfg.Section("credentials").Key("JID").String()
|
||||||
|
passwd := cfg.Section("credentials").Key("PASSWORD").String()
|
||||||
|
mcuJid := cfg.Section("credentials").Key("ROOM").String()
|
||||||
|
nick := cfg.Section("credentials").Key("NICK").String()
|
||||||
|
|
||||||
|
cl, err := xmpp.NewClientNoTLS(host, user, passwd, false)
|
||||||
|
if err != nil {
|
||||||
|
return &NekoUKrovuBot{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err := cl.JoinMUCNoHistory(mcuJid, nick)
|
||||||
|
if err != nil {
|
||||||
|
return &NekoUKrovuBot{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = n
|
||||||
|
|
||||||
|
return &NekoUKrovuBot{cl: cl,
|
||||||
|
host: host,
|
||||||
|
user: user,
|
||||||
|
mcuJid: mcuJid,
|
||||||
|
nick: nick}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nkbot *NekoUKrovuBot) Listen() {
|
||||||
|
for {
|
||||||
|
msg, err := nkbot.cl.Recv()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch m := msg.(type) {
|
||||||
|
case xmpp.Chat:
|
||||||
|
nkbot.handleChat(&m)
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nkbot *NekoUKrovuBot) handleChat(ch *xmpp.Chat) {
|
||||||
|
src := ch.Remote
|
||||||
|
txt := ch.Text
|
||||||
|
|
||||||
|
if src == "sdsads" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if nkbot.checkForJelNekoUKrovu(txt) {
|
||||||
|
n := ping.Run()
|
||||||
|
nkbot.answer(fmt.Sprintf("%v uredjaja povezano", n))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nkbot *NekoUKrovuBot) checkForJelNekoUKrovu(txt string) bool {
|
||||||
|
normalizedText := strings.ToLower(txt)
|
||||||
|
|
||||||
|
pattern := `(?i)^(?:\S+\s+){2,}\b(jel|el|ima li|ima|neko|koga|nekoga|je l)?\s*(neko|koga|nekoga)?\s*(u)?\s*(krovu|krov|vkro)\b`
|
||||||
|
matched, err := regexp.MatchString(pattern, normalizedText)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error compiling regex:", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return matched
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nkbot *NekoUKrovuBot) answer(ans string) {
|
||||||
|
chat := xmpp.Chat{
|
||||||
|
Remote: "chatbottest@conference.dmz.rs",
|
||||||
|
Type: "groupchat",
|
||||||
|
Text: ans,
|
||||||
|
Stamp: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err := nkbot.cl.Send(chat)
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = n
|
||||||
|
}
|
96
chatbot/chatbot_test.go
Normal file
96
chatbot/chatbot_test.go
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
package chatbot
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNekoUKrovuBot_checkForJelNekoUKrovu(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
txt string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "matches 'jel neko u krovu'",
|
||||||
|
args: args{
|
||||||
|
txt: "jel neko u krovu",
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "matches 'ima li koga na krovu'",
|
||||||
|
args: args{
|
||||||
|
txt: "ima li koga na krovu",
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "does not match 'nema nikoga'",
|
||||||
|
args: args{
|
||||||
|
txt: "nema nikoga",
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "matches 'koga ima na krovu'",
|
||||||
|
args: args{
|
||||||
|
txt: "koga ima na krovu",
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "matches 'neko u krov'",
|
||||||
|
args: args{
|
||||||
|
txt: "neko u krov",
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case insensitive match 'EL NEKO krov'",
|
||||||
|
args: args{
|
||||||
|
txt: "EL NEKO krov",
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case insensitive match 'jel neko jebeno u krovu'",
|
||||||
|
args: args{
|
||||||
|
txt: "jel neko jebeno u krovu",
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case insensitive match 'buraz jel neko jebeno u krovu'",
|
||||||
|
args: args{
|
||||||
|
txt: "buraz jel neko jebeno u krovu",
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case insensitive match 'neko u krovu?'",
|
||||||
|
args: args{
|
||||||
|
txt: "neko u krovu?",
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case insensitive match 'u krovu?'",
|
||||||
|
args: args{
|
||||||
|
txt: "u krovu?",
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
nkbot := &NekoUKrovuBot{
|
||||||
|
}
|
||||||
|
if got := nkbot.checkForJelNekoUKrovu(tt.args.txt); got != tt.want {
|
||||||
|
t.Errorf("NekoUKrovuBot.checkForJelNekoUKrovu() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
6
config.ini.example
Normal file
6
config.ini.example
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[credentials]
|
||||||
|
JID = botusername@example.org
|
||||||
|
PASSWORD = bot_password
|
||||||
|
NICK = chatbot
|
||||||
|
ROOM = room_jid@example.org
|
||||||
|
HOST = example.org
|
13
go.mod
Normal file
13
go.mod
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
module gitea.dmz.rs/bauljamic123arlijam/neko-u-krovu-bot
|
||||||
|
|
||||||
|
go 1.23.1
|
||||||
|
|
||||||
|
require github.com/xmppo/go-xmpp v0.2.1
|
||||||
|
|
||||||
|
require github.com/stretchr/testify v1.9.0 // indirect
|
||||||
|
|
||||||
|
require (
|
||||||
|
golang.org/x/crypto v0.23.0 // indirect
|
||||||
|
golang.org/x/net v0.25.0 // indirect
|
||||||
|
gopkg.in/ini.v1 v1.67.0
|
||||||
|
)
|
16
go.sum
Normal file
16
go.sum
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
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/xmppo/go-xmpp v0.2.1 h1:8Bw6W6RNGTq6ajgMiKxn0iJKYt6Atef5Y0A5AkGWn9Q=
|
||||||
|
github.com/xmppo/go-xmpp v0.2.1/go.mod h1:H46WSy/5uHW1SWsyJYI6fRZqFrK326qWmFRpVJ2Wwhs=
|
||||||
|
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||||
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
|
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||||
|
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||||
|
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||||
|
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
14
main.go
Normal file
14
main.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"gitea.dmz.rs/bauljamic123arlijam/neko-u-krovu-bot/chatbot"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
nkbot, err := chatbot.NewNekoUKrovuBot()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
nkbot.Listen()
|
||||||
|
}
|
68
ping/ping.go
Normal file
68
ping/ping.go
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package ping
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os/exec"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Run() int {
|
||||||
|
localIP, err := getLocalIP()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error getting local IP:", err)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
network := getNetworkPrefix(localIP)
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
deviceCount := 0
|
||||||
|
mu := &sync.Mutex{}
|
||||||
|
|
||||||
|
for i := 1; i < 255; i++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go func(i int) {
|
||||||
|
defer wg.Done()
|
||||||
|
addr := fmt.Sprintf("%s.%d", network[:len(network)-2], i)
|
||||||
|
|
||||||
|
if ping(addr) {
|
||||||
|
mu.Lock()
|
||||||
|
deviceCount++
|
||||||
|
mu.Unlock()
|
||||||
|
}
|
||||||
|
}(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
return deviceCount
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLocalIP() (net.IP, error) {
|
||||||
|
addrs, err := net.InterfaceAddrs()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, addr := range addrs {
|
||||||
|
if ipnet, ok := addr.(*net.IPNet); ok && ipnet.IP.IsGlobalUnicast() {
|
||||||
|
return ipnet.IP, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("local IP not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNetworkPrefix(ip net.IP) string {
|
||||||
|
ip = ip.To4()
|
||||||
|
return fmt.Sprintf("%d.%d.%d.0", ip[0], ip[1], ip[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func ping(ip string) bool {
|
||||||
|
output, err := exec.Command("ping", "-c", "1", "-W", "1", ip).CombinedOutput()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
_ = output
|
||||||
|
return true
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user