initial working version
commit
0c0aeb2944
|
@ -0,0 +1,5 @@
|
|||
module code.hackerspace.pl/ar/notbot
|
||||
|
||||
go 1.16
|
||||
|
||||
require gopkg.in/irc.v3 v3.1.4
|
|
@ -0,0 +1,13 @@
|
|||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/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/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/irc.v3 v3.1.4 h1:DYGMRFbtseXEh+NadmMUFzMraqyuUj4I3iWYFEzDZPc=
|
||||
gopkg.in/irc.v3 v3.1.4/go.mod h1:shO2gz8+PVeS+4E6GAny88Z0YVVQSxQghdrMVGQsR9s=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
@ -0,0 +1,179 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"gopkg.in/irc.v3"
|
||||
)
|
||||
|
||||
type atMonitor struct {
|
||||
previousUserList []string
|
||||
}
|
||||
|
||||
type atUsers struct {
|
||||
Login string
|
||||
Timestamp float64
|
||||
PrettyTime string `json:"pretty_time"`
|
||||
}
|
||||
|
||||
type atResponse struct {
|
||||
Users []atUsers
|
||||
Esps uint
|
||||
Kektops uint
|
||||
Vms uint
|
||||
Unknown uint
|
||||
}
|
||||
|
||||
func (a *atResponse) UserList() (ret []string) {
|
||||
for _, user := range a.Users {
|
||||
ret = append(ret, user.Login)
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func listSubstract(a, b []string) (ret []string) {
|
||||
mb := make(map[string]bool, len(b))
|
||||
|
||||
for _, x := range b {
|
||||
mb[x] = true
|
||||
}
|
||||
|
||||
for _, x := range a {
|
||||
if _, found := mb[x]; !found {
|
||||
ret = append(ret, x)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (a *atMonitor) Run(c *irc.Client, done chan bool) {
|
||||
ticker := time.NewTicker(10 * time.Second)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
return
|
||||
case <-ticker.C:
|
||||
var diffText string
|
||||
atHS, err := at()
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
break
|
||||
}
|
||||
|
||||
current := atHS.UserList()
|
||||
|
||||
arrived := listSubstract(current, a.previousUserList)
|
||||
left := listSubstract(a.previousUserList, current)
|
||||
|
||||
if len(arrived) > 0 {
|
||||
diffText = fmt.Sprint(" +", arrived)
|
||||
}
|
||||
|
||||
if len(left) > 0 {
|
||||
diffText = fmt.Sprint(" -", left)
|
||||
}
|
||||
|
||||
if len(diffText) > 0 {
|
||||
msg := fmt.Sprintf("NOTICE #hswaw-bottest :%s\n", diffText)
|
||||
log.println(diffText)
|
||||
c.Write(msg)
|
||||
a.previousUserList = current
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func genericHandler(c *irc.Client, m *irc.Message) {
|
||||
log.Println(m)
|
||||
if m.Command == "001" {
|
||||
c.Write("JOIN #hswaw-bottest")
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
done := make(chan bool)
|
||||
var a atMonitor
|
||||
|
||||
conn, err := net.Dial("tcp", "irc.libera.chat:6667")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
config := irc.ClientConfig{
|
||||
Nick: "notbot",
|
||||
Pass: "***",
|
||||
User: "bot",
|
||||
Name: "notbot",
|
||||
Handler: irc.HandlerFunc(genericHandler),
|
||||
}
|
||||
|
||||
client := irc.NewClient(conn, config)
|
||||
go a.Run(client, done)
|
||||
|
||||
err = client.Run()
|
||||
if err != nil {
|
||||
done <- true
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
func at() (at atResponse, err error) {
|
||||
var values atResponse = atResponse{}
|
||||
|
||||
data, err := httpGet("https://at.hackerspace.pl/api")
|
||||
if err != nil {
|
||||
return values, fmt.Errorf("Unable to access checkinator api:", err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(data, &values)
|
||||
if err != nil {
|
||||
return values, fmt.Errorf("Unable to decode checkinator response:", err)
|
||||
}
|
||||
|
||||
return values, nil
|
||||
}
|
||||
|
||||
func httpGet(link string) ([]byte, error) {
|
||||
var buf []byte
|
||||
tr := &http.Transport{
|
||||
TLSHandshakeTimeout: 20 * time.Second,
|
||||
ResponseHeaderTimeout: 20 * time.Second,
|
||||
}
|
||||
client := &http.Client{
|
||||
Transport: tr,
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("GET", link, nil)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Limit response to 5MiB
|
||||
limitedResponse := http.MaxBytesReader(nil, resp.Body, 5*1024*1024)
|
||||
buf = make([]byte, 5*1024*1024)
|
||||
|
||||
i, err := io.ReadFull(limitedResponse, buf)
|
||||
if err == io.ErrUnexpectedEOF {
|
||||
buf = buf[:i]
|
||||
} else if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
}
|
Loading…
Reference in New Issue