func (suite *ListTracksCommandTestSuite) TestExecuteWithValidArg() {
	track1 := new(bot.Track)
	track1.Title = "first"
	track1.Submitter = "test"

	track2 := new(bot.Track)
	track2.Title = "second"
	track2.Submitter = "test"

	track3 := new(bot.Track)
	track3.Title = "third"
	track3.Submitter = "test"

	DJ.Queue.AppendTrack(track1)
	DJ.Queue.AppendTrack(track2)
	DJ.Queue.AppendTrack(track3)

	message, isPrivateMessage, err := suite.Command.Execute(nil, "2")

	suite.NotEqual("", message, "A message containing track information should be returned.")
	suite.Contains(message, "first", "The returned message should contain the first track.")
	suite.Contains(message, "second", "The returned message should contain the second track.")
	suite.NotContains(message, "third", "The returned message should not contain the third track.")
	suite.True(isPrivateMessage, "This should be a private message.")
	suite.Nil(err, "No error should be returned.")
}
func (suite *CurrentTrackCommandTestSuite) TestExecuteWhenQueueNotEmpty() {
	track := new(bot.Track)
	track.Submitter = "test"
	track.Title = "test"

	DJ.Queue.AppendTrack(track)

	message, isPrivateMessage, err := suite.Command.Execute(nil)

	suite.NotEqual("", message, "A message should be returned with the current track information.")
	suite.True(isPrivateMessage, "This should be a private message.")
	suite.Nil(err, "No error should be returned.")
}
func (suite *ListTracksCommandTestSuite) TestExecuteWithInvalidArg() {
	track := new(bot.Track)
	track.Title = "track"
	track.Submitter = "test"

	DJ.Queue.AppendTrack(track)

	message, isPrivateMessage, err := suite.Command.Execute(nil, "test")

	suite.Equal("", message, "No message should be returned.")
	suite.True(isPrivateMessage, "This should be a private message.")
	suite.NotNil(err, "An error should be returned due to an invalid argument being supplied.")
}
func (suite *NextTrackCommandTestSuite) TestExecuteWhenQueueHasOneTrack() {
	track := new(bot.Track)
	track.Title = "test"
	track.Submitter = "test"

	DJ.Queue.AppendTrack(track)

	message, isPrivateMessage, err := suite.Command.Execute(nil)

	suite.Equal("", message, "No message should be returned.")
	suite.True(isPrivateMessage, "This should be a private message.")
	suite.NotNil(err, "An error should be returned due to the queue having only one track.")
}
func (suite *NumTracksCommandTestSuite) TestExecuteWhenOneTrackIsInQueue() {
	track := new(bot.Track)
	track.Title = "test"
	track.Submitter = "test"

	DJ.Queue.AppendTrack(track)

	message, isPrivateMessage, err := suite.Command.Execute(nil)

	suite.NotEqual("", message, "A message should be returned.")
	suite.Contains(message, "<b>1</b> track", "The returned message should state that there is one track in the queue.")
	suite.True(isPrivateMessage, "This should be a private message.")
	suite.Nil(err, "No error should be returned.")
}
func (suite *ListTracksCommandTestSuite) TestExecuteWithNoArg() {
	track := new(bot.Track)
	track.Title = "title"
	track.Submitter = "test"

	DJ.Queue.AppendTrack(track)

	message, isPrivateMessage, err := suite.Command.Execute(nil)

	suite.NotEqual("", message, "A message containing track information should be returned.")
	suite.Contains(message, "title", "The returned message should contain the track title.")
	suite.Contains(message, "test", "The returned message should contain the track submitter.")
	suite.True(isPrivateMessage, "This should be a private message.")
	suite.Nil(err, "No error should be returned.")
}
func (suite *ListTracksCommandTestSuite) TestExecuteWithArgLargerThanQueueLength() {
	track := new(bot.Track)
	track.Title = "track"
	track.Submitter = "test"

	DJ.Queue.AppendTrack(track)

	message, isPrivateMessage, err := suite.Command.Execute(nil, "2")

	suite.NotEqual("", message, "A message containing track information should be returned.")
	suite.Contains(message, "1", "The returned message should contain the first track.")
	suite.NotContains(message, "2", "The returned message should not contain any further tracks.")
	suite.True(isPrivateMessage, "This should be a private message.")
	suite.Nil(err, "No error should be returned.")
}
func (suite *NumTracksCommandTestSuite) TestExecuteWhenTwoOrMoreTracksAreInQueue() {
	track1 := new(bot.Track)
	track1.Title = "test"
	track1.Submitter = "test"

	track2 := new(bot.Track)
	track2.Title = "test"
	track2.Submitter = "test"

	DJ.Queue.AppendTrack(track1)
	DJ.Queue.AppendTrack(track2)

	message, isPrivateMessage, err := suite.Command.Execute(nil)

	suite.NotEqual("", "A message should be returned.")
	suite.Contains(message, "tracks", "The returned message should use the plural form of the word track.")
	suite.True(isPrivateMessage, "This should be a private message.")
	suite.Nil(err, "No error should be returned.")
}
func (suite *NextTrackCommandTestSuite) TestExecuteWhenQueueHasTwoOrMoreTracks() {
	track1 := new(bot.Track)
	track1.Title = "first"
	track1.Submitter = "test"

	track2 := new(bot.Track)
	track2.Title = "second"
	track2.Submitter = "test"

	DJ.Queue.AppendTrack(track1)
	DJ.Queue.AppendTrack(track2)

	message, isPrivateMessage, err := suite.Command.Execute(nil)

	suite.NotEqual("", "A message containing information for the next track should be returned.")
	suite.Contains(message, "second", "The returned message should contain information about the second track in the queue.")
	suite.True(isPrivateMessage, "This should be a private message.")
	suite.Nil(err, "No error should be returned.")
}
Example #10
0
// GetTracks uses the passed URL to find and return
// tracks associated with the URL. An error is returned
// if any error occurs during the API call.
func (sc *SoundCloud) GetTracks(url string, submitter *gumble.User) ([]interfaces.Track, error) {
	var (
		apiURL string
		err    error
		resp   *http.Response
		v      *jason.Object
		track  bot.Track
		tracks []interfaces.Track
	)

	urlSplit := strings.Split(url, "#t=")

	apiURL = "http://api.soundcloud.com/resolve?url=%s&client_id=%s"

	if sc.isPlaylist(url) {
		// Submitter has added a playlist!
		resp, err = http.Get(fmt.Sprintf(apiURL, urlSplit[0], viper.GetString("api_keys.soundcloud")))
		defer resp.Body.Close()
		if err != nil {
			return nil, err
		}

		v, err = jason.NewObjectFromReader(resp.Body)
		if err != nil {
			return nil, err
		}

		title, _ := v.GetString("title")
		permalink, _ := v.GetString("permalink_url")
		playlist := &bot.Playlist{
			ID:        permalink,
			Title:     title,
			Submitter: submitter.Name,
			Service:   sc.ReadableName,
		}

		var scTracks []*jason.Object
		scTracks, err = v.GetObjectArray("tracks")
		if err != nil {
			return nil, err
		}

		dummyOffset, _ := time.ParseDuration("0s")
		for _, t := range scTracks {
			track, err = sc.getTrack(t, dummyOffset, submitter)
			if err != nil {
				// Skip this track.
				continue
			}
			track.Playlist = playlist
			tracks = append(tracks, track)
		}

		if len(tracks) == 0 {
			return nil, errors.New("Invalid playlist. No tracks were added")
		}
		return tracks, nil
	}

	// Submitter has added a track!

	offset := 0
	// Calculate track offset if needed
	if len(urlSplit) == 2 {
		timeSplit := strings.Split(urlSplit[1], ":")
		multiplier := 1
		for i := len(timeSplit) - 1; i >= 0; i-- {
			time, _ := strconv.Atoi(timeSplit[i])
			offset += time * multiplier
			multiplier *= 60
		}
	}
	playbackOffset, _ := time.ParseDuration(fmt.Sprintf("%ds", offset))

	resp, err = http.Get(fmt.Sprintf(apiURL, urlSplit[0], viper.GetString("api_keys.soundcloud")))
	defer resp.Body.Close()
	if err != nil {
		return nil, err
	}

	v, err = jason.NewObjectFromReader(resp.Body)
	if err != nil {
		return nil, err
	}
	track, err = sc.getTrack(v, playbackOffset, submitter)
	if err != nil {
		return nil, err
	}

	tracks = append(tracks, track)
	return tracks, nil
}
Example #11
0
// GetTracks uses the passed URL to find and return
// tracks associated with the URL. An error is returned
// if any error occurs during the API call.
func (yt *YouTube) GetTracks(url string, submitter *gumble.User) ([]interfaces.Track, error) {
	var (
		playlistURL      string
		playlistItemsURL string
		id               string
		err              error
		resp             *http.Response
		v                *jason.Object
		track            bot.Track
		tracks           []interfaces.Track
	)

	playlistURL = "https://www.googleapis.com/youtube/v3/playlists?part=snippet&id=%s&key=%s"
	playlistItemsURL = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet,contentDetails&playlistId=%s&maxResults=%d&key=%s&pageToken=%s"
	id, err = yt.getID(url)
	if err != nil {
		return nil, err
	}

	if yt.isPlaylist(url) {
		resp, err = http.Get(fmt.Sprintf(playlistURL, id, viper.GetString("api_keys.youtube")))
		defer resp.Body.Close()
		if err != nil {
			return nil, err
		}

		v, err = jason.NewObjectFromReader(resp.Body)
		if err != nil {
			return nil, err
		}

		items, _ := v.GetObjectArray("items")
		item := items[0]

		title, _ := item.GetString("snippet", "title")

		playlist := &bot.Playlist{
			ID:        id,
			Title:     title,
			Submitter: submitter.Name,
			Service:   yt.ReadableName,
		}

		maxItems := math.MaxInt32
		if viper.GetInt("queue.max_tracks_per_playlist") > 0 {
			maxItems = viper.GetInt("queue.max_tracks_per_playlist")
		}

		pageToken := ""
		for len(tracks) < maxItems {
			curResp, curErr := http.Get(fmt.Sprintf(playlistItemsURL, id, maxItems, viper.GetString("api_keys.youtube"), pageToken))
			defer curResp.Body.Close()
			if curErr != nil {
				// An error occurred, simply skip this track.
				continue
			}

			v, err = jason.NewObjectFromReader(curResp.Body)
			if err != nil {
				// An error occurred, simply skip this track.
				continue
			}

			curTracks, _ := v.GetObjectArray("items")
			for _, track := range curTracks {
				videoID, _ := track.GetString("snippet", "resourceId", "videoId")

				// Unfortunately we have to execute another API call for each video as the YouTube API does not
				// return video durations from the playlistItems endpoint...
				newTrack, _ := yt.getTrack(videoID, submitter)
				newTrack.Playlist = playlist
				tracks = append(tracks, newTrack)

				if len(tracks) >= maxItems {
					break
				}
			}
		}

		if len(tracks) == 0 {
			return nil, errors.New("Invalid playlist. No tracks were added")
		}
		return tracks, nil
	}

	track, err = yt.getTrack(id, submitter)
	if err != nil {
		return nil, err
	}
	tracks = append(tracks, track)
	return tracks, nil
}