use of se.michaelthelin.spotify.model_objects.specification.Episode in project aiode by robinfriedli.
the class SpotifyService method searchEpisode.
public List<Episode> searchEpisode(String searchTerm, boolean limitToLibrary, int limit) throws IOException, SpotifyWebApiException, ParseException {
List<EpisodeSimplified> searchResultItems = searchItem(limitToLibrary, limit, () -> spotifyApi.searchEpisodes(searchTerm).market(getCurrentMarket()), batch -> {
// this implements checking whether the episode is in the current user's library by checking whether its show is
//
// It is vital that the resulting Boolean[] matches the provided batch of EpisodeSimplified[] in size and indexing,
// yet it is theoretically conceivable that getSeveralEpisodes returns null values when converting from
// EpisodeSimplified to Episode, which is required to get the show. Therefore this implementation maps the
// boolean value at the same index as the null-filtered list of episode ids, which might have a different
// size, and finally iterates over the original array of EpisodeSimplified[] and retrieves the boolean value
// for its id and maps false if absent.
String[] ids = Arrays.stream(batch).map(EpisodeSimplified::getId).toArray(String[]::new);
Episode[] episodes = spotifyApi.getSeveralEpisodes(ids).market(getCurrentMarket()).build().execute();
List<String> episodeIds = Lists.newArrayList();
List<String> showIds = Lists.newArrayList();
for (Episode episode : episodes) {
if (episode != null) {
episodeIds.add(episode.getId());
showIds.add(episode.getShow().getId());
}
}
Boolean[] isInLibrary = spotifyApi.checkUsersSavedShows(showIds.toArray(new String[0])).build().execute();
Map<String, Boolean> episodeInLibraryMap = new HashMap<>();
if (isInLibrary.length != episodeIds.size()) {
throw new IllegalStateException("checkUsersSavedShows check did not return exactly one boolean for each episode ID");
}
for (int i = 0; i < isInLibrary.length; i++) {
episodeInLibraryMap.put(episodeIds.get(i), isInLibrary[i]);
}
return Arrays.stream(batch).map(episode -> Objects.requireNonNullElse(episodeInLibraryMap.get(episode.getId()), false)).toArray(Boolean[]::new);
});
String[] resultIds = searchResultItems.stream().filter(Objects::nonNull).map(EpisodeSimplified::getId).toArray(String[]::new);
return getSeveralEpisodes(resultIds);
}
use of se.michaelthelin.spotify.model_objects.specification.Episode in project aiode by robinfriedli.
the class PlayableFactory method createPlayables.
/**
* Creates Playables for a Collection of Objects; YouTube videos or Spotify Tracks.
*
* @param redirectSpotify if true the matching YouTube video is loaded to play the full track using
* {@link YouTubeService#redirectSpotify(HollowYouTubeVideo)}, else a {@link PlayableTrackWrapper} is created to play the
* preview mp3 provided by Spotify
* @param items the objects to create a Playable for
* @return the created Playables
*/
public List<Playable> createPlayables(boolean redirectSpotify, Collection<?> items) {
List<Playable> playables = Lists.newArrayList();
List<HollowYouTubeVideo> tracksToRedirect = Lists.newArrayList();
List<YouTubePlaylist> youTubePlaylistsToLoad = Lists.newArrayList();
try {
for (Object item : items) {
if (item instanceof Playable) {
playables.add((Playable) item);
} else if (item instanceof Track) {
handleTrack(SpotifyTrack.wrap((Track) item), redirectSpotify, tracksToRedirect, playables);
} else if (item instanceof Episode) {
handleTrack(SpotifyTrack.wrap((Episode) item), redirectSpotify, tracksToRedirect, playables);
} else if (item instanceof SpotifyTrack) {
handleTrack((SpotifyTrack) item, redirectSpotify, tracksToRedirect, playables);
} else if (item instanceof UrlTrack) {
playables.add(((UrlTrack) item).asPlayable());
} else if (item instanceof YouTubePlaylist) {
YouTubePlaylist youTubePlaylist = ((YouTubePlaylist) item);
playables.addAll(youTubePlaylist.getVideos());
youTubePlaylistsToLoad.add(youTubePlaylist);
} else if (item instanceof PlaylistSimplified) {
List<SpotifyTrack> t = SpotifyInvoker.create(spotifyService.getSpotifyApi()).invoke(() -> spotifyService.getPlaylistTracks((PlaylistSimplified) item));
for (SpotifyTrack track : t) {
handleTrack(track, redirectSpotify, tracksToRedirect, playables);
}
} else if (item instanceof AlbumSimplified) {
List<Track> t = invoker.invoke(() -> spotifyService.getAlbumTracks((AlbumSimplified) item));
for (Track track : t) {
handleTrack(SpotifyTrack.wrapIfNotNull(track), redirectSpotify, tracksToRedirect, playables);
}
} else if (item instanceof AudioTrack) {
playables.add(new UrlPlayable((AudioTrack) item));
} else if (item instanceof AudioPlaylist) {
List<Playable> convertedPlayables = ((AudioPlaylist) item).getTracks().stream().map(UrlPlayable::new).collect(Collectors.toList());
playables.addAll(convertedPlayables);
} else if (item != null) {
throw new UnsupportedOperationException("Unsupported playable " + item.getClass());
}
}
} catch (Exception e) {
throw new RuntimeException("Exception while creating Playables", e);
}
if (!tracksToRedirect.isEmpty() || !youTubePlaylistsToLoad.isEmpty()) {
trackLoadingExecutor.execute(new SpotifyTrackRedirectionRunnable(tracksToRedirect, youTubeService).andThen(new YouTubePlaylistPopulationRunnable(youTubePlaylistsToLoad, youTubeService)));
}
return playables;
}
use of se.michaelthelin.spotify.model_objects.specification.Episode in project aiode by robinfriedli.
the class PlayableFactory method createPlayablesFromSpotifyUrl.
private List<Playable> createPlayablesFromSpotifyUrl(URI uri, SpotifyApi spotifyApi, boolean redirectSpotify) {
StringList pathFragments = StringList.createWithRegex(uri.getPath(), "/");
SpotifyService spotifyService = new SpotifyService(spotifyApi);
if (pathFragments.contains("playlist")) {
return createPlayableForSpotifyUrlType(pathFragments, "playlist", playlistId -> {
List<SpotifyTrack> playlistTracks = spotifyService.getPlaylistTracks(playlistId);
return createPlayables(redirectSpotify, playlistTracks);
}, spotifyApi);
} else if (pathFragments.contains("track")) {
return createPlayableForSpotifyUrlType(pathFragments, "track", trackId -> {
Track track = spotifyApi.getTrack(trackId).build().execute();
return Lists.newArrayList(createPlayable(redirectSpotify, track));
}, spotifyApi);
} else if (pathFragments.contains("episode")) {
return createPlayableForSpotifyUrlType(pathFragments, "episode", episodeId -> {
Episode episode = spotifyApi.getEpisode(episodeId).build().execute();
return Lists.newArrayList(createPlayable(redirectSpotify, episode));
}, spotifyApi);
} else if (pathFragments.contains("album")) {
return createPlayableForSpotifyUrlType(pathFragments, "album", albumId -> {
List<Track> albumTracks = spotifyService.getAlbumTracks(albumId);
return createPlayables(redirectSpotify, albumTracks);
}, spotifyApi);
} else if (pathFragments.contains("show")) {
return createPlayableForSpotifyUrlType(pathFragments, "show", showId -> {
List<Episode> showEpisodes = spotifyService.getShowEpisodes(showId);
return createPlayables(redirectSpotify, showEpisodes);
}, spotifyApi);
} else {
throw new InvalidCommandException("Detected Spotify URL but no track, playlist or album id provided.");
}
}
use of se.michaelthelin.spotify.model_objects.specification.Episode in project spotify-web-api-java by spotify-web-api-java.
the class GetEpisodeExample method getEpisode_Async.
public static void getEpisode_Async() {
try {
final CompletableFuture<Episode> episodeFuture = getEpisodeRequest.executeAsync();
// Thread free to do other tasks...
// Example Only. Never block in production code.
final Episode episode = episodeFuture.join();
System.out.println("Name: " + episode.getName());
} catch (CompletionException e) {
System.out.println("Error: " + e.getCause().getMessage());
} catch (CancellationException e) {
System.out.println("Async operation cancelled.");
}
}
use of se.michaelthelin.spotify.model_objects.specification.Episode in project aiode by robinfriedli.
the class SearchCommand method listTracks.
private void listTracks(List<SpotifyTrack> spotifyTracks, String name, String owner, String artist, String path) {
EmbedBuilder embedBuilder = new EmbedBuilder();
long totalDuration = spotifyTracks.stream().mapToInt(track -> {
Integer durationMs = track.getDurationMs();
return Objects.requireNonNullElse(durationMs, 0);
}).sum();
embedBuilder.addField("Name", name, true);
embedBuilder.addField("Song count", String.valueOf(spotifyTracks.size()), true);
embedBuilder.addField("Duration", Util.normalizeMillis(totalDuration), true);
if (owner != null) {
embedBuilder.addField("Owner", owner, true);
}
if (artist != null) {
embedBuilder.addField("Artist", artist, true);
}
if (!spotifyTracks.isEmpty()) {
String url = "https://open.spotify.com/" + path;
embedBuilder.addField("First tracks:", "[Full list](" + url + ")", false);
Util.appendEmbedList(embedBuilder, spotifyTracks.size() > 5 ? spotifyTracks.subList(0, 5) : spotifyTracks, spotifyTrack -> spotifyTrack.exhaustiveMatch(track -> String.format("%s - %s - %s", track.getName(), StringList.create(track.getArtists(), ArtistSimplified::getName).toSeparatedString(", "), Util.normalizeMillis(track.getDurationMs() != null ? track.getDurationMs() : 0)), episode -> String.format("%s - %s - %s", episode.getName(), episode.getShow() != null ? episode.getShow().getName() : "", Util.normalizeMillis(episode.getDurationMs() != null ? episode.getDurationMs() : 0))), "Track - Artist - Duration");
}
sendMessage(embedBuilder);
}
Aggregations