CLEAN UP THE CODE AGAIN RAAAAAAAAAAH

This commit is contained in:
Michał Gdula 2025-05-08 20:33:47 +01:00
parent fbb0b61556
commit 972e1371fd
10 changed files with 137 additions and 188 deletions

View file

@ -7,7 +7,7 @@ steps:
image: golang:1.24-alpine3.20 image: golang:1.24-alpine3.20
commands: commands:
- go mod tidy - go mod tidy
- go build -ldflags="-X 'main.ConfigBuildHash=$CI_COMMIT_SHA' -X 'main.ConfigBuildPipeline=$CI_PIPELINE_URL'" -o lynxie . - go build -ldflags="-X 'github.com/Fluffy-Bean/lynxie/_resources.BuildHash=$CI_COMMIT_SHA' -X 'github.com/Fluffy-Bean/lynxie/_resources.BuildPipelineLink=$CI_PIPELINE_URL'" -o lynxie .
- name: deploy - name: deploy
image: alpine:latest image: alpine:latest
commands: commands:

View file

@ -6,3 +6,6 @@ import (
//go:embed fonts/Roboto.ttf //go:embed fonts/Roboto.ttf
var FontRoboto []byte var FontRoboto []byte
var BuildHash string
var BuildPipelineLink string

View file

@ -1,10 +0,0 @@
package err
type Error struct {
Msg string
Err error
}
func (e *Error) Ok() bool {
return e.Err == nil
}

View file

@ -1,4 +1,4 @@
package app package errors
type Error struct { type Error struct {
Msg string Msg string

View file

@ -1,67 +1,65 @@
package app package handler
import ( import (
"fmt" "fmt"
"log"
"os" "os"
"os/signal" "os/signal"
"strings" "strings"
"syscall" "syscall"
"github.com/Fluffy-Bean/lynxie/internal/color" "github.com/Fluffy-Bean/lynxie/internal/color"
"github.com/Fluffy-Bean/lynxie/internal/errors"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
) )
type Callback func(h *Handler, args []string) Error type Callback func(h *Handler, args []string) errors.Error
type Config struct { type Bot struct {
BotPrefix string Prefix string
BotToken string token string
BotIntents discordgo.Intent intents discordgo.Intent
CommandExtras map[string]string commands map[string]Callback
aliases map[string]string
} }
type App struct { func NewBot(prefix, token string, intents discordgo.Intent) *Bot {
Config Config return &Bot{
Commands map[string]Callback Prefix: prefix,
CommandAliases map[string]string token: token,
} intents: intents,
commands: make(map[string]Callback),
func NewApp(config Config) *App { aliases: make(map[string]string),
return &App{
Config: config,
Commands: make(map[string]Callback),
CommandAliases: make(map[string]string),
} }
} }
func (a *App) RegisterCommand(cmd string, f Callback) { func (b *Bot) RegisterCommand(cmd string, f Callback) {
a.Commands[cmd] = f b.commands[cmd] = f
} }
func (a *App) RegisterCommandAlias(alias, cmd string) { func (b *Bot) RegisterCommandAlias(alias, cmd string) {
a.CommandAliases[alias] = cmd b.aliases[alias] = cmd
} }
func (a *App) Run() { func (b *Bot) Run() {
dg, err := discordgo.New("Bot " + a.Config.BotToken) dg, err := discordgo.New("Bot " + b.token)
if err != nil { if err != nil {
fmt.Println("error creating Discord session,", err) fmt.Println("Could not create Discord session:", err)
return return
} }
dg.AddHandler(a.handler) dg.AddHandler(b.handler)
dg.Identify.Intents = a.Config.BotIntents dg.Identify.Intents = b.intents
err = dg.Open() err = dg.Open()
if err != nil { if err != nil {
fmt.Println("error opening connection,", err) fmt.Println("Could not connect:", err)
return return
} }
fmt.Println("Bot is now running. Press CTRL-C to exit.") fmt.Println("Bot is now running. Press CTRL-C to exit.")
sc := make(chan os.Signal, 1) sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt) signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
<-sc <-sc
@ -75,7 +73,7 @@ type Handler struct {
Reference *discordgo.MessageReference Reference *discordgo.MessageReference
} }
func (a *App) handler(session *discordgo.Session, message *discordgo.MessageCreate) { func (b *Bot) handler(session *discordgo.Session, message *discordgo.MessageCreate) {
h := &Handler{ h := &Handler{
Session: session, Session: session,
Message: message, Message: message,
@ -87,8 +85,8 @@ func (a *App) handler(session *discordgo.Session, message *discordgo.MessageCrea
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
printError(a, h, Error{ printError(b, h, errors.Error{
Msg: "But the bot simply refused", Msg: "But the b simply refused",
Err: fmt.Errorf("%v", r), Err: fmt.Errorf("%v", r),
}) })
} }
@ -105,19 +103,19 @@ func (a *App) handler(session *discordgo.Session, message *discordgo.MessageCrea
var args string var args string
cmd = h.Message.Content cmd = h.Message.Content
cmd = strings.TrimPrefix(cmd, a.Config.BotPrefix) cmd = strings.TrimPrefix(cmd, b.Prefix)
cmd, args, _ = strings.Cut(cmd, " ") cmd, args, _ = strings.Cut(cmd, " ")
alias, ok := a.CommandAliases[cmd] alias, ok := b.aliases[cmd]
if ok { if ok {
cmd = alias cmd = alias
} }
callback, ok := a.Commands[cmd] callback, ok := b.commands[cmd]
if !ok { if !ok {
// Falling back to default help command // Falling back to default help command
if cmd == "help" { if cmd == "help" {
printHelp(a, h) printHelp(b, h)
} }
return return
@ -127,13 +125,14 @@ func (a *App) handler(session *discordgo.Session, message *discordgo.MessageCrea
err := callback(h, strings.Split(args, " ")) err := callback(h, strings.Split(args, " "))
if !err.Ok() { if !err.Ok() {
printError(a, h, err) printError(b, h, err)
} }
} }
func printHelp(a *App, h *Handler) { func printHelp(bot *Bot, h *Handler) {
var commands []string var commands []string
for cmd := range a.Commands {
for cmd := range bot.commands {
commands = append(commands, cmd) commands = append(commands, cmd)
} }
@ -147,8 +146,8 @@ func printHelp(a *App, h *Handler) {
}) })
} }
func printError(a *App, h *Handler, e Error) { func printError(bot *Bot, h *Handler, e errors.Error) {
log.Println(e.Err) fmt.Println(e.Err)
_, _ = h.Session.ChannelMessageSendComplex(h.Message.ChannelID, &discordgo.MessageSend{ _, _ = h.Session.ChannelMessageSendComplex(h.Message.ChannelID, &discordgo.MessageSend{
Embed: &discordgo.MessageEmbed{ Embed: &discordgo.MessageEmbed{

27
main.go
View file

@ -3,7 +3,7 @@ package main
import ( import (
"os" "os"
"github.com/Fluffy-Bean/lynxie/app" "github.com/Fluffy-Bean/lynxie/internal/handler"
"github.com/Fluffy-Bean/lynxie/pkg/commands/debug" "github.com/Fluffy-Bean/lynxie/pkg/commands/debug"
"github.com/Fluffy-Bean/lynxie/pkg/commands/img" "github.com/Fluffy-Bean/lynxie/pkg/commands/img"
"github.com/Fluffy-Bean/lynxie/pkg/commands/porb" "github.com/Fluffy-Bean/lynxie/pkg/commands/porb"
@ -11,26 +11,13 @@ import (
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
) )
var ConfigBuildHash string
var ConfigBuildPipeline string
func main() { func main() {
a := app.NewApp(app.Config{ bot := handler.NewBot(">", os.Getenv("TOKEN"), discordgo.IntentsGuildMessages)
BotPrefix: ">",
BotToken: os.Getenv("TOKEN"),
BotIntents: discordgo.IntentsGuildMessages,
CommandExtras: map[string]string{
"debug_build-hash": ConfigBuildHash,
"debug_build-pipeline": ConfigBuildPipeline,
"e621_username": os.Getenv("E621_USERNAME"),
"e621_password": os.Getenv("E621_PASSWORD"),
},
})
debug.RegisterDebugCommands(a) debug.RegisterDebugCommands(bot)
img.RegisterImgCommands(a) img.RegisterImgCommands(bot)
tinyfox.RegisterTinyfoxCommands(a) tinyfox.RegisterTinyfoxCommands(bot)
porb.RegisterPorbCommands(a) porb.RegisterPorbCommands(bot)
a.Run() bot.Run()
} }

View file

@ -6,22 +6,24 @@ import (
"runtime/debug" "runtime/debug"
"strings" "strings"
"github.com/Fluffy-Bean/lynxie/app" "github.com/Fluffy-Bean/lynxie/_resources"
"github.com/Fluffy-Bean/lynxie/internal/color" "github.com/Fluffy-Bean/lynxie/internal/color"
"github.com/Fluffy-Bean/lynxie/internal/errors"
"github.com/Fluffy-Bean/lynxie/internal/handler"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
) )
func RegisterDebugCommands(a *app.App) { func RegisterDebugCommands(bot *handler.Bot) {
a.RegisterCommand("debug", registerDebug(a)) bot.RegisterCommand("debug", registerDebug(bot))
} }
func registerDebug(a *app.App) app.Callback { func registerDebug(bot *handler.Bot) handler.Callback {
return func(h *app.Handler, args []string) app.Error { return func(h *handler.Handler, args []string) errors.Error {
buildTags := "-" buildTags := "-"
goVersion := strings.TrimPrefix(runtime.Version(), "go") goVersion := strings.TrimPrefix(runtime.Version(), "go")
gcCount := runtime.MemStats{}.NumGC gcCount := runtime.MemStats{}.NumGC
buildHash, _ := a.Config.CommandExtras["debug_build-hash"] buildHash := _resources.BuildHash
buildPipeline, _ := a.Config.CommandExtras["debug_build-pipeline"] buildPipeline := _resources.BuildPipelineLink
latency := h.Session.HeartbeatLatency().Milliseconds() latency := h.Session.HeartbeatLatency().Milliseconds()
info, _ := debug.ReadBuildInfo() info, _ := debug.ReadBuildInfo()
@ -72,12 +74,12 @@ func registerDebug(a *app.App) app.Callback {
Reference: h.Reference, Reference: h.Reference,
}) })
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "failed to send debug message", Msg: "failed to send debug message",
Err: err, Err: err,
} }
} }
return app.Error{} return errors.Error{}
} }
} }

View file

@ -4,7 +4,6 @@ import (
"bufio" "bufio"
"bytes" "bytes"
_ "embed" _ "embed"
"errors"
"fmt" "fmt"
"image" "image"
"image/jpeg" "image/jpeg"
@ -16,8 +15,9 @@ import (
"git.sr.ht/~sbinet/gg" "git.sr.ht/~sbinet/gg"
"github.com/Fluffy-Bean/lynxie/_resources" "github.com/Fluffy-Bean/lynxie/_resources"
"github.com/Fluffy-Bean/lynxie/app"
"github.com/Fluffy-Bean/lynxie/internal/color" "github.com/Fluffy-Bean/lynxie/internal/color"
"github.com/Fluffy-Bean/lynxie/internal/errors"
"github.com/Fluffy-Bean/lynxie/internal/handler"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
) )
@ -27,19 +27,19 @@ var client = http.Client{
Timeout: 10 * time.Second, Timeout: 10 * time.Second,
} }
func RegisterImgCommands(a *app.App) { func RegisterImgCommands(bot *handler.Bot) {
a.RegisterCommand("saveable", registerSaveable(a)) bot.RegisterCommand("saveable", registerSaveable(bot))
a.RegisterCommandAlias("gif", "saveable") bot.RegisterCommandAlias("gif", "saveable")
a.RegisterCommand("caption", registerCaption(a)) bot.RegisterCommand("caption", registerCaption(bot))
a.RegisterCommandAlias("c", "caption") bot.RegisterCommandAlias("c", "caption")
} }
func registerSaveable(a *app.App) app.Callback { func registerSaveable(bot *handler.Bot) handler.Callback {
return func(h *app.Handler, args []string) app.Error { return func(h *handler.Handler, args []string) errors.Error {
fileEndpoint, err := findClosestImage(h) fileEndpoint, err := findClosestImage(h)
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "Could not get image", Msg: "Could not get image",
Err: err, Err: err,
} }
@ -47,23 +47,23 @@ func registerSaveable(a *app.App) app.Callback {
req, err := http.NewRequest(http.MethodGet, fileEndpoint, nil) req, err := http.NewRequest(http.MethodGet, fileEndpoint, nil)
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "", Msg: "",
Err: err, Err: err,
} }
} }
if req.ContentLength > maxFileSize { if req.ContentLength > maxFileSize {
return app.Error{ return errors.Error{
Msg: "Could not get image", Msg: "Could not get image",
Err: errors.New("requested file is too big"), Err: fmt.Errorf("requested file is too big"),
} }
} }
res, err := client.Do(req) res, err := client.Do(req)
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "", Msg: "failed to fetch image",
Err: err, Err: err,
} }
} }
@ -88,21 +88,21 @@ func registerSaveable(a *app.App) app.Callback {
Reference: h.Reference, Reference: h.Reference,
}) })
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "failed to send saveable message", Msg: "failed to send saveable message",
Err: err, Err: err,
} }
} }
return app.Error{} return errors.Error{}
} }
} }
func registerCaption(a *app.App) app.Callback { func registerCaption(bot *handler.Bot) handler.Callback {
return func(h *app.Handler, args []string) app.Error { return func(h *handler.Handler, args []string) errors.Error {
fileEndpoint, err := findClosestImage(h) fileEndpoint, err := findClosestImage(h)
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "Could not get image", Msg: "Could not get image",
Err: err, Err: err,
} }
@ -110,23 +110,23 @@ func registerCaption(a *app.App) app.Callback {
req, err := http.NewRequest(http.MethodGet, fileEndpoint, nil) req, err := http.NewRequest(http.MethodGet, fileEndpoint, nil)
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "", Msg: "failed to fetch image",
Err: err, Err: err,
} }
} }
if req.ContentLength > maxFileSize { if req.ContentLength > maxFileSize {
return app.Error{ return errors.Error{
Msg: "Could not get image", Msg: "Could not get image",
Err: errors.New("requested file is too big"), Err: fmt.Errorf("requested file is too big"),
} }
} }
res, err := client.Do(req) res, err := client.Do(req)
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "", Msg: "failed to fetch image",
Err: err, Err: err,
} }
} }
@ -134,7 +134,7 @@ func registerCaption(a *app.App) app.Callback {
buff, err := io.ReadAll(res.Body) buff, err := io.ReadAll(res.Body)
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "failed to read image", Msg: "failed to read image",
Err: err, Err: err,
} }
@ -142,9 +142,9 @@ func registerCaption(a *app.App) app.Callback {
img, err := loadImageFromBytes(buff) img, err := loadImageFromBytes(buff)
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "failed to load image", Msg: "failed to load image",
Err: errors.New("Failed to load image " + err.Error()), Err: fmt.Errorf("Failed to load image " + err.Error()),
} }
} }
imgWidth, imgHeight := img.Bounds().Dx(), img.Bounds().Dy() imgWidth, imgHeight := img.Bounds().Dx(), img.Bounds().Dy()
@ -167,7 +167,7 @@ func registerCaption(a *app.App) app.Callback {
canvas := gg.NewContext(imgWidth, imgHeight+captionHeight) canvas := gg.NewContext(imgWidth, imgHeight+captionHeight)
err = canvas.LoadFontFaceFromBytes(_resources.FontRoboto, captionSize) err = canvas.LoadFontFaceFromBytes(_resources.FontRoboto, captionSize)
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "failed to load font", Msg: "failed to load font",
Err: err, Err: err,
} }
@ -193,7 +193,7 @@ func registerCaption(a *app.App) app.Callback {
&jpeg.Options{Quality: 100}, &jpeg.Options{Quality: 100},
) )
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "failed to encode JPEG", Msg: "failed to encode JPEG",
Err: err, Err: err,
} }
@ -217,13 +217,13 @@ func registerCaption(a *app.App) app.Callback {
Reference: h.Reference, Reference: h.Reference,
}) })
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "failed to send caption message", Msg: "failed to send caption message",
Err: err, Err: err,
} }
} }
return app.Error{} return errors.Error{}
} }
} }
@ -255,11 +255,11 @@ func loadImageFromBytes(buff []byte) (image.Image, error) {
return img, nil return img, nil
} }
func findClosestImage(h *app.Handler) (string, error) { func findClosestImage(h *handler.Handler) (string, error) {
// Get message attachments // Get message attachments
if len(h.Message.Attachments) >= 1 { if len(h.Message.Attachments) >= 1 {
if h.Message.Attachments[0].Size > maxFileSize { if h.Message.Attachments[0].Size > maxFileSize {
return "", errors.New("file size is too big") return "", fmt.Errorf("file size is too big")
} }
return h.Message.Attachments[0].ProxyURL, nil return h.Message.Attachments[0].ProxyURL, nil
@ -269,7 +269,7 @@ func findClosestImage(h *app.Handler) (string, error) {
if h.Message.ReferencedMessage != nil { if h.Message.ReferencedMessage != nil {
if len(h.Message.ReferencedMessage.Attachments) >= 1 { if len(h.Message.ReferencedMessage.Attachments) >= 1 {
if h.Message.ReferencedMessage.Attachments[0].Size > maxFileSize { if h.Message.ReferencedMessage.Attachments[0].Size > maxFileSize {
return "", errors.New("file size is too big") return "", fmt.Errorf("file size is too big")
} }
return h.Message.ReferencedMessage.Attachments[0].ProxyURL, nil return h.Message.ReferencedMessage.Attachments[0].ProxyURL, nil
@ -282,7 +282,7 @@ func findClosestImage(h *app.Handler) (string, error) {
} }
} }
return "", errors.New("no files exists") return "", fmt.Errorf("no files exists")
} }
func measureText(font []byte, text string, size float64, width int) (int, int) { func measureText(font []byte, text string, size float64, width int) (int, int) {

View file

@ -4,13 +4,13 @@ import (
"encoding/json" "encoding/json"
"flag" "flag"
"fmt" "fmt"
"log"
"net/http" "net/http"
"strings" "strings"
"time" "time"
"github.com/Fluffy-Bean/lynxie/app"
"github.com/Fluffy-Bean/lynxie/internal/color" "github.com/Fluffy-Bean/lynxie/internal/color"
"github.com/Fluffy-Bean/lynxie/internal/errors"
"github.com/Fluffy-Bean/lynxie/internal/handler"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
) )
@ -53,23 +53,14 @@ type post struct {
CommentCount int `json:"comment_count"` CommentCount int `json:"comment_count"`
} }
func RegisterPorbCommands(a *app.App) { func RegisterPorbCommands(bot *handler.Bot) {
username, _ := a.Config.CommandExtras["e621_username"] bot.RegisterCommand("e621", registerE621(bot))
password, _ := a.Config.CommandExtras["e621_password"]
if username == "" || password == "" { bot.RegisterCommandAlias("porb", "e621")
log.Println("Not registering e621 command...")
return
}
a.RegisterCommand("e621", registerE621(a))
a.RegisterCommandAlias("porb", "e621")
} }
func registerE621(a *app.App) app.Callback { func registerE621(bot *handler.Bot) handler.Callback {
return func(h *app.Handler, args []string) app.Error { return func(h *handler.Handler, args []string) errors.Error {
var options struct { var options struct {
Order string Order string
Rating string Rating string
@ -82,40 +73,33 @@ func registerE621(a *app.App) app.Callback {
err := cmd.Parse(args) err := cmd.Parse(args)
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "failed parsing e621 flags", Msg: "failed parsing e621 flags",
Err: err, Err: err,
} }
} }
req, err := http.NewRequest( url := fmt.Sprintf(
http.MethodGet,
fmt.Sprintf(
"https://e621.net/posts.json/?limit=1&tags=order:%s+rating:%s+%s", "https://e621.net/posts.json/?limit=1&tags=order:%s+rating:%s+%s",
options.Order, options.Order,
options.Rating, options.Rating,
strings.Join(cmd.Args(), "+"), strings.Join(cmd.Args(), "+"),
),
nil,
) )
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "failed to make request", Msg: "failed to make request",
Err: err, Err: err,
} }
} }
username, _ := a.Config.CommandExtras["e621_username"]
password, _ := a.Config.CommandExtras["e621_password"]
req.Header.Add("Accept", "application/json") req.Header.Add("Accept", "application/json")
req.Header.Add("Content-Type", "application/json") req.Header.Add("Content-Type", "application/json")
req.Header.Add("User-Agent", fmt.Sprintf("Lynxie/2.0 (by %s on e621)", username))
req.SetBasicAuth(username, password)
res, err := client.Do(req) res, err := client.Do(req)
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "Failed to do request", Msg: "Failed to do request",
Err: err, Err: err,
} }
@ -127,14 +111,14 @@ func registerE621(a *app.App) app.Callback {
} }
err = json.NewDecoder(res.Body).Decode(&data) err = json.NewDecoder(res.Body).Decode(&data)
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "failed decoding e621 response", Msg: "failed decoding e621 response",
Err: err, Err: err,
} }
} }
if len(data.Posts) == 0 { if len(data.Posts) == 0 {
return app.Error{ return errors.Error{
Msg: "no posts found", Msg: "no posts found",
Err: fmt.Errorf("no posts found"), Err: fmt.Errorf("no posts found"),
} }
@ -147,13 +131,6 @@ func registerE621(a *app.App) app.Callback {
description = "No description provided." description = "No description provided."
} }
var generalTags string
if len(data.Posts[0].Tags.General) > 0 {
generalTags = strings.Join(data.Posts[0].Tags.General[:20], ", ")
} else {
generalTags = "No tags provided."
}
_, err = h.Session.ChannelMessageSendComplex(h.Message.ChannelID, &discordgo.MessageSend{ _, err = h.Session.ChannelMessageSendComplex(h.Message.ChannelID, &discordgo.MessageSend{
Embed: &discordgo.MessageEmbed{ Embed: &discordgo.MessageEmbed{
Title: "E621", Title: "E621",
@ -176,33 +153,24 @@ func registerE621(a *app.App) app.Callback {
Value: strings.Join(data.Posts[0].Sources, ", "), Value: strings.Join(data.Posts[0].Sources, ", "),
Inline: false, Inline: false,
}, },
{
Name: "Tag(s)",
Value: generalTags,
Inline: false,
},
}, },
Image: &discordgo.MessageEmbedImage{ Image: &discordgo.MessageEmbedImage{
URL: data.Posts[0].File.Url, URL: data.Posts[0].File.Url,
}, },
Footer: &discordgo.MessageEmbedFooter{ Footer: &discordgo.MessageEmbedFooter{
Text: fmt.Sprintf( Text: fmt.Sprintf("ID: %d | Created: %s", data.Posts[0].Id, data.Posts[0].CreatedAt.Format(time.DateTime)),
"ID: %d | Created: %s",
data.Posts[0].Id,
data.Posts[0].CreatedAt.Format(time.DateTime),
),
}, },
Color: color.RGBToDiscord(255, 255, 255), Color: color.RGBToDiscord(255, 255, 255),
}, },
Reference: h.Reference, Reference: h.Reference,
}) })
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "failed sending e621 message", Msg: "failed sending e621 message",
Err: err, Err: err,
} }
} }
return app.Error{} return errors.Error{}
} }
} }

