Search in sources :

Example 6 with Episode

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);
}
Also used : Arrays(java.util.Arrays) PlaylistTrack(se.michaelthelin.spotify.model_objects.specification.PlaylistTrack) SpotifyInvoker(net.robinfriedli.aiode.function.SpotifyInvoker) Episode(se.michaelthelin.spotify.model_objects.specification.Episode) HashMap(java.util.HashMap) AbstractDataPagingRequest(se.michaelthelin.spotify.requests.data.AbstractDataPagingRequest) Function(java.util.function.Function) Supplier(java.util.function.Supplier) Playlist(se.michaelthelin.spotify.model_objects.specification.Playlist) EpisodeSimplified(se.michaelthelin.spotify.model_objects.specification.EpisodeSimplified) Lists(com.google.common.collect.Lists) AbstractDataRequest(se.michaelthelin.spotify.requests.data.AbstractDataRequest) Map(java.util.Map) ThreadContext(net.robinfriedli.aiode.concurrent.ThreadContext) Paging(se.michaelthelin.spotify.model_objects.specification.Paging) Track(se.michaelthelin.spotify.model_objects.specification.Track) SearchEngine(net.robinfriedli.aiode.util.SearchEngine) CountryCode(com.neovisionaries.i18n.CountryCode) ParseException(org.apache.hc.core5.http.ParseException) SpotifyWebApiException(se.michaelthelin.spotify.exceptions.SpotifyWebApiException) IOException(java.io.IOException) TrackSimplified(se.michaelthelin.spotify.model_objects.specification.TrackSimplified) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) Aiode(net.robinfriedli.aiode.Aiode) SpotifyApi(se.michaelthelin.spotify.SpotifyApi) ShowSimplified(se.michaelthelin.spotify.model_objects.specification.ShowSimplified) List(java.util.List) IPlaylistItem(se.michaelthelin.spotify.model_objects.IPlaylistItem) PlaylistSimplified(se.michaelthelin.spotify.model_objects.specification.PlaylistSimplified) Artist(se.michaelthelin.spotify.model_objects.specification.Artist) AlbumSimplified(se.michaelthelin.spotify.model_objects.specification.AlbumSimplified) HashMap(java.util.HashMap) Episode(se.michaelthelin.spotify.model_objects.specification.Episode) EpisodeSimplified(se.michaelthelin.spotify.model_objects.specification.EpisodeSimplified) Objects(java.util.Objects)

Example 7 with Episode

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;
}
Also used : NoResultsFoundException(net.robinfriedli.aiode.exceptions.NoResultsFoundException) NotFoundException(se.michaelthelin.spotify.exceptions.detailed.NotFoundException) InvalidCommandException(net.robinfriedli.aiode.exceptions.InvalidCommandException) ParseException(org.apache.hc.core5.http.ParseException) SpotifyWebApiException(se.michaelthelin.spotify.exceptions.SpotifyWebApiException) IOException(java.io.IOException) Episode(se.michaelthelin.spotify.model_objects.specification.Episode) SpotifyTrack(net.robinfriedli.aiode.audio.spotify.SpotifyTrack) UrlTrack(net.robinfriedli.aiode.entities.UrlTrack) YouTubePlaylist(net.robinfriedli.aiode.audio.youtube.YouTubePlaylist) HollowYouTubeVideo(net.robinfriedli.aiode.audio.youtube.HollowYouTubeVideo) AlbumSimplified(se.michaelthelin.spotify.model_objects.specification.AlbumSimplified) StringList(net.robinfriedli.stringlist.StringList) List(java.util.List) AudioTrack(com.sedmelluq.discord.lavaplayer.track.AudioTrack) SpotifyTrackRedirectionRunnable(net.robinfriedli.aiode.audio.exec.SpotifyTrackRedirectionRunnable) SpotifyTrack(net.robinfriedli.aiode.audio.spotify.SpotifyTrack) Track(se.michaelthelin.spotify.model_objects.specification.Track) AudioTrack(com.sedmelluq.discord.lavaplayer.track.AudioTrack) UrlTrack(net.robinfriedli.aiode.entities.UrlTrack) YouTubePlaylistPopulationRunnable(net.robinfriedli.aiode.audio.exec.YouTubePlaylistPopulationRunnable) PlaylistSimplified(se.michaelthelin.spotify.model_objects.specification.PlaylistSimplified) AudioPlaylist(com.sedmelluq.discord.lavaplayer.track.AudioPlaylist)

