From b4d31974d318d01ef94cfe0279611ace43c1e51e Mon Sep 17 00:00:00 2001 From: Fluffy-Bean Date: Mon, 31 Mar 2025 11:36:18 +0100 Subject: [PATCH] cleany --- commands/debug/debug.go | 92 +++++++++++++ commands/meta.go | 97 -------------- commands/porb.go | 212 ------------------------------ commands/porb/porb.go | 145 ++++++++++++++++++++ commands/porb/types.go | 75 +++++++++++ commands/{ => tinyfox}/tinyfox.go | 36 ++--- main.go | 10 +- 7 files changed, 337 insertions(+), 330 deletions(-) create mode 100644 commands/debug/debug.go delete mode 100644 commands/meta.go delete mode 100644 commands/porb.go create mode 100644 commands/porb/porb.go create mode 100644 commands/porb/types.go rename commands/{ => tinyfox}/tinyfox.go (68%) diff --git a/commands/debug/debug.go b/commands/debug/debug.go new file mode 100644 index 0000000..d8ea719 --- /dev/null +++ b/commands/debug/debug.go @@ -0,0 +1,92 @@ +package debug + +import ( + "fmt" + "runtime" + "runtime/debug" + "strings" + "time" + + "github.com/Fluffy-Bean/lynxie/app" + "github.com/Fluffy-Bean/lynxie/utils" + "github.com/bwmarrin/discordgo" +) + +func RegisterDebugCommands(a *app.App) { + a.RegisterCommand("debug", registerDebug(a)) +} + +func registerDebug(a *app.App) app.Callback { + return func(h *app.Handler, args []string) app.Error { + modified := false + revision := "-" + buildTags := "-" + goVersion := strings.TrimPrefix(runtime.Version(), "go") + gcCount := runtime.MemStats{}.NumGC + localTime := time.Now().Local().Format("2006-01-02 15:04:05") + latency := h.Session.HeartbeatLatency().Milliseconds() + + info, _ := debug.ReadBuildInfo() + for _, setting := range info.Settings { + switch setting.Key { + case "vcs.revision": + revision = setting.Value + case "vcs.modified": + modified = setting.Value == "true" + case "-tags": + buildTags = strings.ReplaceAll(setting.Value, ",", " ") + } + } + + if modified { + revision += " (modified)" + } + + h.Session.ChannelMessageSendComplex(h.Message.ChannelID, &discordgo.MessageSend{ + Embed: &discordgo.MessageEmbed{ + Title: "Lynxie", + Fields: []*discordgo.MessageEmbedField{ + { + Name: "Revision", + Value: revision, + Inline: false, + }, + { + Name: "Build Tags", + Value: buildTags, + Inline: false, + }, + { + Name: "Go version", + Value: goVersion, + Inline: false, + }, + { + Name: "OS/Arch", + Value: runtime.GOOS + "/" + runtime.GOARCH, + Inline: false, + }, + { + Name: "GC Count", + Value: fmt.Sprint(gcCount), + Inline: false, + }, + { + Name: "Local Time", + Value: localTime, + Inline: false, + }, + { + Name: "Latency", + Value: fmt.Sprintf("%dms", latency), + Inline: false, + }, + }, + Color: utils.ColorFromRGB(255, 255, 255), + }, + Reference: h.Reference, + }) + + return app.Error{} + } +} diff --git a/commands/meta.go b/commands/meta.go deleted file mode 100644 index 917b020..0000000 --- a/commands/meta.go +++ /dev/null @@ -1,97 +0,0 @@ -package commands - -import ( - "flag" - "fmt" - "runtime" - "runtime/debug" - "strings" - "time" - - "github.com/Fluffy-Bean/lynxie/app" - "github.com/Fluffy-Bean/lynxie/utils" - "github.com/bwmarrin/discordgo" -) - -func RegisterMetaCommands(a *app.App) { - a.RegisterCommand("ping", registerPong(a)) - a.RegisterCommand("debug", registerDebug(a)) -} - -func registerPong(a *app.App) app.Callback { - return func(h *app.Handler, args []string) app.Error { - var options struct { - latency bool - } - - cmd := flag.NewFlagSet("", flag.ContinueOnError) - cmd.BoolVar(&options.latency, "latency", false, "Display the latency of ping") - cmd.Parse(args) - - var content string - if options.latency { - content = fmt.Sprintf("Pong! %dms", h.Session.HeartbeatLatency().Milliseconds()) - } else { - content = "Pong!" - } - - h.Session.ChannelMessageSendComplex(h.Message.ChannelID, &discordgo.MessageSend{ - Embed: &discordgo.MessageEmbed{ - Description: content, - Color: utils.ColorFromRGB(255, 255, 255), - }, - Reference: h.Reference, - }) - - return app.Error{} - } -} - -func registerDebug(a *app.App) app.Callback { - return func(h *app.Handler, args []string) app.Error { - modified := false - revision := "-" - tags := "-" - _go := strings.TrimPrefix(runtime.Version(), "go") - gcCount := runtime.MemStats{}.NumGC - localTime := time.Now().Local().Format("2006-01-02 15:04:05") - - info, _ := debug.ReadBuildInfo() - for _, setting := range info.Settings { - switch setting.Key { - case "vcs.revision": - revision = setting.Value - case "vcs.modified": - modified = setting.Value == "true" - case "-tags": - tags = strings.ReplaceAll(setting.Value, ",", " ") - } - } - - if modified { - revision += " (uncommitted changes)" - } - - h.Session.ChannelMessageSendComplex(h.Message.ChannelID, &discordgo.MessageSend{ - Embed: &discordgo.MessageEmbed{ - Description: strings.Join( - []string{ - "```", - "Revision: " + revision, - "Build Tags: " + tags, - "Go version: " + _go, - "OS/Arch: " + runtime.GOOS + "/" + runtime.GOARCH, - "GC Count: " + fmt.Sprint(gcCount), - "Local Time: " + localTime, - "```", - }, - "\n", - ), - Color: utils.ColorFromRGB(255, 255, 255), - }, - Reference: h.Reference, - }) - - return app.Error{} - } -} diff --git a/commands/porb.go b/commands/porb.go deleted file mode 100644 index 12af249..0000000 --- a/commands/porb.go +++ /dev/null @@ -1,212 +0,0 @@ -package commands - -import ( - "encoding/json" - "flag" - "fmt" - "net/http" - "os" - "strings" - "time" - - "github.com/Fluffy-Bean/lynxie/app" - "github.com/Fluffy-Bean/lynxie/utils" - "github.com/bwmarrin/discordgo" -) - -func RegisterPorbCommands(a *app.App) { - a.RegisterCommand("e621", registerE621(a)) -} - -func registerE621(a *app.App) app.Callback { - username := os.Getenv("E621_USERNAME") - password := os.Getenv("E621_PASSWORD") - - client := http.Client{ - Timeout: 10 * time.Second, - } - - return func(h *app.Handler, args []string) app.Error { - var options struct { - tags string - order string - rating string - } - - cmd := flag.NewFlagSet("", flag.ContinueOnError) - cmd.StringVar(&options.order, "order", "random", "Search order") - cmd.StringVar(&options.rating, "rating", "e", "Search rating") - cmd.StringVar(&options.tags, "tags", "", "Search tags") - cmd.Parse(args) - - req, err := http.NewRequest( - http.MethodGet, - fmt.Sprintf( - "https://e621.net/posts.json/?limit=1&tags=order:%s+rating:%s+%s", - options.order, - options.rating, - options.tags, - ), - nil, - ) - if err != nil { - return app.Error{ - Msg: "Failed to make request", - Err: err, - } - } - - req.Header.Add("Accept", "application/json") - req.Header.Add("Content-Type", "application/json") - req.Header.Add("User-Agent", fmt.Sprintf("Lynxie/1.0 (by %s on e621)", username)) - req.SetBasicAuth(username, password) - - res, err := client.Do(req) - if err != nil { - return app.Error{ - Msg: "Failed to do request", - Err: err, - } - } - defer res.Body.Close() - - var data struct { - Posts []struct { - Id int `json:"id"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - File struct { - Width int `json:"width"` - Height int `json:"height"` - Ext string `json:"ext"` - Size int `json:"size"` - Md5 string `json:"md5"` - Url string `json:"url"` - } `json:"file"` - Preview struct { - Width int `json:"width"` - Height int `json:"height"` - Url string `json:"url"` - } `json:"preview"` - Sample struct { - Has bool `json:"has"` - Height int `json:"height"` - Width int `json:"width"` - Url string `json:"url"` - Alternates struct { - } `json:"alternates"` - } `json:"sample"` - Score struct { - Up int `json:"up"` - Down int `json:"down"` - Total int `json:"total"` - } `json:"score"` - Tags struct { - General []string `json:"general"` - Artist []string `json:"artist"` - Contributor []interface{} `json:"contributor"` - Copyright []string `json:"copyright"` - Character []interface{} `json:"character"` - Species []string `json:"species"` - Invalid []interface{} `json:"invalid"` - Meta []string `json:"meta"` - Lore []interface{} `json:"lore"` - } `json:"tags"` - LockedTags []interface{} `json:"locked_tags"` - ChangeSeq int `json:"change_seq"` - Flags struct { - Pending bool `json:"pending"` - Flagged bool `json:"flagged"` - NoteLocked bool `json:"note_locked"` - StatusLocked bool `json:"status_locked"` - RatingLocked bool `json:"rating_locked"` - Deleted bool `json:"deleted"` - } `json:"flags"` - Rating string `json:"rating"` - FavCount int `json:"fav_count"` - Sources []string `json:"sources"` - Pools []int `json:"pools"` - Relationships struct { - ParentId interface{} `json:"parent_id"` - HasChildren bool `json:"has_children"` - HasActiveChildren bool `json:"has_active_children"` - Children []interface{} `json:"children"` - } `json:"relationships"` - ApproverId interface{} `json:"approver_id"` - UploaderId int `json:"uploader_id"` - Description string `json:"description"` - CommentCount int `json:"comment_count"` - IsFavorited bool `json:"is_favorited"` - HasNotes bool `json:"has_notes"` - Duration interface{} `json:"duration"` - } `json:"posts"` - } - json.NewDecoder(res.Body).Decode(&data) - - if len(data.Posts) == 0 { - return app.Error{ - Msg: "No posts found", - Err: fmt.Errorf("no posts found"), - } - } - - var description string - if len(data.Posts[0].Description) > 0 { - description = data.Posts[0].Description - } else { - 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." - } - - h.Session.ChannelMessageSendComplex(h.Message.ChannelID, &discordgo.MessageSend{ - Embed: &discordgo.MessageEmbed{ - Title: "E621", - Description: description, - Fields: []*discordgo.MessageEmbedField{ - { - Name: "Score", - Value: fmt.Sprintf("⬆️ %d | ⬇️ %d", data.Posts[0].Score.Up, data.Posts[0].Score.Down), - }, - { - Name: "Favorites", - Value: fmt.Sprintf("%d", data.Posts[0].FavCount), - }, - { - Name: "Comments", - Value: fmt.Sprintf("%d", data.Posts[0].CommentCount), - }, - { - Name: "Source(s)", - Value: strings.Join(data.Posts[0].Sources, ", "), - Inline: false, - }, - { - Name: "Tag(s)", - Value: generalTags, - Inline: false, - }, - }, - Image: &discordgo.MessageEmbedImage{ - URL: data.Posts[0].File.Url, - }, - Footer: &discordgo.MessageEmbedFooter{ - Text: fmt.Sprintf( - "ID: %d | Created: %s", - data.Posts[0].Id, - data.Posts[0].CreatedAt.Format(time.DateTime), - ), - }, - Color: utils.ColorFromRGB(255, 255, 255), - }, - Reference: h.Reference, - }) - - return app.Error{} - } -} diff --git a/commands/porb/porb.go b/commands/porb/porb.go new file mode 100644 index 0000000..1862cc2 --- /dev/null +++ b/commands/porb/porb.go @@ -0,0 +1,145 @@ +package porb + +import ( + "encoding/json" + "flag" + "fmt" + "net/http" + "os" + "strings" + "time" + + "github.com/Fluffy-Bean/lynxie/app" + "github.com/Fluffy-Bean/lynxie/utils" + "github.com/bwmarrin/discordgo" +) + +var client = http.Client{ + Timeout: 10 * time.Second, +} +var username = os.Getenv("E621_USERNAME") +var password = os.Getenv("E621_PASSWORD") + +func RegisterPorbCommands(a *app.App) { + a.RegisterCommand("e621", registerE621(a)) +} + +func registerE621(a *app.App) app.Callback { + return func(h *app.Handler, args []string) app.Error { + var options struct { + Tags string + Order string + Rating string + } + + cmd := flag.NewFlagSet("", flag.ContinueOnError) + + cmd.StringVar(&options.Order, "order", "random", "Search order") + cmd.StringVar(&options.Rating, "rating", "e", "Search rating") + cmd.StringVar(&options.Tags, "tags", "", "Search tags") + + cmd.Parse(args) + + req, err := http.NewRequest( + http.MethodGet, + fmt.Sprintf( + "https://e621.net/posts.json/?limit=1&tags=order:%s+rating:%s+%s", + options.Order, + options.Rating, + options.Tags, + ), + nil, + ) + if err != nil { + return app.Error{ + Msg: "Failed to make request", + Err: err, + } + } + + req.Header.Add("Accept", "application/json") + req.Header.Add("Content-Type", "application/json") + req.Header.Add("User-Agent", fmt.Sprintf("Lynxie/1.0 (by %s on e621)", username)) + req.SetBasicAuth(username, password) + + res, err := client.Do(req) + if err != nil { + return app.Error{ + Msg: "Failed to do request", + Err: err, + } + } + defer res.Body.Close() + + var data struct { + Posts []post `json:"posts"` + } + json.NewDecoder(res.Body).Decode(&data) + + if len(data.Posts) == 0 { + return app.Error{ + Msg: "No posts found", + Err: fmt.Errorf("no posts found"), + } + } + + var description string + if len(data.Posts[0].Description) > 0 { + description = data.Posts[0].Description + } else { + 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." + } + + h.Session.ChannelMessageSendComplex(h.Message.ChannelID, &discordgo.MessageSend{ + Embed: &discordgo.MessageEmbed{ + Title: "E621", + Description: description, + Fields: []*discordgo.MessageEmbedField{ + { + Name: "Score", + Value: fmt.Sprintf("⬆️ %d | ⬇️ %d", data.Posts[0].Score.Up, data.Posts[0].Score.Down), + }, + { + Name: "Favorites", + Value: fmt.Sprintf("%d", data.Posts[0].FavCount), + }, + { + Name: "Comments", + Value: fmt.Sprintf("%d", data.Posts[0].CommentCount), + }, + { + Name: "Source(s)", + Value: strings.Join(data.Posts[0].Sources, ", "), + Inline: false, + }, + { + Name: "Tag(s)", + Value: generalTags, + Inline: false, + }, + }, + Image: &discordgo.MessageEmbedImage{ + URL: data.Posts[0].File.Url, + }, + Footer: &discordgo.MessageEmbedFooter{ + Text: fmt.Sprintf( + "ID: %d | Created: %s", + data.Posts[0].Id, + data.Posts[0].CreatedAt.Format(time.DateTime), + ), + }, + Color: utils.ColorFromRGB(255, 255, 255), + }, + Reference: h.Reference, + }) + + return app.Error{} + } +} diff --git a/commands/porb/types.go b/commands/porb/types.go new file mode 100644 index 0000000..eebbe3c --- /dev/null +++ b/commands/porb/types.go @@ -0,0 +1,75 @@ +package porb + +import ( + "time" +) + +type post struct { + Id int `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + File struct { + Width int `json:"width"` + Height int `json:"height"` + Ext string `json:"ext"` + Size int `json:"size"` + Md5 string `json:"md5"` + Url string `json:"url"` + } `json:"file"` + Preview struct { + Width int `json:"width"` + Height int `json:"height"` + Url string `json:"url"` + } `json:"preview"` + Sample struct { + Has bool `json:"has"` + Height int `json:"height"` + Width int `json:"width"` + Url string `json:"url"` + Alternates struct { + } `json:"alternates"` + } `json:"sample"` + Score struct { + Up int `json:"up"` + Down int `json:"down"` + Total int `json:"total"` + } `json:"score"` + Tags struct { + General []string `json:"general"` + Artist []string `json:"artist"` + Contributor []interface{} `json:"contributor"` + Copyright []string `json:"copyright"` + Character []interface{} `json:"character"` + Species []string `json:"species"` + Invalid []interface{} `json:"invalid"` + Meta []string `json:"meta"` + Lore []interface{} `json:"lore"` + } `json:"tags"` + LockedTags []interface{} `json:"locked_tags"` + ChangeSeq int `json:"change_seq"` + Flags struct { + Pending bool `json:"pending"` + Flagged bool `json:"flagged"` + NoteLocked bool `json:"note_locked"` + StatusLocked bool `json:"status_locked"` + RatingLocked bool `json:"rating_locked"` + Deleted bool `json:"deleted"` + } `json:"flags"` + Rating string `json:"rating"` + FavCount int `json:"fav_count"` + Sources []string `json:"sources"` + Pools []int `json:"pools"` + Relationships struct { + ParentId interface{} `json:"parent_id"` + HasChildren bool `json:"has_children"` + HasActiveChildren bool `json:"has_active_children"` + Children []interface{} `json:"children"` + } `json:"relationships"` + ApproverId interface{} `json:"approver_id"` + UploaderId int `json:"uploader_id"` + Description string `json:"description"` + CommentCount int `json:"comment_count"` + IsFavorited bool `json:"is_favorited"` + HasNotes bool `json:"has_notes"` + Duration interface{} `json:"duration"` +} diff --git a/commands/tinyfox.go b/commands/tinyfox/tinyfox.go similarity index 68% rename from commands/tinyfox.go rename to commands/tinyfox/tinyfox.go index fd9f172..9ecd0b1 100644 --- a/commands/tinyfox.go +++ b/commands/tinyfox/tinyfox.go @@ -1,4 +1,4 @@ -package commands +package tinyfox import ( "errors" @@ -13,44 +13,46 @@ import ( "github.com/bwmarrin/discordgo" ) +var client = http.Client{ + Timeout: 10 * time.Second, +} + func RegisterTinyfoxCommands(a *app.App) { a.RegisterCommand("animal", registerAnimal(a)) } +var animals = []string{ + "fox", "yeen", "dog", "guara", "serval", "ott", "jackal", "bleat", "woof", "chi", "puma", "skunk", "tig", "wah", + "manul", "snep", "jaguar", "badger", "chee", "racc", "bear", "capy", "bun", "marten", "caracal", "snek", + "shiba", "dook", "leo", "yote", "poss", "chee", "lynx", +} + func registerAnimal(a *app.App) app.Callback { - animals := []string{ - "fox", "yeen", "dog", "guara", "serval", "ott", "jackal", "bleat", "woof", "chi", "puma", "skunk", "tig", "wah", - "manul", "snep", "jaguar", "badger", "chee", "racc", "bear", "capy", "bun", "marten", "caracal", "snek", - "shiba", "dook", "leo", "yote", "poss", "chee", "lynx", - } - - client := http.Client{ - Timeout: 10 * time.Second, - } - return func(h *app.Handler, args []string) app.Error { var options struct { - animal string + Kind string } cmd := flag.NewFlagSet("", flag.ContinueOnError) - cmd.StringVar(&options.animal, "animal", "", "Get an image of an animal!") + + cmd.StringVar(&options.Kind, "kind", "", "Animal kind to search for") + cmd.Parse(args) - if options.animal == "" { + if options.Kind == "" { return app.Error{ Msg: "Animal name is required!", Err: errors.New("animal name is required"), } } - if !slices.Contains(animals, options.animal) { + if !slices.Contains(animals, options.Kind) { return app.Error{ - Msg: fmt.Sprintf("Animal %s is invalid", options.animal), + Msg: fmt.Sprintf("Animal %s is invalid", options.Kind), Err: errors.New("entered invalid animal name"), } } - req, err := http.NewRequest(http.MethodGet, "https://api.tinyfox.dev/img?animal="+options.animal, nil) + req, err := http.NewRequest(http.MethodGet, "https://api.tinyfox.dev/img?animal="+options.Kind, nil) if err != nil { return app.Error{ Msg: "Failed to make request", diff --git a/main.go b/main.go index 4e207ae..2a5a681 100644 --- a/main.go +++ b/main.go @@ -4,7 +4,9 @@ import ( "os" "github.com/Fluffy-Bean/lynxie/app" - "github.com/Fluffy-Bean/lynxie/commands" + "github.com/Fluffy-Bean/lynxie/commands/debug" + "github.com/Fluffy-Bean/lynxie/commands/porb" + "github.com/Fluffy-Bean/lynxie/commands/tinyfox" "github.com/bwmarrin/discordgo" ) @@ -15,9 +17,9 @@ func main() { Intents: discordgo.IntentsGuildMessages, }) - commands.RegisterMetaCommands(a) - commands.RegisterTinyfoxCommands(a) - commands.RegisterPorbCommands(a) + debug.RegisterDebugCommands(a) + tinyfox.RegisterTinyfoxCommands(a) + porb.RegisterPorbCommands(a) a.Run() }