twitch-bot-tools/automod-debug/main.go

151 lines
3.6 KiB
Go
Raw Normal View History

//nolint:gomnd // Lots of index counts in here, makes not sense
package main
import (
"encoding/json"
"fmt"
"os"
"regexp"
"strconv"
"strings"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/Luzifer/rconfig/v2"
"github.com/Luzifer/twitch-bot/v3/plugins"
)
var (
cfg = struct {
Listen string `flag:"listen" default:":3000" description:"Port/IP to listen on"`
LogLevel string `flag:"log-level" default:"info" description:"Log level (debug, info, warn, error, fatal)"`
VersionAndExit bool `flag:"version" default:"false" description:"Prints current version and exits"`
}{}
categories = map[string]string{
"A": "Aggressive Content",
"I": "Identity-Based Hate",
"P": "Profane Content",
"S": "Sexual Content",
}
flagParse = regexp.MustCompile(`([0-9]+)\-([0-9]+):((?:[AIPS]\.[0-9]+/?)+)`)
flagLevelParse = regexp.MustCompile(`([AIPS])\.([0-9]+)`)
version = "dev"
)
func initApp() error {
rconfig.AutoEnv(true)
if err := rconfig.ParseAndValidate(&cfg); err != nil {
return errors.Wrap(err, "parsing cli options")
}
l, err := logrus.ParseLevel(cfg.LogLevel)
if err != nil {
return errors.Wrap(err, "parsing log-level")
}
logrus.SetLevel(l)
return nil
}
func main() {
var err error
if err = initApp(); err != nil {
logrus.WithError(err).Fatal("initializing app")
}
if cfg.VersionAndExit {
logrus.WithField("version", version).Info("twitch-bot-tools/automod-debug")
os.Exit(0)
}
var input struct {
Message string `json:"message"`
Tags struct {
Flags string `json:"flags"`
} `json:"tags"`
}
if err = json.NewDecoder(os.Stdin).Decode(&input); err != nil {
logrus.WithError(err).Fatal("parsing input")
}
if err = json.NewEncoder(os.Stdout).Encode(flagsToResponse(input.Message, input.Tags.Flags)); err != nil {
logrus.WithError(err).Fatal("encoding response")
}
}
func flagsToResponse(msg, flags string) (out []plugins.RuleAction) {
if flags == "" {
return []plugins.RuleAction{respondMessage("AutoMod is fine with your message! SeemsGood")}
}
var (
issues = strings.Split(flags, ",")
idx = 0
)
for _, issue := range issues {
fields := flagParse.FindStringSubmatch(issue)
if len(fields) != 4 {
continue
}
startIdx, _ := strconv.Atoi(fields[1])
endIdx, _ := strconv.Atoi(fields[2])
var excerpt string
switch {
case startIdx == 0:
case startIdx <= 5:
excerpt += strings.TrimLeft(msg[0:startIdx], " ")
default:
excerpt += "…" + strings.TrimLeft(msg[startIdx-5:startIdx], " ")
}
excerpt += fmt.Sprintf("[[%s]]", msg[startIdx:endIdx+1])
switch {
case len(msg)-endIdx == 0:
case len(msg)-endIdx <= 6:
excerpt += strings.TrimRight(msg[endIdx+1:], " ")
default:
excerpt += strings.TrimRight(msg[endIdx+1:endIdx+6], " ") + "…"
}
for _, flag := range strings.Split(fields[3], "/") {
idx++
cat, lvl := parseLevel(flag)
out = append(out, respondMessage("[%.02d] %s Level %d: %s", idx, cat, lvl, excerpt))
}
}
out = append([]plugins.RuleAction{respondMessage("AutoMod found %d issue(s) with that message! D:", idx)}, out...)
return out
}
func parseLevel(flag string) (cat string, lvl int) {
pts := flagLevelParse.FindStringSubmatch(flag)
if len(pts) != 3 {
logrus.WithField("flag", flag).Warn("flag format does not match expectation")
return cat, lvl
}
cat = categories[pts[1]]
lvl, _ = strconv.Atoi(pts[2])
return cat, lvl
}
func respondMessage(message string, vars ...any) plugins.RuleAction {
return plugins.RuleAction{
Type: "respond",
Attributes: plugins.FieldCollectionFromData(map[string]any{"message": fmt.Sprintf(message, vars...)}),
}
}