diff --git a/cmd/nourybot/command.go b/cmd/nourybot/command.go index ad61930..e49680c 100644 --- a/cmd/nourybot/command.go +++ b/cmd/nourybot/command.go @@ -304,3 +304,57 @@ func (app *application) ListCommands() string { return reply } + +// InitialTimers is called on startup and queries the database for a list of +// timers and then adds each onto the scheduler. +func (app *application) ListChannelCommands(channel string) string { + command, err := app.Models.Commands.GetAllChannel(channel) + if err != nil { + app.Log.Errorw("Error trying to retrieve all timers from database", err) + return "" + } + + // The slice of timers is only used to log them at + // the start so it looks a bit nicer. + var cs []string + + // Iterate over all timers and then add them onto the scheduler. + for i, v := range command { + // idk why this works but it does so no touchy touchy. + // https://github.com/robfig/cron/issues/420#issuecomment-940949195 + i, v := i, v + _ = i + var c string + + if v.Category == "ascii" { + c = fmt.Sprintf( + "Name: \t%v\n"+ + "Help: \t%v\n"+ + "Level: \t%v\n"+ + "\n", + v.Name, v.Help, v.Level, + ) + } else { + c = fmt.Sprintf( + "Name: \t%v\n"+ + "Help: \t%v\n"+ + "Level: \t%v\n"+ + "Text: \t%v\n"+ + "\n", + v.Name, v.Help, v.Level, v.Text, + ) + } + + // Add new value to the slice + cs = append(cs, c) + + } + + reply, err := app.uploadPaste(strings.Join(cs, "")) + if err != nil { + app.Log.Errorw("Error trying to retrieve all timers from database", err) + return "" + } + + return reply +} diff --git a/cmd/nourybot/commands.go b/cmd/nourybot/commands.go index 7c4dd22..789b52b 100644 --- a/cmd/nourybot/commands.go +++ b/cmd/nourybot/commands.go @@ -193,6 +193,8 @@ func (app *application) handleCommand(message twitch.PrivateMessage) { case "uid": reply = ivr.IDByUsername(cmdParams[1]) + case "commands": + reply = app.ListChannelCommands(message.Channel) case "set": switch cmdParams[1] { case "lastfm": diff --git a/cmd/nourybot/wolframalpha.go b/cmd/nourybot/wolframalpha.go deleted file mode 100644 index 876d73b..0000000 --- a/cmd/nourybot/wolframalpha.go +++ /dev/null @@ -1,29 +0,0 @@ -package main - -import ( - "fmt" - "io" - "net/http" - "net/url" -) - -func (app *application) WolframAlphaQuery(query string) string { - escaped := url.QueryEscape(query) - url := fmt.Sprintf("http://api.wolframalpha.com/v1/result?appid=%s&i=%s", app.Config.wolframAlphaAppID, escaped) - - resp, err := http.Get(url) - if err != nil { - return "" - } - - defer resp.Body.Close() - - body, err := io.ReadAll(resp.Body) - if err != nil { - return "" - } - - reply := string(body) - return reply - -} diff --git a/internal/data/commands.go b/internal/data/commands.go index aab4a7d..58dae1d 100644 --- a/internal/data/commands.go +++ b/internal/data/commands.go @@ -262,3 +262,60 @@ func (c CommandModel) GetAll() ([]*Command, error) { return commands, nil } + +// GetAll() returns a pointer to a slice of all channels (`[]*Channel`) in the database. +func (c CommandModel) GetAllChannel(channel string) ([]*Command, error) { + query := ` + SELECT id, name, channel, text, category, level, help + FROM commands + WHERE channel = $1 + ORDER BY name` + + // Create a context with 3 seconds timeout. + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + // Use QueryContext() the context and query. This returns a + // sql.Rows resultset containing our channels. + rows, err := c.DB.QueryContext(ctx, query, channel) + if err != nil { + return nil, err + } + + // Need to defer a call to rows.Close() to ensure the resultset + // is closed before GetAll() returns. + defer rows.Close() + + // Initialize an empty slice to hold the data. + commands := []*Command{} + + // Iterate over the resultset. + for rows.Next() { + // Initialize an empty Channel struct where we put on + // a single channel value. + var command Command + + // Scan the values onto the channel struct + err := rows.Scan( + &command.ID, + &command.Name, + &command.Channel, + &command.Text, + &command.Category, + &command.Level, + &command.Help, + ) + if err != nil { + return nil, err + } + // Add the single movie struct onto the slice. + commands = append(commands, &command) + } + + // When rows.Next() finishes call rows.Err() to retrieve any errors. + if err = rows.Err(); err != nil { + return nil, err + } + + return commands, nil +} diff --git a/internal/data/models.go b/internal/data/models.go index d691a69..d73e462 100644 --- a/internal/data/models.go +++ b/internal/data/models.go @@ -39,6 +39,7 @@ type Models struct { Commands interface { Get(name, channel string) (*Command, error) GetAll() ([]*Command, error) + GetAllChannel(channel string) ([]*Command, error) Insert(command *Command) error Update(command *Command) error SetCategory(name, channel, category string) error