diff --git a/Makefile b/Makefile index b642d08..5de2412 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ mumbledj: main.go commands.go parseconfig.go strings.go service.go service_youtu go get github.com/nitrous-io/goop rm -rf Goopfile.lock goop install - goop go build . + goop go build clean: rm -f mumbledj* @@ -17,4 +17,4 @@ install: if [ -d ~/bin ]; then cp -f mumbledj* ~/bin/mumbledj; else sudo cp -f mumbledj* /usr/local/bin/mumbledj; fi; build: - goop go build . + goop go build diff --git a/commands.go b/commands.go index 7f16d09..3b5d928 100644 --- a/commands.go +++ b/commands.go @@ -238,23 +238,23 @@ func add(user *gumble.User, username, url string) { func skip(user *gumble.User, username string, admin, playlistSkip bool) { if dj.audioStream.IsPlaying() { if playlistSkip { - if dj.queue.CurrentSong().playlist != nil { - if err := dj.queue.CurrentSong().playlist.AddSkip(username); err == nil { + if dj.queue.CurrentSong().Playlist() != nil { + if err := dj.queue.CurrentSong().Playlist().AddSkip(username); err == nil { submitterSkipped := false if admin { dj.client.Self.Channel.Send(ADMIN_PLAYLIST_SKIP_MSG, false) - } else if dj.queue.CurrentSong().submitter == username { + } else if dj.queue.CurrentSong().Submitter() == username { dj.client.Self.Channel.Send(fmt.Sprintf(PLAYLIST_SUBMITTER_SKIP_HTML, username), false) submitterSkipped = true } else { dj.client.Self.Channel.Send(fmt.Sprintf(PLAYLIST_SKIP_ADDED_HTML, username), false) } - if submitterSkipped || dj.queue.CurrentSong().playlist.SkipReached(len(dj.client.Self.Channel.Users)) || admin { - id := dj.queue.CurrentSong().playlist.id - dj.queue.CurrentSong().playlist.DeleteSkippers() + if submitterSkipped || dj.queue.CurrentSong().Playlist().SkipReached(len(dj.client.Self.Channel.Users)) || admin { + id := dj.queue.CurrentSong().Playlist().ID() + dj.queue.CurrentSong().Playlist().DeleteSkippers() for i := 0; i < len(dj.queue.queue); i++ { - if dj.queue.queue[i].playlist != nil { - if dj.queue.queue[i].playlist.id == id { + if dj.queue.queue[i].Playlist() != nil { + if dj.queue.queue[i].Playlist().ID() == id { dj.queue.queue = append(dj.queue.queue[:i], dj.queue.queue[i+1:]...) i-- } @@ -262,7 +262,7 @@ func skip(user *gumble.User, username string, admin, playlistSkip bool) { } if dj.queue.Len() != 0 { // Set dontSkip to true to avoid audioStream.Stop() callback skipping the new first song. - dj.queue.CurrentSong().dontSkip = true + dj.queue.CurrentSong().SetDontSkip(true) } if !(submitterSkipped || admin) { dj.client.Self.Channel.Send(PLAYLIST_SKIPPED_HTML, false) @@ -280,7 +280,7 @@ func skip(user *gumble.User, username string, admin, playlistSkip bool) { submitterSkipped := false if admin { dj.client.Self.Channel.Send(ADMIN_SONG_SKIP_MSG, false) - } else if dj.queue.CurrentSong().submitter == username { + } else if dj.queue.CurrentSong().Submitter() == username { dj.client.Self.Channel.Send(fmt.Sprintf(SUBMITTER_SKIP_HTML, username), false) submitterSkipped = true } else { @@ -369,7 +369,7 @@ func reset(username string) { // the number of songs in the queue to chat. func numSongs() { songCount := 0 - dj.queue.Traverse(func(i int, song *Song) { + dj.queue.Traverse(func(i int, song Song) { songCount++ }) dj.client.Self.Channel.Send(fmt.Sprintf(NUM_SONGS_HTML, songCount), false) @@ -382,7 +382,7 @@ func nextSong(user *gumble.User) { if song, err := dj.queue.PeekNext(); err != nil { dj.SendPrivateMessage(user, NO_SONG_NEXT_MSG) } else { - dj.SendPrivateMessage(user, fmt.Sprintf(NEXT_SONG_HTML, song.title, song.submitter)) + dj.SendPrivateMessage(user, fmt.Sprintf(NEXT_SONG_HTML, song.Title(), song.Submitter())) } } @@ -390,11 +390,11 @@ func nextSong(user *gumble.User) { // information about the song currently playing. func currentSong(user *gumble.User) { if dj.audioStream.IsPlaying() { - if dj.queue.CurrentSong().playlist == nil { - dj.SendPrivateMessage(user, fmt.Sprintf(CURRENT_SONG_HTML, dj.queue.CurrentSong().title, dj.queue.CurrentSong().submitter)) + if dj.queue.CurrentSong().Playlist() == nil { + dj.SendPrivateMessage(user, fmt.Sprintf(CURRENT_SONG_HTML, dj.queue.CurrentSong().Title(), dj.queue.CurrentSong().Submitter())) } else { - dj.SendPrivateMessage(user, fmt.Sprintf(CURRENT_SONG_PLAYLIST_HTML, dj.queue.CurrentSong().title, - dj.queue.CurrentSong().submitter, dj.queue.CurrentSong().playlist.title)) + dj.SendPrivateMessage(user, fmt.Sprintf(CURRENT_SONG_PLAYLIST_HTML, dj.queue.CurrentSong().Title(), + dj.queue.CurrentSong().Submitter(), dj.queue.CurrentSong().Playlist().Title())) } } else { dj.SendPrivateMessage(user, NO_MUSIC_PLAYING_MSG) diff --git a/main.go b/main.go index 308f00b..05932ff 100644 --- a/main.go +++ b/main.go @@ -102,8 +102,8 @@ func (dj *mumbledj) OnTextMessage(e *gumble.TextMessageEvent) { func (dj *mumbledj) OnUserChange(e *gumble.UserChangeEvent) { if e.Type.Has(gumble.UserChangeDisconnected) { if dj.audioStream.IsPlaying() { - if dj.queue.CurrentSong().playlist != nil { - dj.queue.CurrentSong().playlist.RemoveSkip(e.User.Name) + if dj.queue.CurrentSong().Playlist() != nil { + dj.queue.CurrentSong().Playlist().RemoveSkip(e.User.Name) } dj.queue.CurrentSong().RemoveSkip(e.User.Name) } diff --git a/service.go b/service.go index bcaa821..205c277 100644 --- a/service.go +++ b/service.go @@ -13,26 +13,27 @@ type Song interface { Download() error Play() Delete() error - AddSkip() error - RemoveSkip() error - SkipReached() bool + AddSkip(string) error + RemoveSkip(string) error + SkipReached(int) bool Submitter() string Title() string ID() string Filename() string Duration() string Thumbnail() string - Playlist() *Playlist + Playlist() Playlist DontSkip() bool + SetDontSkip(bool) } // Playlist interface. Each service will implement these // functions in their Playlist types. type Playlist interface { - AddSkip() error - RemoveSkip() error + AddSkip(string) error + RemoveSkip(string) error DeleteSkippers() - SkipReached() bool + SkipReached(int) bool ID() string Title() string } diff --git a/service_youtube.go b/service_youtube.go index f8337a5..6e72fa5 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -34,7 +34,7 @@ type YouTubeSong struct { duration string thumbnail string skippers []string - playlist *Playlist + playlist *YouTubePlaylist dontSkip bool } @@ -43,13 +43,13 @@ type YouTubeSong struct { func NewYouTubeSong(user, id string, playlist *YouTubePlaylist) (*YouTubeSong, error) { url := fmt.Sprintf("https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails&id=%s&key=%s", id, os.Getenv("YOUTUBE_API_KEY")) - if response, err := PerformGetRequest(url); err != nil { + if apiResponse, err := PerformGetRequest(url); err != nil { return nil, err } - title, _ := response.String("items", "0", "snippet", "title") - thumbnail, _ := response.String("items", "0", "snippet", "thumbnails", "high", "url") - duration, _ := response.String("items", "0", "contentDetails", "duration") + title, _ := apiResponse.String("items", "0", "snippet", "title") + thumbnail, _ := apiResponse.String("items", "0", "snippet", "thumbnails", "high", "url") + duration, _ := apiResponse.String("items", "0", "contentDetails", "duration") minutes := int(duration[2:strings.Index(duration, "M")]) seconds := int(duration[strings.Index(duration, "M")+1 : len(duration)-1]) @@ -58,16 +58,15 @@ func NewYouTubeSong(user, id string, playlist *YouTubePlaylist) (*YouTubeSong, e if dj.conf.General.MaxSongDuration == 0 || totalSeconds <= dj.conf.General.MaxSongDuration { song := &YouTubeSong{ - submitter: user, - title: title, - id: id, - filename: id + ".m4a", - duration: durationString, - secondsDuration: totalSeconds, - thumbnail: thumbnail, - skippers: make([]string, 0), - playlist: nil, - dontSkip: false, + submitter: user, + title: title, + id: id, + filename: id + ".m4a", + duration: durationString, + thumbnail: thumbnail, + skippers: make([]string, 0), + playlist: nil, + dontSkip: false, } dj.queue.AddSong(song) return song, nil @@ -216,8 +215,8 @@ func (s *YouTubeSong) Thumbnail() string { } // Playlist returns the playlist type for the YouTubeSong (may be nil). -func (s *YouTubeSong) Playlist() *YouTubePlaylist { - return s.playlist +func (s *YouTubeSong) Playlist() Playlist { + return *s.playlist } // DontSkip returns the DontSkip boolean value for the YouTubeSong. @@ -225,6 +224,11 @@ func (s *YouTubeSong) DontSkip() bool { return s.dontSkip } +// SetDontSkip sets the DontSkip boolean value for the YouTubeSong. +func (s *YouTubeSong) SetDontSkip(value bool) { + s.dontSkip = value +} + // ---------------- // YOUTUBE PLAYLIST // ---------------- @@ -240,10 +244,10 @@ func NewYouTubePlaylist(user, id string) (*YouTubePlaylist, error) { // Retrieve title of playlist url := fmt.Sprintf("https://www.googleapis.com/youtube/v3/playlists?part=snippet&id=%s&key=%s", id, os.Getenv("YOUTUBE_API_KEY")) - if response, err := PerformGetRequest(url); err != nil { + if apiResponse, err := PerformGetRequest(url); err != nil { return nil, err } - title, _ := response.String("items", "0") + title, _ := apiResponse.String("items", "0") playlist := &YouTubePlaylist{ id: id, @@ -253,19 +257,19 @@ func NewYouTubePlaylist(user, id string) (*YouTubePlaylist, error) { // Retrieve items in playlist url = fmt.Sprintf("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=25&playlistId=%s&key=%s", id, os.Getenv("YOUTUBE_API_KEY")) - if response, err = PerformGetRequest(url); err != nil { + if apiResponse, err = PerformGetRequest(url); err != nil { return nil, err } - numVideos := response.Int("pageInfo", "totalResults") + numVideos := apiResponse.Int("pageInfo", "totalResults") if numVideos > 25 { numVideos = 25 } for i := 0; i < numVideos; i++ { index := strconv.Itoa(i) - videoTitle, _ := response.String("items", index, "snippet", "title") - videoID, _ := response.String("items", index, "snippet", "resourceId", "videoId") - videoThumbnail, _ := response.String("items", index, "snippet", "thumbnails", "high", "url") + videoTitle, _ := apiResponse.String("items", index, "snippet", "title") + videoID, _ := apiResponse.String("items", index, "snippet", "resourceId", "videoId") + videoThumbnail, _ := apiResponse.String("items", index, "snippet", "thumbnails", "high", "url") // A completely separate API call just to get the duration of a video in a // playlist? WHY GOOGLE, WHY?! @@ -274,7 +278,7 @@ func NewYouTubePlaylist(user, id string) (*YouTubePlaylist, error) { if response, err = PerformGetRequest(url); err != nil { return nil, err } - videoDuration, _ := response.String("items", "0", "contentDetails", "duration") + videoDuration, _ := apiResponse.String("items", "0", "contentDetails", "duration") minutes := int(videoDuration[2:strings.Index(videoDuration, "M")]) seconds := int(videoDuration[strings.Index(videoDuration, "M")+1 : len(videoDuration)-1]) totalSeconds := (minutes * 60) + seconds