Example 8 with Episode

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.");
    }
}
Also used : StringList(net.robinfriedli.stringlist.StringList) NoResultsFoundException(net.robinfriedli.aiode.exceptions.NoResultsFoundException) YouTubePlaylist(net.robinfriedli.aiode.audio.youtube.YouTubePlaylist) SpotifyInvoker(net.robinfriedli.aiode.function.SpotifyInvoker) SpotifyTrack(net.robinfriedli.aiode.audio.spotify.SpotifyTrack) Episode(se.michaelthelin.spotify.model_objects.specification.Episode) AudioPlaylist(com.sedmelluq.discord.lavaplayer.track.AudioPlaylist) PlayableTrackWrapper(net.robinfriedli.aiode.audio.spotify.PlayableTrackWrapper) Strings(com.google.common.base.Strings) NotFoundException(se.michaelthelin.spotify.exceptions.detailed.NotFoundException) Lists(com.google.common.collect.Lists) HollowYouTubeVideo(net.robinfriedli.aiode.audio.youtube.HollowYouTubeVideo) Map(java.util.Map) YouTubeVideo(net.robinfriedli.aiode.audio.youtube.YouTubeVideo) Track(se.michaelthelin.spotify.model_objects.specification.Track) URI(java.net.URI) SpotifyTrackRedirectionRunnable(net.robinfriedli.aiode.audio.exec.SpotifyTrackRedirectionRunnable) Nullable(javax.annotation.Nullable) Collection(java.util.Collection) InvalidCommandException(net.robinfriedli.aiode.exceptions.InvalidCommandException) ParseException(org.apache.hc.core5.http.ParseException) SpotifyWebApiException(se.michaelthelin.spotify.exceptions.SpotifyWebApiException) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) SpotifyTrackKind(net.robinfriedli.aiode.audio.spotify.SpotifyTrackKind) StandardCharsets(java.nio.charset.StandardCharsets) AudioItem(com.sedmelluq.discord.lavaplayer.track.AudioItem) SpotifyApi(se.michaelthelin.spotify.SpotifyApi) YouTubePlaylistPopulationRunnable(net.robinfriedli.aiode.audio.exec.YouTubePlaylistPopulationRunnable) List(java.util.List) SpotifyService(net.robinfriedli.aiode.audio.spotify.SpotifyService) PlaylistSimplified(se.michaelthelin.spotify.model_objects.specification.PlaylistSimplified) URLEncodedUtils(org.apache.http.client.utils.URLEncodedUtils) AlbumSimplified(se.michaelthelin.spotify.model_objects.specification.AlbumSimplified) AudioTrack(com.sedmelluq.discord.lavaplayer.track.AudioTrack) TrackLoadingExecutor(net.robinfriedli.aiode.audio.exec.TrackLoadingExecutor) NameValuePair(org.apache.http.NameValuePair) UrlTrack(net.robinfriedli.aiode.entities.UrlTrack) Collections(java.util.Collections) YouTubeService(net.robinfriedli.aiode.audio.youtube.YouTubeService) CheckedFunction(net.robinfriedli.aiode.function.CheckedFunction) Episode(se.michaelthelin.spotify.model_objects.specification.Episode) InvalidCommandException(net.robinfriedli.aiode.exceptions.InvalidCommandException) StringList(net.robinfriedli.stringlist.StringList) SpotifyTrack(net.robinfriedli.aiode.audio.spotify.SpotifyTrack) SpotifyService(net.robinfriedli.aiode.audio.spotify.SpotifyService) StringList(net.robinfriedli.stringlist.StringList) List(java.util.List) SpotifyTrack(net.robinfriedli.aiode.audio.spotify.SpotifyTrack) Track(se.michaelthelin.spotify.model_objects.specification.Track) AudioTrack(com.sedmelluq.discord.lavaplayer.track.AudioTrack) UrlTrack(net.robinfriedli.aiode.entities.UrlTrack)

Example 9 with Episode

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.");
    }
}
Also used : Episode(se.michaelthelin.spotify.model_objects.specification.Episode) CancellationException(java.util.concurrent.CancellationException) CompletionException(java.util.concurrent.CompletionException)

