More changes and additions to Song and Playlist types

This commit is contained in:
Matthieu Grieger 2015-04-15 23:32:32 -07:00
parent e0a936ab63
commit f6b301edd6
5 changed files with 57 additions and 52 deletions

View file

@ -4,7 +4,7 @@ mumbledj: main.go commands.go parseconfig.go strings.go service.go service_youtu
go get github.com/nitrous-io/goop go get github.com/nitrous-io/goop
rm -rf Goopfile.lock rm -rf Goopfile.lock
goop install goop install
goop go build . goop go build
clean: clean:
rm -f mumbledj* 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; if [ -d ~/bin ]; then cp -f mumbledj* ~/bin/mumbledj; else sudo cp -f mumbledj* /usr/local/bin/mumbledj; fi;
build: build:
goop go build . goop go build

View file

@ -238,23 +238,23 @@ func add(user *gumble.User, username, url string) {
func skip(user *gumble.User, username string, admin, playlistSkip bool) { func skip(user *gumble.User, username string, admin, playlistSkip bool) {
if dj.audioStream.IsPlaying() { if dj.audioStream.IsPlaying() {
if playlistSkip { if playlistSkip {
if dj.queue.CurrentSong().playlist != nil { if dj.queue.CurrentSong().Playlist() != nil {
if err := dj.queue.CurrentSong().playlist.AddSkip(username); err == nil { if err := dj.queue.CurrentSong().Playlist().AddSkip(username); err == nil {
submitterSkipped := false submitterSkipped := false
if admin { if admin {
dj.client.Self.Channel.Send(ADMIN_PLAYLIST_SKIP_MSG, false) 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) dj.client.Self.Channel.Send(fmt.Sprintf(PLAYLIST_SUBMITTER_SKIP_HTML, username), false)
submitterSkipped = true submitterSkipped = true
} else { } else {
dj.client.Self.Channel.Send(fmt.Sprintf(PLAYLIST_SKIP_ADDED_HTML, username), false) 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 { if submitterSkipped || dj.queue.CurrentSong().Playlist().SkipReached(len(dj.client.Self.Channel.Users)) || admin {
id := dj.queue.CurrentSong().playlist.id id := dj.queue.CurrentSong().Playlist().ID()
dj.queue.CurrentSong().playlist.DeleteSkippers() dj.queue.CurrentSong().Playlist().DeleteSkippers()
for i := 0; i < len(dj.queue.queue); i++ { for i := 0; i < len(dj.queue.queue); i++ {
if dj.queue.queue[i].playlist != nil { if dj.queue.queue[i].Playlist() != nil {
if dj.queue.queue[i].playlist.id == id { if dj.queue.queue[i].Playlist().ID() == id {
dj.queue.queue = append(dj.queue.queue[:i], dj.queue.queue[i+1:]...) dj.queue.queue = append(dj.queue.queue[:i], dj.queue.queue[i+1:]...)
i-- i--
} }
@ -262,7 +262,7 @@ func skip(user *gumble.User, username string, admin, playlistSkip bool) {
} }
if dj.queue.Len() != 0 { if dj.queue.Len() != 0 {
// Set dontSkip to true to avoid audioStream.Stop() callback skipping the new first song. // 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) { if !(submitterSkipped || admin) {
dj.client.Self.Channel.Send(PLAYLIST_SKIPPED_HTML, false) 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 submitterSkipped := false
if admin { if admin {
dj.client.Self.Channel.Send(ADMIN_SONG_SKIP_MSG, false) 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) dj.client.Self.Channel.Send(fmt.Sprintf(SUBMITTER_SKIP_HTML, username), false)
submitterSkipped = true submitterSkipped = true
} else { } else {
@ -369,7 +369,7 @@ func reset(username string) {
// the number of songs in the queue to chat. // the number of songs in the queue to chat.
func numSongs() { func numSongs() {
songCount := 0 songCount := 0
dj.queue.Traverse(func(i int, song *Song) { dj.queue.Traverse(func(i int, song Song) {
songCount++ songCount++
}) })
dj.client.Self.Channel.Send(fmt.Sprintf(NUM_SONGS_HTML, songCount), false) 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 { if song, err := dj.queue.PeekNext(); err != nil {
dj.SendPrivateMessage(user, NO_SONG_NEXT_MSG) dj.SendPrivateMessage(user, NO_SONG_NEXT_MSG)
} else { } 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. // information about the song currently playing.
func currentSong(user *gumble.User) { func currentSong(user *gumble.User) {
if dj.audioStream.IsPlaying() { if dj.audioStream.IsPlaying() {
if dj.queue.CurrentSong().playlist == nil { if dj.queue.CurrentSong().Playlist() == nil {
dj.SendPrivateMessage(user, fmt.Sprintf(CURRENT_SONG_HTML, dj.queue.CurrentSong().title, dj.queue.CurrentSong().submitter)) dj.SendPrivateMessage(user, fmt.Sprintf(CURRENT_SONG_HTML, dj.queue.CurrentSong().Title(), dj.queue.CurrentSong().Submitter()))
} else { } else {
dj.SendPrivateMessage(user, fmt.Sprintf(CURRENT_SONG_PLAYLIST_HTML, dj.queue.CurrentSong().title, dj.SendPrivateMessage(user, fmt.Sprintf(CURRENT_SONG_PLAYLIST_HTML, dj.queue.CurrentSong().Title(),
dj.queue.CurrentSong().submitter, dj.queue.CurrentSong().playlist.title)) dj.queue.CurrentSong().Submitter(), dj.queue.CurrentSong().Playlist().Title()))
} }
} else { } else {
dj.SendPrivateMessage(user, NO_MUSIC_PLAYING_MSG) dj.SendPrivateMessage(user, NO_MUSIC_PLAYING_MSG)

View file

@ -102,8 +102,8 @@ func (dj *mumbledj) OnTextMessage(e *gumble.TextMessageEvent) {
func (dj *mumbledj) OnUserChange(e *gumble.UserChangeEvent) { func (dj *mumbledj) OnUserChange(e *gumble.UserChangeEvent) {
if e.Type.Has(gumble.UserChangeDisconnected) { if e.Type.Has(gumble.UserChangeDisconnected) {
if dj.audioStream.IsPlaying() { if dj.audioStream.IsPlaying() {
if dj.queue.CurrentSong().playlist != nil { if dj.queue.CurrentSong().Playlist() != nil {
dj.queue.CurrentSong().playlist.RemoveSkip(e.User.Name) dj.queue.CurrentSong().Playlist().RemoveSkip(e.User.Name)
} }
dj.queue.CurrentSong().RemoveSkip(e.User.Name) dj.queue.CurrentSong().RemoveSkip(e.User.Name)
} }

View file

@ -13,26 +13,27 @@ type Song interface {
Download() error Download() error
Play() Play()
Delete() error Delete() error
AddSkip() error AddSkip(string) error
RemoveSkip() error RemoveSkip(string) error
SkipReached() bool SkipReached(int) bool
Submitter() string Submitter() string
Title() string Title() string
ID() string ID() string
Filename() string Filename() string
Duration() string Duration() string
Thumbnail() string Thumbnail() string
Playlist() *Playlist Playlist() Playlist
DontSkip() bool DontSkip() bool
SetDontSkip(bool)
} }
// Playlist interface. Each service will implement these // Playlist interface. Each service will implement these
// functions in their Playlist types. // functions in their Playlist types.
type Playlist interface { type Playlist interface {
AddSkip() error AddSkip(string) error
RemoveSkip() error RemoveSkip(string) error
DeleteSkippers() DeleteSkippers()
SkipReached() bool SkipReached(int) bool
ID() string ID() string
Title() string Title() string
} }

View file

@ -34,7 +34,7 @@ type YouTubeSong struct {
duration string duration string
thumbnail string thumbnail string
skippers []string skippers []string
playlist *Playlist playlist *YouTubePlaylist
dontSkip bool dontSkip bool
} }
@ -43,13 +43,13 @@ type YouTubeSong struct {
func NewYouTubeSong(user, id string, playlist *YouTubePlaylist) (*YouTubeSong, error) { 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", url := fmt.Sprintf("https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails&id=%s&key=%s",
id, os.Getenv("YOUTUBE_API_KEY")) id, os.Getenv("YOUTUBE_API_KEY"))
if response, err := PerformGetRequest(url); err != nil { if apiResponse, err := PerformGetRequest(url); err != nil {
return nil, err return nil, err
} }
title, _ := response.String("items", "0", "snippet", "title") title, _ := apiResponse.String("items", "0", "snippet", "title")
thumbnail, _ := response.String("items", "0", "snippet", "thumbnails", "high", "url") thumbnail, _ := apiResponse.String("items", "0", "snippet", "thumbnails", "high", "url")
duration, _ := response.String("items", "0", "contentDetails", "duration") duration, _ := apiResponse.String("items", "0", "contentDetails", "duration")
minutes := int(duration[2:strings.Index(duration, "M")]) minutes := int(duration[2:strings.Index(duration, "M")])
seconds := int(duration[strings.Index(duration, "M")+1 : len(duration)-1]) 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 { if dj.conf.General.MaxSongDuration == 0 || totalSeconds <= dj.conf.General.MaxSongDuration {
song := &YouTubeSong{ song := &YouTubeSong{
submitter: user, submitter: user,
title: title, title: title,
id: id, id: id,
filename: id + ".m4a", filename: id + ".m4a",
duration: durationString, duration: durationString,
secondsDuration: totalSeconds, thumbnail: thumbnail,
thumbnail: thumbnail, skippers: make([]string, 0),
skippers: make([]string, 0), playlist: nil,
playlist: nil, dontSkip: false,
dontSkip: false,
} }
dj.queue.AddSong(song) dj.queue.AddSong(song)
return song, nil return song, nil
@ -216,8 +215,8 @@ func (s *YouTubeSong) Thumbnail() string {
} }
// Playlist returns the playlist type for the YouTubeSong (may be nil). // Playlist returns the playlist type for the YouTubeSong (may be nil).
func (s *YouTubeSong) Playlist() *YouTubePlaylist { func (s *YouTubeSong) Playlist() Playlist {
return s.playlist return *s.playlist
} }
// DontSkip returns the DontSkip boolean value for the YouTubeSong. // DontSkip returns the DontSkip boolean value for the YouTubeSong.
@ -225,6 +224,11 @@ func (s *YouTubeSong) DontSkip() bool {
return s.dontSkip return s.dontSkip
} }
// SetDontSkip sets the DontSkip boolean value for the YouTubeSong.
func (s *YouTubeSong) SetDontSkip(value bool) {
s.dontSkip = value
}
// ---------------- // ----------------
// YOUTUBE PLAYLIST // YOUTUBE PLAYLIST
// ---------------- // ----------------
@ -240,10 +244,10 @@ func NewYouTubePlaylist(user, id string) (*YouTubePlaylist, error) {
// Retrieve title of playlist // Retrieve title of playlist
url := fmt.Sprintf("https://www.googleapis.com/youtube/v3/playlists?part=snippet&id=%s&key=%s", url := fmt.Sprintf("https://www.googleapis.com/youtube/v3/playlists?part=snippet&id=%s&key=%s",
id, os.Getenv("YOUTUBE_API_KEY")) id, os.Getenv("YOUTUBE_API_KEY"))
if response, err := PerformGetRequest(url); err != nil { if apiResponse, err := PerformGetRequest(url); err != nil {
return nil, err return nil, err
} }
title, _ := response.String("items", "0") title, _ := apiResponse.String("items", "0")
playlist := &YouTubePlaylist{ playlist := &YouTubePlaylist{
id: id, id: id,
@ -253,19 +257,19 @@ func NewYouTubePlaylist(user, id string) (*YouTubePlaylist, error) {
// Retrieve items in playlist // Retrieve items in playlist
url = fmt.Sprintf("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=25&playlistId=%s&key=%s", url = fmt.Sprintf("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=25&playlistId=%s&key=%s",
id, os.Getenv("YOUTUBE_API_KEY")) id, os.Getenv("YOUTUBE_API_KEY"))
if response, err = PerformGetRequest(url); err != nil { if apiResponse, err = PerformGetRequest(url); err != nil {
return nil, err return nil, err
} }
numVideos := response.Int("pageInfo", "totalResults") numVideos := apiResponse.Int("pageInfo", "totalResults")
if numVideos > 25 { if numVideos > 25 {
numVideos = 25 numVideos = 25
} }
for i := 0; i < numVideos; i++ { for i := 0; i < numVideos; i++ {
index := strconv.Itoa(i) index := strconv.Itoa(i)
videoTitle, _ := response.String("items", index, "snippet", "title") videoTitle, _ := apiResponse.String("items", index, "snippet", "title")
videoID, _ := response.String("items", index, "snippet", "resourceId", "videoId") videoID, _ := apiResponse.String("items", index, "snippet", "resourceId", "videoId")
videoThumbnail, _ := response.String("items", index, "snippet", "thumbnails", "high", "url") videoThumbnail, _ := apiResponse.String("items", index, "snippet", "thumbnails", "high", "url")
// A completely separate API call just to get the duration of a video in a // A completely separate API call just to get the duration of a video in a
// playlist? WHY GOOGLE, WHY?! // playlist? WHY GOOGLE, WHY?!
@ -274,7 +278,7 @@ func NewYouTubePlaylist(user, id string) (*YouTubePlaylist, error) {
if response, err = PerformGetRequest(url); err != nil { if response, err = PerformGetRequest(url); err != nil {
return nil, err 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")]) minutes := int(videoDuration[2:strings.Index(videoDuration, "M")])
seconds := int(videoDuration[strings.Index(videoDuration, "M")+1 : len(videoDuration)-1]) seconds := int(videoDuration[strings.Index(videoDuration, "M")+1 : len(videoDuration)-1])
totalSeconds := (minutes * 60) + seconds totalSeconds := (minutes * 60) + seconds