4 Commits
Author SHA1 Message Date
gisle c2d029f918 fix posts not being logged after logbot reconnect.
continuous-integration/drone/push Build is passing
2020-08-09 13:01:06 +02:00
gisle 293102c1c6 add more logging and update irc code.
continuous-integration/drone/push Build is passing
2020-07-20 21:14:49 +02:00
gisle de04d6069b simply and hopefully fix channel leave/join
continuous-integration/drone/push Build is passing
2020-07-20 20:40:55 +02:00
gisle b249a495a4 add more debug stuffs.
continuous-integration/drone/push Build is passing
2020-07-20 20:15:55 +02:00
9 changed files with 90 additions and 60 deletions
+1 -1
View File
@@ -35,7 +35,7 @@ steps:
- tag - tag
- name: go-build-1.14 - name: go-build-1.14
image: golang:1.13 image: golang:1.14
commands: commands:
- go mod download - go mod download
- CGO_ENABLED=0 go build -ldflags "-w -s" . - CGO_ENABLED=0 go build -ldflags "-w -s" .
+2 -2
View File
@@ -1,6 +1,6 @@
## 1. Build Server ## 1. Build Server
# Use Go 1.11 # Use Go 1.14
FROM golang:1.11 AS build FROM golang:1.14 AS build
# Load repository into docker # Load repository into docker
WORKDIR /project WORKDIR /project
+1 -1
View File
@@ -4,5 +4,5 @@ go 1.13
require ( require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/gissleh/irc v0.0.0-20200717144508-ec7511e0dfd4 github.com/gissleh/irc v0.0.0-20200720191144-af5dc31ff33d
) )
+4 -10
View File
@@ -1,12 +1,6 @@
git.aiterp.net/gisle/irc v0.0.0-20190317212656-36c2a5ea38d3 h1:2UYpXoDYcgeIGxRX+5K2e/CK0BNAQUZ6xU/9JjQYwDk=
git.aiterp.net/gisle/irc v0.0.0-20190317212656-36c2a5ea38d3/go.mod h1:7uklwlzI0XI2O8ttooTH0suUpUmQ8Pviplg36smc1Aw=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/gissleh/irc v0.0.0-20200717144508-ec7511e0dfd4 h1:2rT4geKF5Zb0TyJjqp8ylUXwfrwIvMESdERItJtmtDI= github.com/gissleh/irc v0.0.0-20200720173331-512ba5aa6fca h1:vTL3kM7PkVnTy77i2/ewaC0VDmSEF7sAOMDTNIs6rKY=
github.com/gissleh/irc v0.0.0-20200717144508-ec7511e0dfd4/go.mod h1:dUQ3oIxO/lK/Ga5Dq72/1tH861WBDJFkkBtbnqg6ZXc= github.com/gissleh/irc v0.0.0-20200720173331-512ba5aa6fca/go.mod h1:h2/fPlbnb11gFpitk0HGxYLgK+bCKGh55QSYNo36X8M=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/gissleh/irc v0.0.0-20200720191144-af5dc31ff33d h1:PbjXoijU290Y6qTD/LM9yyFTWgX8iJtPMQ4Adwsn954=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/gissleh/irc v0.0.0-20200720191144-af5dc31ff33d/go.mod h1:h2/fPlbnb11gFpitk0HGxYLgK+bCKGh55QSYNo36X8M=
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/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+39 -40
View File
@@ -6,9 +6,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/gissleh/irc"
"git.aiterp.net/rpdata/logbot3/internal/models"
"git.aiterp.net/rpdata/logbot3/internal/models/channels" "git.aiterp.net/rpdata/logbot3/internal/models/channels"
"github.com/gissleh/irc"
) )
var botKey = "git.aiterp.net/rpdata/logbot.Bot.key" var botKey = "git.aiterp.net/rpdata/logbot.Bot.key"
@@ -54,6 +53,8 @@ func (bot *Bot) Connect(server string, ssl bool, maxRetries int) (err error) {
} }
bot.ctx, bot.ctxCancel = context.WithCancel(bot.client.Context()) bot.ctx, bot.ctxCancel = context.WithCancel(bot.client.Context())
bot.channels = make(map[string]*Channel)
retries := 0 retries := 0
for maxRetries == 0 || retries < maxRetries { for maxRetries == 0 || retries < maxRetries {
err = bot.client.Connect(server, ssl) err = bot.client.Connect(server, ssl)
@@ -76,6 +77,10 @@ func (bot *Bot) Connect(server string, ssl bool, maxRetries int) (err error) {
return err return err
} }
func (bot *Bot) ClientState() irc.ClientState {
return bot.client.State()
}
func (bot *Bot) addChannel(channelName string) *Channel { func (bot *Bot) addChannel(channelName string) *Channel {
if bot.channels[channelName] != nil { if bot.channels[channelName] != nil {
return bot.channels[channelName] return bot.channels[channelName]
@@ -114,54 +119,48 @@ func (bot *Bot) runCommands(commands []string, target irc.Target, replacers map[
func (bot *Bot) loop() { func (bot *Bot) loop() {
bot.loopCtx, bot.loopCancel = context.WithCancel(bot.ctx) bot.loopCtx, bot.loopCancel = context.WithCancel(bot.ctx)
channelChanges, err := channels.SubscribeLogged(bot.ctx) ticker := time.NewTicker(time.Second * 10)
if err != nil { defer ticker.Stop()
log.Println("Failed to get channel changes:", err)
return
}
for { for {
select { select {
case channel := <-channelChanges: case <-ticker.C:
{ {
channels := []models.Channel{channel} loggedChannels, err := channels.ListLogged(bot.ctx)
deadline := time.After(time.Second * 1) if err != nil {
buffering := true log.Println("Failed to list logged channels:", err)
for buffering { continue
select { }
case channel := <-channelChanges: loggedMap := make(map[string]bool)
channels = append(channels, channel) for _, channel := range loggedChannels {
case <-deadline: loggedMap[channel.Name] = true
buffering = false }
clientMap := make(map[string]bool)
for _, channel := range bot.client.Channels() {
clientMap[channel.Name()] = true
}
joins := make([]string, 0, len(loggedMap))
parts := make([]string, 0, len(clientMap))
for key := range loggedMap {
if !clientMap[key] {
joins = append(joins, key)
}
}
for key := range clientMap {
if !loggedMap[key] {
parts = append(parts, key)
} }
} }
decisions := make(map[string]bool)
for _, channel := range channels {
decisions[channel.Name] = channel.Logged
}
joins := make([]string, 0, len(decisions))
parts := make([]string, 0, len(decisions))
for channelName, logged := range decisions {
if logged {
if bot.client.Channel(channelName) != nil {
continue
}
joins = append(joins, channelName)
} else {
if bot.client.Channel(channelName) == nil {
continue
}
parts = append(parts, channelName)
}
}
if len(joins) > 0 {
bot.client.Join(joins...)
}
if len(parts) > 0 { if len(parts) > 0 {
log.Println("Leaving", strings.Join(parts, ", "))
bot.client.Part(parts...) bot.client.Part(parts...)
} }
if len(joins) > 0 {
log.Println("Joining", strings.Join(joins, ", "))
bot.client.Join(joins...)
}
} }
case <-bot.loopCtx.Done(): case <-bot.loopCtx.Done():
+3 -3
View File
@@ -29,7 +29,7 @@ type Channel struct {
} }
func newChannel(parent *Bot, name string, client *irc.Client) *Channel { func newChannel(parent *Bot, name string, client *irc.Client) *Channel {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(parent.ctx)
return &Channel{ return &Channel{
name: name, name: name,
@@ -132,7 +132,7 @@ func (channel *Channel) loop() {
if target != nil { if target != nil {
me, ok := target.UserList().User(channel.client.Nick()) me, ok := target.UserList().User(channel.client.Nick())
if !ok || !strings.ContainsRune(me.Modes, 'o') { if !ok || !strings.ContainsRune(me.Modes, 'o') {
channel.client.Say(channel.name, "This unit require operator privileges to serve this request.") channel.client.Say(channel.name, "This unit has insufficient privileges.")
break break
} }
@@ -266,7 +266,7 @@ func (channel *Channel) loop() {
channel.lastPostSessionID = "" channel.lastPostSessionID = ""
} }
case <-channel.parentCtx.Done(): case <-channel.ctx.Done():
{ {
// Time to pack up shop. // Time to pack up shop.
return return
+15 -1
View File
@@ -31,7 +31,17 @@ func handler(event *irc.Event, client *irc.Client) {
bot.stopLoop() bot.stopLoop()
conf := config.Get().Server conf := config.Get().Server
go bot.Connect(conf.Address, conf.SSL, 0) go bot.Connect(conf.Address, conf.SSL, 100)
}
// Log Connections
case "client.connecting":
{
log.Println("Client is connecting...")
}
case "client.connect":
{
log.Println("Client connected!")
} }
// Log joins and leaves // Log joins and leaves
@@ -133,6 +143,10 @@ func handler(event *irc.Event, client *irc.Client) {
} }
} }
if event.Kind() == "error" {
log.Printf("Client Error (%s) %s\n", event.Verb(), event.Text)
}
// Always log error numerics. // Always log error numerics.
if len(event.Verb()) == 3 && event.Verb()[0] == '4' || event.Verb()[0] == '9' { if len(event.Verb()) == 3 && event.Verb()[0] == '4' || event.Verb()[0] == '9' {
log.Printf("(%s) %s %s\n", event.Verb(), strings.Join(event.Args, " "), event.Text) log.Printf("(%s) %s %s\n", event.Verb(), strings.Join(event.Args, " "), event.Text)
+6 -2
View File
@@ -14,10 +14,14 @@ type Config struct {
User string `json:"user"` User string `json:"user"`
RealName string `json:"realName"` RealName string `json:"realName"`
} `json:"bot"` } `json:"bot"`
Debug struct {
Enabled bool `json:"enabled"`
Listen string `json:"listen"`
} `json:"debug"`
Server struct { Server struct {
Address string `json:"server"` Address string `json:"server"`
SSL bool `json:"ssl"` SSL bool `json:"ssl"`
} } `json:"server"`
API struct { API struct {
Endpoint string `json:"endpoint"` Endpoint string `json:"endpoint"`
Username string `json:"username"` Username string `json:"username"`
@@ -32,7 +36,7 @@ type Config struct {
} `json:"commands"` } `json:"commands"`
Names struct { Names struct {
ChanServ string `json:"chanserv"` ChanServ string `json:"chanserv"`
} } `json:"names"`
} }
var mutex sync.Mutex var mutex sync.Mutex
+19
View File
@@ -2,7 +2,9 @@ package main
import ( import (
"context" "context"
"encoding/json"
"log" "log"
"net/http"
"os" "os"
"os/signal" "os/signal"
"strings" "strings"
@@ -31,6 +33,23 @@ func main() {
os.Exit(1) os.Exit(1)
} }
if conf.Debug.Enabled {
mux := http.NewServeMux()
mux.HandleFunc("/state", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(200)
_ = json.NewEncoder(w).Encode(bot.ClientState())
})
go func() {
err := http.ListenAndServe(conf.Debug.Listen, mux)
if err != nil {
log.Println("Failed to setup debug listener", err)
}
}()
}
// Listen for a quit signal. // Listen for a quit signal.
interrupt := make(chan os.Signal, 1) interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt) signal.Notify(interrupt, os.Interrupt)