diff --git a/Makefile b/Makefile deleted file mode 100644 index 339839a..0000000 --- a/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -GO ?= go - -.PHONY: fmt -fmt: - $(GO) fmt ./... - -.PHONY: imp -imp: - imp -w - -.PHONY: test -test: - $(GO) test -race ./... - -.PHONY: vet -vet: - $(GO) vet ./... - -.PHONY: build -build: - $(GO) build - -.PHONY: check -check: generate imp fmt test vet build \ No newline at end of file diff --git a/config/canopeas.example.toml b/config/canopeas.example.toml index f1ff6a1..5ffd9a4 100644 --- a/config/canopeas.example.toml +++ b/config/canopeas.example.toml @@ -25,6 +25,34 @@ meme_rate = "0" # Imgur Client ID imgur_client_id = "" +# Welcome new users +[welcome] + +# Channel ID of the welcome channel +channel = "0" + +# Message to send in welcome channel +message = """\ +**Hey ${user}, welcome to The Canopy 🎉 !** + +If you are new, please read #rules and fill out an application here: https://canopymc.net/apply. + +You will need to join our creative server at `creative.canopymc.net` to be verified. + +**After** applying and joining the server, please run the `!register ` (without the brackets) command in this channel to join the Discord! +""" + +# DM to send to user +dm = """\ +**Hey ${user}, welcome to The Canopy 🎉 !** + +If you are new, please read #rules and fill out an application here: https://canopymc.net/apply. + +You will need to join our survival server at `creative.canopymc.net` to be verified. + +After doing that please run the `!register ` (without the brackets) command in the welcome channel to join the Discord! +""" + [register] # role is the role to assign to a user after registering role = "0" diff --git a/config/config.go b/config/config.go index bd0d679..865787f 100644 --- a/config/config.go +++ b/config/config.go @@ -58,6 +58,11 @@ type Config struct { Nouns []string `toml:"nouns"` MinorThings []string `toml:"minor_things"` } `toml:"compliment"` + Welcome struct { + Channel string `toml:"channel"` + Message string `toml:"message"` + DM string `toml:"dm"` + } `toml:"welcome"` } type MessageRole struct { @@ -65,6 +70,7 @@ type MessageRole struct { MessageID string `toml:"message_id"` Reactions []MessageReaction `toml:"reactions"` } + type MessageReaction struct { Emoji string `toml:"emoji"` RoleID string `toml:"role_id"` diff --git a/database/database.go b/database/database.go index 663312e..0b89520 100644 --- a/database/database.go +++ b/database/database.go @@ -19,7 +19,7 @@ type Database struct { } func Load(dbPath string) (*Database, error) { - db, err := bbolt.Open(dbPath, 0600, bbolt.DefaultOptions) + db, err := bbolt.Open(dbPath, 0o600, bbolt.DefaultOptions) if err != nil { return nil, err } diff --git a/discord/ban.go b/discord/ban.go index 5601499..8767862 100644 --- a/discord/ban.go +++ b/discord/ban.go @@ -6,7 +6,7 @@ import ( "strings" "time" - "git.canopymc.net/Etzelia/go-serverapi" + "git.jojodev.com/Minecraft/go-serverapi" ) func init() { diff --git a/discord/birb.go b/discord/birb.go index 572fb82..03be747 100644 --- a/discord/birb.go +++ b/discord/birb.go @@ -6,7 +6,7 @@ import ( "strconv" "strings" - "git.canopymc.net/Etzelia/falseknees" + "git.jojodev.com/Minecraft/canopeas/falseknees" ) func init() { diff --git a/discord/broadcast.go b/discord/broadcast.go index a6c3513..c2f9657 100644 --- a/discord/broadcast.go +++ b/discord/broadcast.go @@ -5,7 +5,7 @@ import ( "net/http" "strings" - "git.canopymc.net/Etzelia/go-serverapi" + "git.jojodev.com/Minecraft/go-serverapi" ) func init() { diff --git a/discord/dad.go b/discord/dad.go index c91c39f..e5110cd 100644 --- a/discord/dad.go +++ b/discord/dad.go @@ -6,7 +6,7 @@ import ( "io/ioutil" "net/http" - "go.jolheiser.com/beaver" + "github.com/rs/zerolog/log" ) const ( @@ -33,7 +33,7 @@ func init() { dj, err := newDadJoke() if err != nil { - beaver.Warnf("error getting new dad joke: %v", err) + log.Warn().Msgf("error getting new dad joke: %v", err) return dadJokeErr, nil } diff --git a/discord/discord.go b/discord/discord.go index 00a9527..d708858 100644 --- a/discord/discord.go +++ b/discord/discord.go @@ -2,17 +2,20 @@ package discord import ( "fmt" + "os" "strings" "time" - "git.canopymc.net/Etzelia/canopeas/config" - "git.canopymc.net/Etzelia/canopeas/database" + "github.com/rs/zerolog/log" + + "git.jojodev.com/Minecraft/go-serverapi" + + "git.jojodev.com/Minecraft/canopeas/config" + "git.jojodev.com/Minecraft/canopeas/database" - "git.canopymc.net/Etzelia/go-serverapi" "github.com/bwmarrin/discordgo" "github.com/dghubble/go-twitter/twitter" "github.com/dghubble/oauth1" - "go.jolheiser.com/beaver" ) // Register commands to this map @@ -88,7 +91,7 @@ func Bot(cfg *config.Config, db *database.Database) (*discordgo.Session, error) Echo(cfg) for _, c := range commands { if c.name == "" { - beaver.Errorf("command is missing a name: %s", c.help) + log.Error().Msgf("command is missing a name: %s", c.help) continue } commandMap[c.name] = c @@ -98,6 +101,7 @@ func Bot(cfg *config.Config, db *database.Database) (*discordgo.Session, error) } bot.AddHandler(readyHandler()) + bot.AddHandler(joinHandler(cfg)) bot.AddHandler(leaveHandler(cfg)) bot.AddHandler(commandHandler(cfg, db, sapi, twitterClient)) bot.AddHandler(messageHandler(cfg, db)) @@ -119,7 +123,7 @@ func Bot(cfg *config.Config, db *database.Database) (*discordgo.Session, error) func sendTyping(s *discordgo.Session, channelID string) { if err := s.ChannelTyping(channelID); err != nil { - beaver.Errorf("could not send typing status: %v", err) + log.Error().Msgf("could not send typing status: %v", err) } } @@ -135,7 +139,7 @@ func sendMessage(s *discordgo.Session, channelID, content string, scrub bool) *d msg, err = s.ChannelMessageSend(channelID, content) } if err != nil { - beaver.Errorf("could not send message: %v", err) + log.Error().Msgf("could not send message: %v", err) return nil } return msg @@ -145,7 +149,7 @@ func sendEmbed(s *discordgo.Session, channelID string, embed *discordgo.MessageE embed.Color = embedColor msg, err := s.ChannelMessageSendEmbed(channelID, embed) if err != nil { - beaver.Errorf("could not send embed: %v", err) + log.Error().Msgf("could not send embed: %v", err) return nil } return msg @@ -164,7 +168,7 @@ func isStaff(authorRoleIDs, staffRoleIDs []string) bool { func readyHandler() func(s *discordgo.Session, m *discordgo.Ready) { return func(s *discordgo.Session, r *discordgo.Ready) { - beaver.Infof("https://discord.com/api/oauth2/authorize?client_id=%s&permissions=0&redirect_uri=https://birbmc.com&scope=bot", r.User.ID) + log.Info().Msgf("https://discord.com/api/oauth2/authorize?client_id=%s&permissions=0&redirect_uri=https://birbmc.com&scope=bot", r.User.ID) // Init status changer go updateStatus(s) @@ -214,13 +218,13 @@ func commandHandler(cfg *config.Config, db *database.Database, sapi *serverapi.C } if cmd.deleteInvocation { if err := s.ChannelMessageDelete(m.Message.ChannelID, m.Message.ID); err != nil { - beaver.Warnf("could not remove invocation for %s: %v", m.Content, err) + log.Warn().Msgf("could not remove invocation for %s: %v", m.Content, err) } } feedback, err := cmd.run(cmdInit) if err != nil { feedback = "Internal error" - beaver.Errorf("error while running %s: %v", cmdArg, err) + log.Error().Msgf("error while running %s: %v", cmdArg, err) } if len(feedback) > 0 { sendMessage(s, m.ChannelID, feedback, false) @@ -239,7 +243,7 @@ func messageHandler(cfg *config.Config, db *database.Database) func(s *discordgo for _, role := range m.MentionRoles { if cfg.FiredRole == role { if err := db.IncrementPing(cfg.FiredRole); err != nil { - beaver.Errorf("could not increment ping for %s: %v", cfg.FiredRole, err) + log.Error().Msgf("could not increment ping for %s: %v", cfg.FiredRole, err) } } } @@ -268,7 +272,7 @@ func reactionHandler(add bool, s *discordgo.Session, m *discordgo.MessageReactio roleCmd = s.GuildMemberRoleRemove } if err := roleCmd(m.GuildID, m.UserID, r); err != nil { - beaver.Errorf("could not modify role %s for user %s", r, m.UserID) + log.Error().Msgf("could not modify role %s for user %s", r, m.UserID) } } } @@ -285,10 +289,39 @@ func updateStatus(s *discordgo.Session) { for { dj, err := newDadJoke() if err != nil { - beaver.Warnf("could not get new dad joke: %v", err) + log.Warn().Msgf("could not get new dad joke: %v", err) } else if err := s.UpdateStatus(1, dj.Joke); err != nil { - beaver.Warnf("could not update status: %v", err) + log.Warn().Msgf("could not update status: %v", err) } <-ticker.C } } + +func joinHandler(cfg *config.Config) func(s *discordgo.Session, m *discordgo.GuildMemberAdd) { + return func(s *discordgo.Session, m *discordgo.GuildMemberAdd) { + sendMessage(s, cfg.Welcome.Channel, os.Expand(cfg.Welcome.Message, func(s string) string { + switch strings.ToLower(s) { + case "user": + return m.Mention() + default: + return s + } + }), false) + + if cfg.Welcome.DM != "" { + dm, err := s.UserChannelCreate(m.User.ID) + if err != nil { + log.Err(err).Msgf("could not create DM with %s", m.User.Username) + return + } + sendMessage(s, dm.ID, os.Expand(cfg.Welcome.DM, func(s string) string { + switch strings.ToLower(s) { + case "user": + return m.Mention() + default: + return s + } + }), false) + } + } +} diff --git a/discord/echo.go b/discord/echo.go index 439bff7..9c797c8 100644 --- a/discord/echo.go +++ b/discord/echo.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "git.canopymc.net/Etzelia/canopeas/config" + "git.jojodev.com/Minecraft/canopeas/config" "github.com/bwmarrin/discordgo" ) diff --git a/discord/history.go b/discord/history.go index fe697c1..0682eb2 100644 --- a/discord/history.go +++ b/discord/history.go @@ -5,10 +5,11 @@ import ( "strings" "time" + "github.com/rs/zerolog/log" + "gitea.com/jolheiser/gojang" "gitea.com/jolheiser/gojang/rate" "github.com/bwmarrin/discordgo" - "go.jolheiser.com/beaver" ) func init() { @@ -44,13 +45,13 @@ func init() { if rate.IsRateLimitExceededError(err) { return "Rate limited by Mojang, slow down!", nil } - beaver.Errorf("Profile: %v", err) + log.Error().Msgf("Profile: %v", err) return "Could not contact the Mojang API.", nil } names, err := client.UUIDToNameHistory(profile.UUID) if err != nil { - beaver.Errorf("UUIDToNameHistory: %v", err) + log.Error().Msgf("UUIDToNameHistory: %v", err) return "Could not contact the Mojang API.", nil } diff --git a/discord/imgur.go b/discord/imgur.go index 7705375..239088a 100644 --- a/discord/imgur.go +++ b/discord/imgur.go @@ -4,8 +4,8 @@ import ( "fmt" "strings" - "git.canopymc.net/Etzelia/canopeas/config" - "git.canopymc.net/Etzelia/canopeas/imgur" + "git.jojodev.com/Minecraft/canopeas/config" + "git.jojodev.com/Minecraft/canopeas/imgur" "github.com/bwmarrin/discordgo" ) diff --git a/discord/inspire.go b/discord/inspire.go index 8a66759..18118a7 100644 --- a/discord/inspire.go +++ b/discord/inspire.go @@ -1,6 +1,6 @@ package discord -import "git.canopymc.net/Etzelia/inspiro" +import "git.jojodev.com/Minecraft/canopeas/inspiro" func init() { commands = append(commands, &command{ diff --git a/discord/register.go b/discord/register.go index 5b3fc87..b6ecf39 100644 --- a/discord/register.go +++ b/discord/register.go @@ -7,10 +7,10 @@ import ( "path/filepath" "strings" - "git.canopymc.net/Etzelia/canopeas/config" + "git.jojodev.com/Minecraft/go-mcm" + "git.jojodev.com/Minecraft/go-mcm/model/django" - "git.canopymc.net/Etzelia/go-mcm" - "git.canopymc.net/Etzelia/go-mcm/model/django" + "git.jojodev.com/Minecraft/canopeas/config" ) const bannedPlayersFile = "banned-players.json" diff --git a/discord/tweet.go b/discord/tweet.go index 756fedd..259377e 100644 --- a/discord/tweet.go +++ b/discord/tweet.go @@ -25,7 +25,6 @@ func init() { return "", err } if resp.StatusCode%100 != 2 { - } return fmt.Sprintf("https://twitter.com/%d/status/%d", tweet.User.ID, tweet.ID), nil diff --git a/discord/unban.go b/discord/unban.go index cee5344..7f8cce6 100644 --- a/discord/unban.go +++ b/discord/unban.go @@ -6,7 +6,7 @@ import ( "strings" "time" - "git.canopymc.net/Etzelia/canopeas/database" + "git.jojodev.com/Minecraft/canopeas/database" ) func init() { diff --git a/discord/utils.go b/discord/utils.go index c599243..bfb1b07 100644 --- a/discord/utils.go +++ b/discord/utils.go @@ -5,10 +5,11 @@ import ( "net/http" "time" - "git.canopymc.net/Etzelia/canopeas/database" + "github.com/rs/zerolog/log" - "git.canopymc.net/Etzelia/go-serverapi" - "go.jolheiser.com/beaver" + "git.jojodev.com/Minecraft/go-serverapi" + + "git.jojodev.com/Minecraft/canopeas/database" ) type rateLimit struct { @@ -60,23 +61,23 @@ func (u *unbanSchedule) Run() { } func (u *unbanSchedule) check() { - beaver.Debug("Running unban schedule") + log.Debug().Msg("Running unban schedule") now := time.Now() for _, record := range u.db.ListUnbans() { if now.After(record.Expiration) { - beaver.Infof("Unbanning %s", record.Username) + log.Info().Msgf("Unbanning %s", record.Username) unban := serverapi.Unban{ Target: record.Username, } status, err := u.sapi.Unban(unban) if err != nil { - beaver.Error(err) + log.Err(err).Msg("") } if status != http.StatusOK { - beaver.Errorf("ServerAPI returned status %d when trying to ban %s", status, record.Username) + log.Error().Msgf("ServerAPI returned status %d when trying to ban %s", status, record.Username) } if err := u.db.RemoveUnban(record.Username); err != nil { - beaver.Errorf("could not remove unban for %s in database", record.Username) + log.Error().Msgf("could not remove unban for %s in database", record.Username) } } } diff --git a/falseknees/client.go b/falseknees/client.go new file mode 100644 index 0000000..b4545af --- /dev/null +++ b/falseknees/client.go @@ -0,0 +1,29 @@ +package falseknees + +import "net/http" + +// Client is a FalseKnees client +type Client struct { + http *http.Client +} + +// New returns a new Client +func New(opts ...ClientOption) *Client { + c := &Client{ + http: http.DefaultClient, + } + for _, opt := range opts { + opt(c) + } + return c +} + +// ClientOption is options for a Client +type ClientOption func(*Client) + +// WithHTTP is a ClientOption for using a different http.Client +func WithHTTP(client *http.Client) ClientOption { + return func(c *Client) { + c.http = client + } +} diff --git a/falseknees/falseknees.go b/falseknees/falseknees.go new file mode 100644 index 0000000..59b0e84 --- /dev/null +++ b/falseknees/falseknees.go @@ -0,0 +1,130 @@ +package falseknees + +import ( + "context" + "errors" + "fmt" + "io/ioutil" + "math/rand" + "net/http" + "regexp" + "strconv" + "time" +) + +var ( + updateInterval = time.Minute * 30 + baseURL = "https://www.falseknees.com/" + currentRe = regexp.MustCompile(`window\.location\.href.+"(.+)\.html"`) + imageRe = regexp.MustCompile(`src="(imgs.+\.png)".+title="(.+)"`) + + current int + lastUpdate time.Time +) + +// Comic is a FalseKnees comic +type Comic struct { + Num int + Title string + Img string +} + +// Comic returns a specific Comic +func (c *Client) Comic(ctx context.Context, num int) (*Comic, error) { + return c.comic(ctx, num) +} + +// Current returns the current Comic +func (c *Client) Current(ctx context.Context) (*Comic, error) { + if err := c.updateCurrent(ctx); err != nil { + return nil, err + } + return c.Comic(ctx, current) +} + +// Random returns a random Comic +func (c *Client) Random(ctx context.Context) (*Comic, error) { + if err := c.updateCurrent(ctx); err != nil { + return nil, err + } + rand.Seed(time.Now().UnixNano()) + return c.Comic(ctx, rand.Intn(current)+1) +} + +func (c *Client) updateCurrent(ctx context.Context) error { + now := time.Now() + if !lastUpdate.IsZero() && lastUpdate.After(now.Add(-updateInterval)) { + return nil + } + lastUpdate = now + + u := fmt.Sprintf("%sindex.html", baseURL) + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil) + if err != nil { + return err + } + + resp, err := c.http.Do(req) + if err != nil { + return err + } + + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("could not get page for index: %s", resp.Status) + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + defer resp.Body.Close() + + match := currentRe.FindStringSubmatch(string(body)) + if len(match) == 0 { + return errors.New("could not find current comic") + } + + curr, err := strconv.Atoi(match[1]) + if err != nil { + return err + } + + current = curr + return nil +} + +func (c *Client) comic(ctx context.Context, num int) (*Comic, error) { + u := fmt.Sprintf("%s%d.html", baseURL, num) + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil) + if err != nil { + return nil, err + } + + resp, err := c.http.Do(req) + if err != nil { + return nil, err + } + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("could not get page for comic %d: %s", num, resp.Status) + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + match := imageRe.FindStringSubmatch(string(body)) + if len(match) == 0 { + return nil, fmt.Errorf("could not find comic #%d", num) + } + + return &Comic{ + Num: num, + Title: match[2], + Img: fmt.Sprintf("%s%s", baseURL, match[1]), + }, nil +} diff --git a/falseknees/falseknees_test.go b/falseknees/falseknees_test.go new file mode 100644 index 0000000..2e01d41 --- /dev/null +++ b/falseknees/falseknees_test.go @@ -0,0 +1,483 @@ +package falseknees + +import ( + "context" + "fmt" + "net/http" + "net/http/httptest" + "os" + "testing" +) + +var ( + server *httptest.Server + client *Client +) + +func TestMain(m *testing.M) { + handler := func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/index.html" { + _, _ = w.Write(indexHTML) + return + } + if r.URL.Path == "/389.html" { + _, _ = w.Write(currentHTML) + return + } + if r.URL.Path == "/252.html" { + _, _ = w.Write(bunnyHTML) + return + } + w.WriteHeader(http.StatusNotFound) + } + + server = httptest.NewServer(http.HandlerFunc(handler)) + baseURL = server.URL + "/" + currentComic.Img = fmt.Sprintf("%simgs/389.png", baseURL) + bunnyComic.Img = fmt.Sprintf("%simgs/252.png", baseURL) + client = New() + + os.Exit(m.Run()) +} + +func TestCurrent(t *testing.T) { + t.Parallel() + + comic, err := client.Current(context.Background()) + if err != nil { + t.Logf("could not get current comic: %v\n", err) + t.FailNow() + } + + if *comic != currentComic { + t.Log("comic does not match test data") + t.FailNow() + } +} + +func TestComic(t *testing.T) { + t.Parallel() + + comic, err := client.Comic(context.Background(), 252) + if err != nil { + t.Logf("could not get comic 252: %v\n", err) + t.FailNow() + } + + if *comic != bunnyComic { + t.Log("comic does not match test data") + t.FailNow() + } +} + +var ( + currentComic = Comic{ + Num: 389, + Title: "that's the good stuff", + } + bunnyComic = Comic{ + Num: 252, + Title: "Spring is the fucking greatest shit", + } + + indexHTML = []byte(` + + + + + + + + + + + + + + + + + + + + + + Page Redirection + + + + + + +
+ + + + + + + +
+
+ +
+
+ + +
+

