diff --git a/pkg/bot/bot.go b/pkg/bot/bot.go index 70a0f18..57669a1 100644 --- a/pkg/bot/bot.go +++ b/pkg/bot/bot.go @@ -114,6 +114,7 @@ func (bot *MusicBot) registerCommands() { bot.registerCommand(playCommand) bot.registerCommand(currentCommand) bot.registerCommand(queueCommand) + bot.registerCommand(queueDeleteCommand) bot.registerCommand(flushCommand) bot.registerCommand(shuffleCommand) bot.registerCommand(whiteListCommand) diff --git a/pkg/bot/commands.go b/pkg/bot/commands.go index 474d28b..fe991ef 100644 --- a/pkg/bot/commands.go +++ b/pkg/bot/commands.go @@ -222,6 +222,32 @@ var queueCommand = Command{ }, } +var queueDeleteCommand = Command{ + Name: "queue-delete", + Function: func(bot *MusicBot, message Message) { + words := strings.Fields(message.Message) + // !music queue-delete # + if len(words) <= 2 { + bot.ReplyToMessage(message, "No queue item provided") + return + } + + queueItem, err := strconv.Atoi(words[2]) + if err != nil { + bot.ReplyToMessage(message, "Invalid queue-item provided") + return + } + + queue := bot.GetMusicPlayer().GetQueue() + if err = queue.Delete(queueItem); err != nil { + bot.ReplyToMessage(message, fmt.Sprintf("Could not delete queue-item: %s", err)) + return + } + + bot.ReplyToMessage(message, fmt.Sprintf("queue-item %d deleted", queueItem)) + }, +} + var flushCommand = Command{ Name: "flush", Function: func(bot *MusicBot, message Message) { diff --git a/pkg/music/queue.go b/pkg/music/queue.go index addc6e9..ec2ed2d 100644 --- a/pkg/music/queue.go +++ b/pkg/music/queue.go @@ -1,6 +1,7 @@ package music import ( + "fmt" "log" "math/rand" "sync" @@ -11,7 +12,8 @@ import ( ) const ( - songAdded eventemitter.EventType = "song-added" + songAdded eventemitter.EventType = "song-added" + songDeleted eventemitter.EventType = "song-deleted" ) var ( @@ -35,6 +37,25 @@ func (queue *Queue) Append(songs ...Song) { queue.EmitEvent(songAdded) } +func (queue *Queue) Delete(item int) error { + queue.lock.Lock() + defer queue.lock.Unlock() + + if item < 1 { + return fmt.Errorf("can not remove negative queue item %d", item) + } + + if len(queue.songs)+1 < item { + return fmt.Errorf("queue-item %d is not in queue", item) + } + + queue.songs = append(queue.songs[:item-1], queue.songs[item:]...) + log.Println("Song deleted from the queue") + queue.EmitEvent(songDeleted) + + return nil +} + // GetNext returns the next item in the queue if it exists func (queue *Queue) GetNext() (Song, error) { queue.lock.Lock() diff --git a/pkg/music/queue_test.go b/pkg/music/queue_test.go index 86768ce..be2afd6 100644 --- a/pkg/music/queue_test.go +++ b/pkg/music/queue_test.go @@ -35,6 +35,60 @@ func TestQueue_Append(t *testing.T) { assert.Equal(t, queue.songs[0], song) } +func TestQueue_Delete(t *testing.T) { + t.Run("delete valid item", func(t *testing.T) { + t.Parallel() + + // fill new queue + queue := NewQueue() + + song1 := Song{Name: "banaan1"} + song2 := Song{Name: "banaan2"} + song3 := Song{Name: "banaan3"} + + queue.Append(song1) + queue.Append(song2) + queue.Append(song3) + + // remove middle queue song + err := queue.Delete(2) + if !assert.NoError(t, err) { + return + } + + assert.Equal(t, 2, len(queue.songs)) + assert.Equal(t, song1.Name, queue.songs[0].Name) + assert.Equal(t, song3.Name, queue.songs[1].Name) + }) + + t.Run("delete negative item", func(t *testing.T) { + t.Parallel() + + queue := NewQueue() + err := queue.Delete(-1) + + if assert.Error(t, err) { + assert.Equal(t, "can not remove negative queue item -1", err.Error()) + } + }) + + t.Run("delete nonexisting item", func(t *testing.T) { + t.Parallel() + + // fill new queue + queue := NewQueue() + queue.Append(Song{Name: "banaan1"}) + queue.Append(Song{Name: "banaan2"}) + queue.Append(Song{Name: "banaan3"}) + + err := queue.Delete(6) + + if assert.Error(t, err) { + assert.Equal(t, "queue-item 6 is not in queue", err.Error()) + } + }) +} + func TestQueue_Flush(t *testing.T) { t.Parallel() queue := NewQueue()