Fixed empty song/playlist entry being added upon !add with invalid YouTube ID.

pull/42/head
Matthieu Grieger 2015-02-02 12:05:00 -08:00
parent 6ba9f94e71
commit fc9f3c8f23
5 changed files with 44 additions and 26 deletions

View File

@ -6,6 +6,7 @@ MumbleDJ Changelog
* Fixed '!' being recognized as '!skipplaylist'.
* Fixed !reset crash when there is no audio playing.
* Fixed newlines after YouTube URL messing up !add commands.
* Fixed empty song/playlist entry being added upon !add with invalid YouTube ID.
### January 30, 2015 -- `v2.3.3`
* Fixed private messages crashing the bot when the target user switches channels or disconnects.

View File

@ -163,17 +163,20 @@ func add(user *gumble.User, username, url string) {
}
if matchFound {
newSong := NewSong(username, shortUrl)
if err := dj.queue.AddItem(newSong); err == nil {
dj.client.Self().Channel().Send(fmt.Sprintf(SONG_ADDED_HTML, username, newSong.title), false)
if dj.queue.Len() == 1 && !dj.audioStream.IsPlaying() {
if err := dj.queue.CurrentItem().(*Song).Download(); err == nil {
dj.queue.CurrentItem().(*Song).Play()
} else {
dj.SendPrivateMessage(user, AUDIO_FAIL_MSG)
dj.queue.CurrentItem().(*Song).Delete()
if newSong, err := NewSong(username, shortUrl); err == nil {
if err := dj.queue.AddItem(newSong); err == nil {
dj.client.Self().Channel().Send(fmt.Sprintf(SONG_ADDED_HTML, username, newSong.title), false)
if dj.queue.Len() == 1 && !dj.audioStream.IsPlaying() {
if err := dj.queue.CurrentItem().(*Song).Download(); err == nil {
dj.queue.CurrentItem().(*Song).Play()
} else {
dj.SendPrivateMessage(user, AUDIO_FAIL_MSG)
dj.queue.CurrentItem().(*Song).Delete()
}
}
}
} else {
dj.SendPrivateMessage(user, INVALID_YOUTUBE_ID_MSG)
}
} else {
// Check to see if we have a playlist URL instead.
@ -182,17 +185,20 @@ func add(user *gumble.User, username, url string) {
if re.MatchString(url) {
if dj.HasPermission(username, dj.conf.Permissions.AdminAddPlaylists) {
shortUrl = re.FindStringSubmatch(url)[1]
newPlaylist := NewPlaylist(username, shortUrl)
if dj.queue.AddItem(newPlaylist); err == nil {
dj.client.Self().Channel().Send(fmt.Sprintf(PLAYLIST_ADDED_HTML, username, newPlaylist.title), false)
if dj.queue.Len() == 1 && !dj.audioStream.IsPlaying() {
if err := dj.queue.CurrentItem().(*Playlist).songs.CurrentItem().(*Song).Download(); err == nil {
dj.queue.CurrentItem().(*Playlist).songs.CurrentItem().(*Song).Play()
} else {
dj.SendPrivateMessage(user, AUDIO_FAIL_MSG)
dj.queue.CurrentItem().(*Playlist).songs.CurrentItem().(*Song).Delete()
if newPlaylist, err := NewPlaylist(username, shortUrl); err == nil {
if dj.queue.AddItem(newPlaylist); err == nil {
dj.client.Self().Channel().Send(fmt.Sprintf(PLAYLIST_ADDED_HTML, username, newPlaylist.title), false)
if dj.queue.Len() == 1 && !dj.audioStream.IsPlaying() {
if err := dj.queue.CurrentItem().(*Playlist).songs.CurrentItem().(*Song).Download(); err == nil {
dj.queue.CurrentItem().(*Playlist).songs.CurrentItem().(*Song).Play()
} else {
dj.SendPrivateMessage(user, AUDIO_FAIL_MSG)
dj.queue.CurrentItem().(*Playlist).songs.CurrentItem().(*Song).Delete()
}
}
}
} else {
dj.SendPrivateMessage(user, INVALID_YOUTUBE_ID_MSG)
}
} else {
dj.SendPrivateMessage(user, NO_PLAYLIST_PERMISSION_MSG)

View File

@ -30,15 +30,19 @@ type Playlist struct {
// Returns a new Playlist type. Before returning the new type, the playlist's metadata is collected
// via the YouTube Gdata API.
func NewPlaylist(user, id string) *Playlist {
func NewPlaylist(user, id string) (*Playlist, error) {
queue := NewSongQueue()
jsonUrl := fmt.Sprintf("http://gdata.youtube.com/feeds/api/playlists/%s?v=2&alt=jsonc&maxresults=25", id)
jsonString := ""
if response, err := http.Get(jsonUrl); err == nil {
defer response.Body.Close()
if body, err := ioutil.ReadAll(response.Body); err == nil {
jsonString = string(body)
if response.StatusCode != 400 {
if body, err := ioutil.ReadAll(response.Body); err == nil {
jsonString = string(body)
}
} else {
return nil, errors.New("Invalid YouTube ID supplied.")
}
}
@ -78,7 +82,7 @@ func NewPlaylist(user, id string) *Playlist {
submitter: user,
skipped: false,
}
return playlist
return playlist, nil
}
// Adds a skip to the skippers slice. If the user is already in the slice AddSkip() returns

12
song.go
View File

@ -33,14 +33,18 @@ type Song struct {
// Returns a new Song type. Before returning the new type, the song's metadata is collected
// via the YouTube Gdata API.
func NewSong(user, id string) *Song {
func NewSong(user, id string) (*Song, error) {
jsonUrl := fmt.Sprintf("http://gdata.youtube.com/feeds/api/videos/%s?v=2&alt=jsonc", id)
jsonString := ""
if response, err := http.Get(jsonUrl); err == nil {
defer response.Body.Close()
if body, err := ioutil.ReadAll(response.Body); err == nil {
jsonString = string(body)
if response.StatusCode != 400 {
if body, err := ioutil.ReadAll(response.Body); err == nil {
jsonString = string(body)
}
} else {
return nil, errors.New("Invalid YouTube ID supplied.")
}
}
@ -63,7 +67,7 @@ func NewSong(user, id string) *Song {
thumbnailUrl: videoThumbnail,
itemType: "song",
}
return song
return song, nil
}
// Downloads the song via youtube-dl. All downloaded songs are stored in ~/.mumbledj/songs and should be automatically cleaned.

View File

@ -50,6 +50,9 @@ const ADMIN_PLAYLIST_SKIP_MSG = "An admin has decided to skip the current playli
// Message shown to users when the audio for a video could not be downloaded.
const AUDIO_FAIL_MSG = "The audio download for this video failed. YouTube has likely not generated the audio files for this video yet. Skipping to the next song!"
// Message shown to users when they supply a YouTube URL that does not contain a valid ID.
const INVALID_YOUTUBE_ID_MSG = "The YouTube URL you supplied did not contain a valid YouTube ID."
// Message shown to a channel when a new song starts playing.
const NOW_PLAYING_HTML = `
<table>