+ + + + + + + + + + +
About + Store + + About +
+

+
+ + +
+ +
+ + + +
+
+ + +
+

+ + + + + + + + +
First + Previous + Archive + Next + Last +
+

+
+ + + + + + + + + + + + + + + +
+

False Knees © 2013-whenever Joshua Barkman

+
+ + +`) + + currentHTML = []byte(` + + + + + + + + + + + + + + + + + False Knees + + + + + +
+ + + + + + + +
+ +
+ + +
+

+ + + + + + + + + + +
AboutStoreAbout

+
+ + +
+ +
+ + + +
+
+ + +
+

+ + + + + + + + +
FirstPreviousArchiveNextLast

+
+ + + + + + + + + + + + + + + +
+

False Knees © 2013-whenever Joshua Barkman

+
+ + +`) + + bunnyHTML = []byte(` + + + + + + + + + + + + + + + + + False Knees + + + + + +
+ + + + + + + +
+ +
+ + +
+

+ + + + + + + + + + +
AboutStoreAbout

+
+ + +
+ +
+ + + +
+
+ + +
+

+ + + + + + + + +
FirstPreviousArchiveNextLast

+
+ + + + + + + + + + + + + + + +
+

False Knees © 2013-whenever Joshua Barkman

+
+ + +`) +) diff --git a/go.mod b/go.mod index 2e0b0b8..1240496 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,10 @@ -module git.canopymc.net/Etzelia/canopeas +module git.jojodev.com/Minecraft/canopeas go 1.16 require ( - git.canopymc.net/Etzelia/falseknees v0.0.0-20210713232726-7325698e2451 - git.canopymc.net/Etzelia/go-mcm v0.0.0-20210713232816-d2b27d7edff0 - git.canopymc.net/Etzelia/go-serverapi v0.0.0-20210713233104-94e800dbb304 - git.canopymc.net/Etzelia/inspiro v0.0.3-0.20210713233035-ffd88077147f + git.jojodev.com/Minecraft/go-mcm v0.0.1 + git.jojodev.com/Minecraft/go-serverapi v0.0.1 gitea.com/jolheiser/gojang v0.0.7 gitea.com/jolheiser/xkcd v0.0.2 github.com/bwmarrin/discordgo v0.22.0 @@ -14,8 +12,6 @@ require ( github.com/dghubble/oauth1 v0.7.0 github.com/gorilla/websocket v1.4.2 // indirect github.com/pelletier/go-toml v1.8.1 + github.com/rs/zerolog v1.26.1 go.etcd.io/bbolt v1.3.4 - go.jolheiser.com/beaver v1.0.2 - golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 // indirect - golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5 // indirect ) diff --git a/go.sum b/go.sum index 8b1ea55..5dd3627 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,7 @@ -git.canopymc.net/Etzelia/falseknees v0.0.0-20210713232726-7325698e2451 h1:EbxWDS7sOyxv8einE7ps8WsywvlFqyKp3vdvk4PYVw4= -git.canopymc.net/Etzelia/falseknees v0.0.0-20210713232726-7325698e2451/go.mod h1:bgGHtcoYFmNIFgcU4P2LwqANZsJxoygnLI0C6OWE/U4= -git.canopymc.net/Etzelia/go-mcm v0.0.0-20210713232816-d2b27d7edff0 h1:UrwR0Ap4sjoRDfbi/ow76OeBAR9pI+BFKMYU6Jj9EtU= -git.canopymc.net/Etzelia/go-mcm v0.0.0-20210713232816-d2b27d7edff0/go.mod h1:M9yjY5mBSK5vGVPru7RG6K5bUfoRH7dTtyQ+MCuJ33g= -git.canopymc.net/Etzelia/go-serverapi v0.0.0-20210713233104-94e800dbb304 h1:gBzoEToJCO1nKbfhfzhGMgSWY6szwDbA8doVmPr3SIY= -git.canopymc.net/Etzelia/go-serverapi v0.0.0-20210713233104-94e800dbb304/go.mod h1:U0H8WgtAzR+L+65odnpUH1lT6z7ylcG6R9keOOTG+fk= -git.canopymc.net/Etzelia/inspiro v0.0.3-0.20210713233035-ffd88077147f h1:CupD+6/4Vrx0fGDIFf+cu8ponr19or3bCzkPPQXmRJk= -git.canopymc.net/Etzelia/inspiro v0.0.3-0.20210713233035-ffd88077147f/go.mod h1:7zYT6obYO7/a3v+gV+uNfNlWK1dJz6Mz7lY9FeRSGOU= +git.jojodev.com/Minecraft/go-mcm v0.0.1 h1:3nfjCz3wA4l44QWYMRC7DLwU4GneWC5e1CRub7Tt1S0= +git.jojodev.com/Minecraft/go-mcm v0.0.1/go.mod h1:0VAA1b5ZgM1leeYOqMhBnEfdonZccdMdeQrsF+50s04= +git.jojodev.com/Minecraft/go-serverapi v0.0.1 h1:sn594cScthq0W/ntLVhWfMfNcPXG9IyyqMatcEjcYIQ= +git.jojodev.com/Minecraft/go-serverapi v0.0.1/go.mod h1:a3e4OnMNJnd2OzwRG62Fe/k70SelNDoAxYW9SYmkDf4= gitea.com/jolheiser/gojang v0.0.7 h1:Q4cG7QYiKQsJtUWgXXiolAH9DCLRoaQ4olaO9OV628U= gitea.com/jolheiser/gojang v0.0.7/go.mod h1:r9kj2wv/21Da7VpWz+qmxLexH85o2BAM4NMxeYgQlcY= gitea.com/jolheiser/xkcd v0.0.2 h1:HJP83YwSKxSYcoNfpb1ZpAfBvkUAnN+YgeukraXtfrc= @@ -14,6 +10,7 @@ github.com/bwmarrin/discordgo v0.22.0 h1:uBxY1HmlVCsW1IuaPjpCGT6A2DBwRn0nvOguQIx github.com/bwmarrin/discordgo v0.22.0/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M= github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -23,6 +20,7 @@ github.com/dghubble/oauth1 v0.7.0 h1:AlpZdbRiJM4XGHIlQ8BuJ/wlpGwFEJNnB4Mc+78tA/w github.com/dghubble/oauth1 v0.7.0/go.mod h1:8pFdfPkv/jr8mkChVbNVuJ0suiHe278BtWI4Tk1ujxk= github.com/dghubble/sling v1.3.0 h1:pZHjCJq4zJvc6qVQ5wN1jo5oNZlNE0+8T/h0XeXBUKU= github.com/dghubble/sling v1.3.0/go.mod h1:XXShWaBWKzNLhu2OxikSNFrlsvowtz4kyRuXUG7oQKY= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -30,26 +28,46 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc= +github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg= go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= -go.jolheiser.com/beaver v1.0.2 h1:KA2D6iO8MQhZi1nZYi/Chak/f1Cxfrs6b1XO623+Khk= -go.jolheiser.com/beaver v1.0.2/go.mod h1:7X4F5+XOGSC3LejTShoBdqtRCnPWcnRgmYGmG3EKW8g= go.jolheiser.com/gql v0.0.1 h1:y3LGHcJUZI9otTCcMn8TVdF3aEzNX0FW6m0YUamlLto= go.jolheiser.com/gql v0.0.1/go.mod h1:74eYqVRIxsOFxtVl0RYGKNyYQgJYQaxOCgar7LP71Hw= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E= -golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e h1:1SzTfNOXwIS2oWiMF+6qu0OUDKb0dauo6MoDUQyu+yU= +golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5 h1:iCaAy5bMeEvwANu3YnJfWwI0kWAGkEa2RXPdweI/ysk= -golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/imgur/imgur.go b/imgur/imgur.go index 0b2e680..e948f3a 100644 --- a/imgur/imgur.go +++ b/imgur/imgur.go @@ -30,7 +30,6 @@ type Image struct { } func Get(clientID, albumID string) ([]*Image, error) { - req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("https://api.imgur.com/3/album/%s/images", albumID), nil) if err != nil { return nil, err diff --git a/inspiro/inspiro.go b/inspiro/inspiro.go new file mode 100644 index 0000000..c9da520 --- /dev/null +++ b/inspiro/inspiro.go @@ -0,0 +1,23 @@ +package inspiro + +import ( + "io/ioutil" + "net/http" +) + +const api = "https://inspirobot.me/api?generate=true" + +func Generate() (string, error) { + resp, err := http.Get(api) + if err != nil { + return "", err + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + defer resp.Body.Close() + + return string(body), nil +} diff --git a/inspiro/inspiro_test.go b/inspiro/inspiro_test.go new file mode 100644 index 0000000..a8fe21d --- /dev/null +++ b/inspiro/inspiro_test.go @@ -0,0 +1,17 @@ +package inspiro + +import ( + "os" + "testing" +) + +func TestMain(m *testing.M) { + os.Exit(m.Run()) +} + +func TestGenerate(t *testing.T) { + if _, err := Generate(); err != nil { + t.Logf("could not generate image: %v", err) + t.Fail() + } +} diff --git a/main.go b/main.go index 295fe0c..b0acafa 100644 --- a/main.go +++ b/main.go @@ -6,54 +6,49 @@ import ( "os/signal" "syscall" - "git.canopymc.net/Etzelia/canopeas/config" - "git.canopymc.net/Etzelia/canopeas/database" - "git.canopymc.net/Etzelia/canopeas/discord" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" - "go.jolheiser.com/beaver" + "git.jojodev.com/Minecraft/canopeas/config" + "git.jojodev.com/Minecraft/canopeas/database" + "git.jojodev.com/Minecraft/canopeas/discord" ) var configFlag string func main() { + log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) + flag.StringVar(&configFlag, "config", "canopeas.toml", "Set config path") flag.Parse() - beaver.Console.Format = beaver.FormatOptions{ - TimePrefix: true, - StackPrefix: true, - StackLimit: 15, - LevelPrefix: true, - LevelColor: true, - } - cfg, err := config.Load(configFlag) if err != nil { - beaver.Fatalf("could not load config: %v", err) + log.Fatal().Msgf("could not load config: %v", err) } db, err := database.Load(cfg.DBPath) if err != nil { - beaver.Fatalf("could not load database: %v", err) + log.Fatal().Msgf("could not load database: %v", err) } bot, err := discord.Bot(cfg, db) if err != nil { - beaver.Fatalf("could not start Discord bot: %v", err) + log.Fatal().Msgf("could not start Discord bot: %v", err) } go func() { if err := bot.Open(); err != nil { - beaver.Errorf("error running Discord bot: %v", err) + log.Error().Msgf("error running Discord bot: %v", err) } }() - beaver.Info("Bot is now running. Press CTRL-C to exit.") + log.Info().Msg("Bot is now running. Press CTRL-C to exit.") sc := make(chan os.Signal, 1) signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill) <-sc if err := bot.Close(); err != nil { - beaver.Errorf("error closing Discord bot: %v", err) + log.Error().Msgf("error closing Discord bot: %v", err) } }