diff --git a/README.md b/README.md index 80c5406b..cef7f06c 100644 --- a/README.md +++ b/README.md @@ -243,6 +243,7 @@ plugins: countryCode: "US" # the country code you want to use for filtering the artists top tracks. See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 playlistLoadLimit: 6 # The number of pages at 100 tracks each albumLoadLimit: 6 # The number of pages at 50 tracks each + localFiles: false # Enable local files support with Spotify playlists. Please note `uri` & `iscr` will be `null` & `identifier` will be `"local"` applemusic: countryCode: "US" # the country code you want to use for filtering the artists top tracks and language. See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 mediaAPIToken: "your apple music api token" # apple music api token @@ -316,7 +317,7 @@ LavaSrc adds the following fields to tracks & playlists in Lavalink (check out [Spotify Recommendations Docs](https://developer.spotify.com/documentation/web-api/reference/get-recommendations) for the full query parameter list) * https://open.spotify.com/track/0eG08cBeKk0mzykKjw4hcQ * https://open.spotify.com/album/7qemUq4n71awwVPOaX7jw4 -* https://open.spotify.com/playlist/7HAO9R9v203gkaPAgknOMp +* https://open.spotify.com/playlist/7HAO9R9v203gkaPAgknOMp (playlists can include local files if you enabled this via: `plugins.lavasrc.spotify.localFiles: true`. Please note `uri` & `iscr` will be `null` & `identifier` will be `"local"`) * https://open.spotify.com/artist/3ZztVuWxHzNpl0THurTFCv (including new regional links like https://open.spotify.com/intl-de/track/0eG08cBeKk0mzykKjw4hcQ) diff --git a/application.example.yml b/application.example.yml index f6fa10a9..dd416b0d 100644 --- a/application.example.yml +++ b/application.example.yml @@ -25,6 +25,7 @@ plugins: countryCode: "US" # the country code you want to use for filtering the artists top tracks. See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 playlistLoadLimit: 6 # The number of pages at 100 tracks each albumLoadLimit: 6 # The number of pages at 50 tracks each + localFiles: false # Enable local files support with Spotify playlists. Please note `uri` & `iscr` will be `null` & `identifier` will be `"local"` applemusic: countryCode: "US" # the country code you want to use for filtering the artists top tracks and language. See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 mediaAPIToken: "..." # apple music api token diff --git a/main/src/main/java/com/github/topi314/lavasrc/spotify/SpotifyAudioTrack.java b/main/src/main/java/com/github/topi314/lavasrc/spotify/SpotifyAudioTrack.java index 6ed0808f..b6323e48 100644 --- a/main/src/main/java/com/github/topi314/lavasrc/spotify/SpotifyAudioTrack.java +++ b/main/src/main/java/com/github/topi314/lavasrc/spotify/SpotifyAudioTrack.java @@ -29,4 +29,8 @@ protected AudioTrack makeShallowClone() { return new SpotifyAudioTrack(this.trackInfo, (SpotifySourceManager) this.sourceManager); } + public boolean isLocal() { + return this.trackInfo.identifier.equals("local"); + } + } diff --git a/main/src/main/java/com/github/topi314/lavasrc/spotify/SpotifySourceManager.java b/main/src/main/java/com/github/topi314/lavasrc/spotify/SpotifySourceManager.java index fdd0ca19..f7b20a59 100644 --- a/main/src/main/java/com/github/topi314/lavasrc/spotify/SpotifySourceManager.java +++ b/main/src/main/java/com/github/topi314/lavasrc/spotify/SpotifySourceManager.java @@ -59,6 +59,7 @@ public class SpotifySourceManager extends MirroringAudioSourceManager implements private final String countryCode; private int playlistPageLimit = 6; private int albumPageLimit = 6; + private boolean localFiles; private String spToken; private Instant spTokenExpire; @@ -99,6 +100,10 @@ public void setAlbumPageLimit(int albumPageLimit) { this.albumPageLimit = albumPageLimit; } + public void setLocalFiles(boolean localFiles) { + this.localFiles = localFiles; + } + @NotNull @Override public String getSourceName() { @@ -422,9 +427,10 @@ public AudioItem getPlaylist(String id, boolean preview) throws IOException { for (var value : page.get("items").values()) { var track = value.get("track"); - if (track.isNull() || track.get("is_local").asBoolean(false) || track.get("type").text().equals("episode")) { + if (track.isNull() || track.get("type").text().equals("episode") || (!this.localFiles && track.get("is_local").asBoolean(false))) { continue; } + tracks.add(this.parseTrack(track, preview)); } @@ -493,9 +499,9 @@ private AudioTrack parseTrack(JsonBrowser json, boolean preview) { return new SpotifyAudioTrack( new AudioTrackInfo( json.get("name").text(), - json.get("artists").index(0).get("name").text(), + json.get("artists").index(0).get("name").text().isEmpty() ? "Unknown" : json.get("artists").index(0).get("name").text(), preview ? PREVIEW_LENGTH : json.get("duration_ms").asLong(0), - json.get("id").text(), + json.get("id").text() != null ? json.get("id").text() : "local", false, json.get("external_urls").get("spotify").text(), json.get("album").get("images").index(0).get("url").text(), diff --git a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/LavaSrcAudioPluginInfoModifier.java b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/LavaSrcAudioPluginInfoModifier.java index bf9ce386..3a32aa88 100644 --- a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/LavaSrcAudioPluginInfoModifier.java +++ b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/LavaSrcAudioPluginInfoModifier.java @@ -2,6 +2,7 @@ import com.github.topi314.lavasrc.ExtendedAudioPlaylist; import com.github.topi314.lavasrc.ExtendedAudioTrack; +import com.github.topi314.lavasrc.spotify.SpotifyAudioTrack; import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; import com.sedmelluq.discord.lavaplayer.track.AudioTrack; import dev.arbjerg.lavalink.api.AudioPluginInfoModifier; @@ -12,6 +13,7 @@ import org.springframework.stereotype.Component; import java.util.Map; +import java.util.HashMap; @Component public class LavaSrcAudioPluginInfoModifier implements AudioPluginInfoModifier { @@ -31,19 +33,24 @@ public JsonObject modifyAudioPlaylistPluginInfo(@NotNull AudioPlaylist playlist) } @Nullable - @Override - public JsonObject modifyAudioTrackPluginInfo(@NotNull AudioTrack track) { - if (track instanceof ExtendedAudioTrack extendedTrack) { - return new JsonObject(Map.of( - "albumName", JsonElementKt.JsonPrimitive(extendedTrack.getAlbumName()), - "albumUrl", JsonElementKt.JsonPrimitive(extendedTrack.getAlbumUrl()), - "artistUrl", JsonElementKt.JsonPrimitive(extendedTrack.getArtistUrl()), - "artistArtworkUrl", JsonElementKt.JsonPrimitive(extendedTrack.getArtistArtworkUrl()), - "previewUrl", JsonElementKt.JsonPrimitive(extendedTrack.getPreviewUrl()), - "isPreview", JsonElementKt.JsonPrimitive(extendedTrack.isPreview()) + @Override + public JsonObject modifyAudioTrackPluginInfo(@NotNull AudioTrack track) { + if (track instanceof ExtendedAudioTrack extendedTrack) { + var json = new HashMap<>(Map.of( + "albumName", JsonElementKt.JsonPrimitive(extendedTrack.getAlbumName()), + "albumUrl", JsonElementKt.JsonPrimitive(extendedTrack.getAlbumUrl()), + "artistUrl", JsonElementKt.JsonPrimitive(extendedTrack.getArtistUrl()), + "artistArtworkUrl", JsonElementKt.JsonPrimitive(extendedTrack.getArtistArtworkUrl()), + "previewUrl", JsonElementKt.JsonPrimitive(extendedTrack.getPreviewUrl()), + "isPreview", JsonElementKt.JsonPrimitive(extendedTrack.isPreview()) + )); - )); - } - return null; - } + if (track instanceof SpotifyAudioTrack spotifyTrack) { + json.put("isLocal", JsonElementKt.JsonPrimitive(spotifyTrack.isLocal())); + } + + return new JsonObject(json); + } + return null; + } } diff --git a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/LavaSrcPlugin.java b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/LavaSrcPlugin.java index 04c88809..3cc28399 100644 --- a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/LavaSrcPlugin.java +++ b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/LavaSrcPlugin.java @@ -46,6 +46,9 @@ public LavaSrcPlugin(LavaSrcConfig pluginConfig, SourcesConfig sourcesConfig, Ly if (spotifyConfig.getAlbumLoadLimit() > 0) { this.spotify.setAlbumPageLimit(spotifyConfig.getAlbumLoadLimit()); } + if(spotifyConfig.isLocalFiles()) { + this.spotify.setLocalFiles(spotifyConfig.isLocalFiles()); + } } if (sourcesConfig.isAppleMusic()) { this.appleMusic = new AppleMusicSourceManager(pluginConfig.getProviders(), appleMusicConfig.getMediaAPIToken(), appleMusicConfig.getCountryCode(), unused -> manager); @@ -153,7 +156,7 @@ public SearchManager configure(@NotNull SearchManager manager) { } if (this.yandexMusic != null && this.sourcesConfig.isYandexMusic()) { log.info("Registering Yandex Music search manager..."); - manager.registerSearchManager(this.yandexMusic); + manager.registerSearchManager(this.yandexMusic); } return manager; } diff --git a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/SpotifyConfig.java b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/SpotifyConfig.java index aa012ca0..42b71080 100644 --- a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/SpotifyConfig.java +++ b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/SpotifyConfig.java @@ -13,6 +13,7 @@ public class SpotifyConfig { private String countryCode = "US"; private int playlistLoadLimit = 6; private int albumLoadLimit = 6; + private boolean localFiles = false; public String getClientId() { return this.clientId; @@ -62,4 +63,11 @@ public void setAlbumLoadLimit(int albumLoadLimit) { this.albumLoadLimit = albumLoadLimit; } + public boolean isLocalFiles() { + return this.localFiles; + } + + public void setLocalFiles(boolean localFiles) { + this.localFiles = localFiles; + } }