125 lines
2.8 KiB
Go
125 lines
2.8 KiB
Go
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
log "github.com/sirupsen/logrus"
|
|
"github.com/spf13/cobra"
|
|
"strings"
|
|
"time"
|
|
"udico.de/uditaren/goboter"
|
|
"udico.de/uditaren/loadmaster2k/api"
|
|
. "udico.de/uditaren/loadmaster2k/config"
|
|
"udico.de/uditaren/terminator"
|
|
)
|
|
|
|
var cBot = &cobra.Command{
|
|
Use: "bot",
|
|
Short: "Run the bot",
|
|
}
|
|
|
|
|
|
func init() {
|
|
cBot.RunE = executeBot
|
|
|
|
cRoot.AddCommand(cBot)
|
|
}
|
|
|
|
type Load struct {
|
|
Area *Area
|
|
Load int
|
|
Status string
|
|
Err error
|
|
}
|
|
|
|
func (l Load) String() string {
|
|
if l.Err != nil {
|
|
return fmt.Sprintf("%v: error='%v'", l.Area, l.Err.Error())
|
|
}
|
|
return fmt.Sprintf("%v: load=%v%%, status='%v'", l.Area, l.Load, l.Status)
|
|
}
|
|
|
|
func executeBot(cmd *cobra.Command, args []string) error {
|
|
log.Info("Starting bot")
|
|
defer log.Info("Bot done")
|
|
|
|
if C.Bot.Token == "" {
|
|
return errors.New("missing bot api token")
|
|
}
|
|
if len(C.Bot.Channels) == 0 {
|
|
log.Warn("There is no channel associated to the bot.")
|
|
log.Warn("Please add the bot to a channel. It will respond with a single message, which you may pin.")
|
|
log.Warn("Channel and message id will be dumped to the logs")
|
|
}
|
|
tBot := goboter.NewTelegramBot(C.Bot.Token, "loadmaster2k")
|
|
|
|
tContext, tCancelFunc := context.WithCancel(context.Background())
|
|
go tBot.LongPoll(tContext, 30)
|
|
go func() {
|
|
updates:
|
|
for {
|
|
select {
|
|
case tUpdate := <- tBot.Updates:
|
|
log.Infof("BOT: %v", tUpdate)
|
|
case <-terminator.Terminate:
|
|
tCancelFunc()
|
|
break updates
|
|
}
|
|
}
|
|
}()
|
|
|
|
log.Debugf("Checking state every %v seconds", C.Bot.Interval)
|
|
tTickC := time.NewTicker(time.Second * time.Duration(C.Bot.Interval)).C
|
|
waiter:
|
|
for {
|
|
// handle here to simulate an "initial tick"
|
|
log.Debug("Tick...")
|
|
|
|
loads := make([]*Load, 0, 5)
|
|
for i, area := range C.Areas {
|
|
log.Debugf("Fetching load data for %v", area)
|
|
tLoad := &Load{
|
|
Area: &C.Areas[i],
|
|
}
|
|
tData, err := api.FetchArea(area.Id)
|
|
if err != nil {
|
|
tLoad.Err = err
|
|
continue
|
|
} else {
|
|
tLoad.Load, tLoad.Status = api.ParseAreaStatus(tData)
|
|
}
|
|
loads = append(loads, tLoad)
|
|
log.Info(tLoad)
|
|
}
|
|
tMessage := &strings.Builder{}
|
|
for _, tL := range loads {
|
|
tMessage.WriteString(fmt.Sprintf("%v: __*%v%%*__ \\(%v\\)\n", tL.Area.Name, tL.Load, tL.Status))
|
|
}
|
|
tMessage.WriteString("\\(Stand " + time.Now().Format("2006\\-01\\-02 15:04") + "\\)" )
|
|
for _, tChan := range C.Bot.Channels {
|
|
if tChan.Id != 0 {
|
|
if tChan.Message != 0 {
|
|
// edit
|
|
_, err := tBot.EditMessageText(tChan.Id, tChan.Message, tMessage.String())
|
|
if err != nil {
|
|
log.WithError(err).Error("cannot update message")
|
|
}
|
|
} else {
|
|
tMsg, err := tBot.SendMessage(tChan.Id, tMessage.String(), 0)
|
|
log.WithError(err).Info(tMsg)
|
|
}
|
|
}
|
|
}
|
|
|
|
select {
|
|
case <-tTickC:
|
|
continue
|
|
case <-terminator.Terminate:
|
|
log.Info("Terminating bot")
|
|
break waiter
|
|
}
|
|
}
|
|
|
|
return nil
|
|
} |