Example 10 with Episode

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);
}
Also used : PlaylistItem(net.robinfriedli.aiode.entities.PlaylistItem) StringList(net.robinfriedli.stringlist.StringList) NoResultsFoundException(net.robinfriedli.aiode.exceptions.NoResultsFoundException) YouTubePlaylist(net.robinfriedli.aiode.audio.youtube.YouTubePlaylist) SpotifyTrack(net.robinfriedli.aiode.audio.spotify.SpotifyTrack) Session(org.hibernate.Session) Episode(se.michaelthelin.spotify.model_objects.specification.Episode) Callable(java.util.concurrent.Callable) ErrorResponse(net.dv8tion.jda.api.requests.ErrorResponse) User(net.dv8tion.jda.api.entities.User) Util(net.robinfriedli.aiode.util.Util) Playlist(net.robinfriedli.aiode.entities.Playlist) AbstractSourceDecidingCommand(net.robinfriedli.aiode.command.commands.AbstractSourceDecidingCommand) YouTubeVideo(net.robinfriedli.aiode.audio.youtube.YouTubeVideo) SearchEngine(net.robinfriedli.aiode.util.SearchEngine) Track(se.michaelthelin.spotify.model_objects.specification.Track) CommandContribution(net.robinfriedli.aiode.entities.xml.CommandContribution) ErrorResponseException(net.dv8tion.jda.api.exceptions.ErrorResponseException) ShardManager(net.dv8tion.jda.api.sharding.ShardManager) UnavailableResourceException(net.robinfriedli.aiode.exceptions.UnavailableResourceException) ArtistSimplified(se.michaelthelin.spotify.model_objects.specification.ArtistSimplified) CommandManager(net.robinfriedli.aiode.command.CommandManager) Collection(java.util.Collection) InvalidCommandException(net.robinfriedli.aiode.exceptions.InvalidCommandException) IOException(java.io.IOException) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) Collectors(java.util.stream.Collectors) NoSpotifyResultsFoundException(net.robinfriedli.aiode.exceptions.NoSpotifyResultsFoundException) StandardCharsets(java.nio.charset.StandardCharsets) Objects(java.util.Objects) Aiode(net.robinfriedli.aiode.Aiode) ShowSimplified(se.michaelthelin.spotify.model_objects.specification.ShowSimplified) URLEncoder(java.net.URLEncoder) List(java.util.List) SpringPropertiesConfig(net.robinfriedli.aiode.boot.SpringPropertiesConfig) CommandContext(net.robinfriedli.aiode.command.CommandContext) PlaylistSimplified(se.michaelthelin.spotify.model_objects.specification.PlaylistSimplified) EmbedTable(net.robinfriedli.aiode.util.EmbedTable) AlbumSimplified(se.michaelthelin.spotify.model_objects.specification.AlbumSimplified) YouTubeService(net.robinfriedli.aiode.audio.youtube.YouTubeService) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) ArtistSimplified(se.michaelthelin.spotify.model_objects.specification.ArtistSimplified)

Aggregations

Episode (se.michaelthelin.spotify.model_objects.specification.Episode)11 List (java.util.List)8 IOException (java.io.IOException)7 StringList (net.robinfriedli.stringlist.StringList)7 Track (se.michaelthelin.spotify.model_objects.specification.Track)7 SpotifyTrack (net.robinfriedli.aiode.audio.spotify.SpotifyTrack)6 AudioTrack (com.sedmelluq.discord.lavaplayer.track.AudioTrack)5 YouTubePlaylist (net.robinfriedli.aiode.audio.youtube.YouTubePlaylist)5 InvalidCommandException (net.robinfriedli.aiode.exceptions.InvalidCommandException)5 AlbumSimplified (se.michaelthelin.spotify.model_objects.specification.AlbumSimplified)5 PlaylistSimplified (se.michaelthelin.spotify.model_objects.specification.PlaylistSimplified)5 AudioPlaylist (com.sedmelluq.discord.lavaplayer.track.AudioPlaylist)4 YouTubeVideo (net.robinfriedli.aiode.audio.youtube.YouTubeVideo)4 NoResultsFoundException (net.robinfriedli.aiode.exceptions.NoResultsFoundException)4 NoSpotifyResultsFoundException (net.robinfriedli.aiode.exceptions.NoSpotifyResultsFoundException)4 ParseException (org.apache.hc.core5.http.ParseException)4 SpotifyWebApiException (se.michaelthelin.spotify.exceptions.SpotifyWebApiException)4 ShowSimplified (se.michaelthelin.spotify.model_objects.specification.ShowSimplified)4 Lists (com.google.common.collect.Lists)3 AudioItem (com.sedmelluq.discord.lavaplayer.track.AudioItem)3