From 08d57ba9d99997fa44a01b4d11bbfb1382ca077d Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 17 Dec 2023 20:11:02 +0100 Subject: [PATCH] add route for showing all channel timer --- cmd/nourybot/commands.go | 4 +++ cmd/nourybot/router.go | 38 +++++++++++++++++++++++++ cmd/nourybot/timer.go | 41 +++++++++++++++++++++++++++ internal/data/models.go | 1 + internal/data/timers.go | 60 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 144 insertions(+) diff --git a/cmd/nourybot/commands.go b/cmd/nourybot/commands.go index 789b52b..7ac9dc1 100644 --- a/cmd/nourybot/commands.go +++ b/cmd/nourybot/commands.go @@ -195,6 +195,10 @@ func (app *application) handleCommand(message twitch.PrivateMessage) { case "commands": reply = app.ListChannelCommands(message.Channel) + + case "timers": + reply = app.ListChannelTimer(message.Channel) + case "set": switch cmdParams[1] { case "lastfm": diff --git a/cmd/nourybot/router.go b/cmd/nourybot/router.go index 17cf559..ddfd508 100644 --- a/cmd/nourybot/router.go +++ b/cmd/nourybot/router.go @@ -13,6 +13,7 @@ func (app *application) startRouter() { router := httprouter.New() router.GET("/status", app.statusPageRoute) router.GET("/commands/:channel", app.channelCommandsRoute) + router.GET("/timer/:channel", app.channelTimersRoute) app.Log.Fatal(http.ListenAndServe(":8080", router)) } @@ -66,6 +67,43 @@ func (app *application) channelCommandsRoute(w http.ResponseWriter, r *http.Requ } +func (app *application) channelTimersRoute(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + channel := ps.ByName("channel") + var ts []string + var text string + + timer, err := app.Models.Timers.GetChannelTimer(channel) + if err != nil { + app.Log.Errorw("Error trying to retrieve all timer for a channel from database", err) + return + } + // The slice of timers is only used to log them at + // the start so it looks a bit nicer. + + // Iterate over all timers and then add them onto the scheduler. + for i, v := range timer { + // 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 t string + + t = fmt.Sprintf( + "Name: \t%v\n"+ + "Text: \t%v\n"+ + "Repeat: %v\n"+ + "\n", + v.Name, v.Text, v.Repeat, + ) + + // Add new value to the slice + ts = append(ts, t) + } + + text = strings.Join(ts, "") + fmt.Fprintf(w, fmt.Sprint(text)) +} + func (app *application) statusPageRoute(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { commit := common.GetVersion() started := common.GetUptime().Format("2006-1-2 15:4:5") diff --git a/cmd/nourybot/timer.go b/cmd/nourybot/timer.go index 2d5d610..facc72f 100644 --- a/cmd/nourybot/timer.go +++ b/cmd/nourybot/timer.go @@ -353,3 +353,44 @@ func (app *application) DeleteTimer(name string, message twitch.PrivateMessage) reply := fmt.Sprintf("Deleted timer with name %s", name) app.Send(message.Channel, reply, message) } + +func (app *application) ListChannelTimer(channel string) string { + timer, err := app.Models.Timers.GetChannelTimer(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 ts []string + + // Iterate over all timers and then add them onto the scheduler. + for i, v := range timer { + // 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 t string + + t = fmt.Sprintf( + "Name: \t%v\n"+ + "Text: \t%v\n"+ + "Repeat: \t%v\n"+ + "\n", + v.Name, v.Text, v.Repeat, + ) + + // Add new value to the slice + ts = append(ts, t) + + } + + reply, err := app.uploadPaste(strings.Join(ts, "")) + if err != nil { + app.Log.Errorw("Error trying to retrieve all timers from database", err) + return "" + } + + return reply +} diff --git a/internal/data/models.go b/internal/data/models.go index d73e462..0f3114b 100644 --- a/internal/data/models.go +++ b/internal/data/models.go @@ -53,6 +53,7 @@ type Models struct { Insert(timer *Timer) error Update(timer *Timer) error GetAll() ([]*Timer, error) + GetChannelTimer(channel string) ([]*Timer, error) Delete(name string) error } Uploads interface { diff --git a/internal/data/timers.go b/internal/data/timers.go index 63830ff..90c263f 100644 --- a/internal/data/timers.go +++ b/internal/data/timers.go @@ -160,6 +160,66 @@ func (t TimerModel) GetAll() ([]*Timer, error) { return timers, nil } +// GetAll() returns a pointer to a slice of all channels (`[]*Channel`) in the database. +func (t TimerModel) GetChannelTimer(channel string) ([]*Timer, error) { + query := ` + SELECT id, name, identifier, text, channel, repeat + FROM timers + 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 := t.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. + timers := []*Timer{} + + // Iterate over the resultset. + for rows.Next() { + // Initialize an empty Channel struct where we put on + // a single channel value. + var timer Timer + + err := rows.Scan( + &timer.ID, + &timer.Name, + &timer.Identifier, + &timer.Text, + &timer.Channel, + &timer.Repeat, + ) + if err != nil { + switch { + case errors.Is(err, sql.ErrNoRows): + return nil, ErrRecordNotFound + default: + return nil, err + } + } + // Add the single movie struct onto the slice. + timers = append(timers, &timer) + } + + // When rows.Next() finishes call rows.Err() to retrieve any errors. + if err = rows.Err(); err != nil { + return nil, err + } + + return timers, nil +} + func (t TimerModel) Update(timer *Timer) error { query := ` UPDATE timers