View file

@ -1,15 +1,15 @@
package tinyfox package tinyfox
import ( import (
"errors"
"fmt" "fmt"
"net/http" "net/http"
"slices" "slices"
"strings" "strings"
"time" "time"
"github.com/Fluffy-Bean/lynxie/app"
"github.com/Fluffy-Bean/lynxie/internal/color" "github.com/Fluffy-Bean/lynxie/internal/color"
"github.com/Fluffy-Bean/lynxie/internal/errors"
"github.com/Fluffy-Bean/lynxie/internal/handler"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
) )
@ -80,18 +80,18 @@ var animalAliases = map[string]string{
"opossum": "poss", "opossum": "poss",
} }
func RegisterTinyfoxCommands(a *app.App) { func RegisterTinyfoxCommands(bot *handler.Bot) {
a.RegisterCommand("animal", registerAnimal(a)) bot.RegisterCommand("animal", registerAnimal(bot))
a.RegisterCommandAlias("a", "animal") bot.RegisterCommandAlias("bot", "animal")
} }
func registerAnimal(a *app.App) app.Callback { func registerAnimal(bot *handler.Bot) handler.Callback {
return func(h *app.Handler, args []string) app.Error { return func(h *handler.Handler, args []string) errors.Error {
if len(args) < 1 { if len(args) < 1 {
return app.Error{ return errors.Error{
Msg: "Animal name is required!", Msg: "Animal name is required!",
Err: errors.New("animal name is required"), Err: fmt.Errorf("animal name is required"),
} }
} }
@ -100,9 +100,9 @@ func registerAnimal(a *app.App) app.Callback {
if !slices.Contains(animals, animal) { if !slices.Contains(animals, animal) {
alias, ok := animalAliases[animal] alias, ok := animalAliases[animal]
if !ok { if !ok {
return app.Error{ return errors.Error{
Msg: fmt.Sprintf("Animal \"%s\" is invalid. The following animals are supported:\n%s", animal, strings.Join(animals, ", ")), Msg: fmt.Sprintf("Animal \"%s\" is invalid. The following animals are supported:\n%s", animal, strings.Join(animals, ", ")),
Err: errors.New("entered invalid animal name"), Err: fmt.Errorf("entered invalid animal name"),
} }
} }
animal = alias animal = alias
@ -110,7 +110,7 @@ func registerAnimal(a *app.App) app.Callback {
req, err := http.NewRequest(http.MethodGet, "https://api.tinyfox.dev/img?animal="+animal, nil) req, err := http.NewRequest(http.MethodGet, "https://api.tinyfox.dev/img?animal="+animal, nil)
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "Failed to make request", Msg: "Failed to make request",
Err: err, Err: err,
} }
@ -118,7 +118,7 @@ func registerAnimal(a *app.App) app.Callback {
res, err := client.Do(req) res, err := client.Do(req)
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "Failed to do request", Msg: "Failed to do request",
Err: err, Err: err,
} }
@ -143,12 +143,12 @@ func registerAnimal(a *app.App) app.Callback {
Reference: h.Reference, Reference: h.Reference,
}) })
if err != nil { if err != nil {
return app.Error{ return errors.Error{
Msg: "failed to send tinyfox message", Msg: "failed to send tinyfox message",
Err: err, Err: err,
} }
} }
return app.Error{} return errors.Error{}
} }
} }