Implemented adding songs to playlist
\+ Creation of playlist with default name \+ implemented track search (opens #2) \+ Implemented adding tracks to list \+ Implemented setting custom playlist cover - Missing ability to select file to upload as cover (opens #3) - Missing saving and retrieving auth tokens for use in chron jobs + flag to enable (opens #4) - Known issue: some tracks cannot be found, although they were played on spotify to be scrobbled onto lastfm (see #2) - Missing flag to set a custom playlist name (opens #5) - missing flags to make playlists public and/or collaborative on creation. (opens #6)
This commit is contained in:
@@ -1,15 +1,26 @@
|
|||||||
package de.b00tload.tools.lastfmtospotifyplaylist;
|
package de.b00tload.tools.lastfmtospotifyplaylist;
|
||||||
|
|
||||||
|
|
||||||
|
import com.neovisionaries.i18n.CountryCode;
|
||||||
import de.b00tload.tools.lastfmtospotifyplaylist.arguments.ArgumentHandler;
|
import de.b00tload.tools.lastfmtospotifyplaylist.arguments.ArgumentHandler;
|
||||||
import de.b00tload.tools.lastfmtospotifyplaylist.arguments.Arguments;
|
import de.b00tload.tools.lastfmtospotifyplaylist.arguments.Arguments;
|
||||||
import de.b00tload.tools.lastfmtospotifyplaylist.util.PeriodHelper;
|
import de.b00tload.tools.lastfmtospotifyplaylist.util.PeriodHelper;
|
||||||
|
import de.b00tload.tools.lastfmtospotifyplaylist.util.TokenHelper;
|
||||||
import de.umass.lastfm.Caller;
|
import de.umass.lastfm.Caller;
|
||||||
import de.umass.lastfm.Track;
|
import de.umass.lastfm.Track;
|
||||||
import de.umass.lastfm.User;
|
import de.umass.lastfm.User;
|
||||||
|
import io.javalin.Javalin;
|
||||||
|
import io.javalin.http.ContentType;
|
||||||
|
import se.michaelthelin.spotify.SpotifyApi;
|
||||||
|
import se.michaelthelin.spotify.model_objects.credentials.AuthorizationCodeCredentials;
|
||||||
|
import se.michaelthelin.spotify.model_objects.specification.Playlist;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.net.URI;
|
||||||
import java.util.HashMap;
|
import java.time.Clock;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import static de.b00tload.tools.lastfmtospotifyplaylist.util.Logger.logLn;
|
import static de.b00tload.tools.lastfmtospotifyplaylist.util.Logger.logLn;
|
||||||
|
|
||||||
@@ -22,6 +33,7 @@ public class LastFMToSpotify {
|
|||||||
// create hash map with user agent
|
// create hash map with user agent
|
||||||
configuration = new HashMap<>();
|
configuration = new HashMap<>();
|
||||||
configuration.put("requests.useragent", "LastFMToSpotify/1.0-Snapshot (" + System.getProperty("os.name") + "; " + System.getProperty("os.arch") + ") Java/" + System.getProperty("java.version"));
|
configuration.put("requests.useragent", "LastFMToSpotify/1.0-Snapshot (" + System.getProperty("os.name") + "; " + System.getProperty("os.arch") + ") Java/" + System.getProperty("java.version"));
|
||||||
|
configuration.put("playlist.name", "LastFMToSpotify@" + LocalDateTime.now(Clock.systemDefaultZone()).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
|
||||||
// parse arguments
|
// parse arguments
|
||||||
for (int a = 0; a < args.length; a++) {
|
for (int a = 0; a < args.length; a++) {
|
||||||
Arguments arg;
|
Arguments arg;
|
||||||
@@ -49,28 +61,60 @@ public class LastFMToSpotify {
|
|||||||
// Start Progress Bar
|
// Start Progress Bar
|
||||||
try {
|
try {
|
||||||
logLn("Authenticating with Spotify...", 1);
|
logLn("Authenticating with Spotify...", 1);
|
||||||
|
SpotifyApi.Builder build = SpotifyApi.builder();
|
||||||
|
build.setClientId(configuration.get("spotify.clientid"));
|
||||||
|
build.setClientSecret(configuration.get("spotify.secret"));
|
||||||
|
build.setRedirectUri(URI.create("http://localhost:9876/callback/spotify/"));
|
||||||
|
SpotifyApi api = build.build();
|
||||||
|
AtomicBoolean waiting = new AtomicBoolean(true);
|
||||||
|
try (Javalin webserver = Javalin.create().start(9876)) {
|
||||||
|
webserver.get("/callback/spotify", ctx -> {
|
||||||
|
if(ctx.queryParamMap().containsKey("code")) {
|
||||||
|
AuthorizationCodeCredentials cred = api.authorizationCode(ctx.queryParam("code")).build().execute();
|
||||||
|
configuration.put("spotify.access", cred.getAccessToken());
|
||||||
|
if(configuration.containsKey("spotify.saveaccess")) TokenHelper.saveTokens(cred);
|
||||||
|
ctx.result("success. <script>window.close()</script>").contentType(ContentType.TEXT_HTML);
|
||||||
|
waiting.set(false);
|
||||||
|
} else {
|
||||||
|
logLn("Error: Spotify authorization failed."+LINE_SEPERATOR+ctx.queryParam("error"), 1);
|
||||||
|
System.exit(500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
logLn("Waiting for Spotify authorization.", 1);
|
||||||
|
//TODO: Open auth page in Browser
|
||||||
|
while (waiting.get());
|
||||||
|
webserver.stop();
|
||||||
|
}
|
||||||
logLn("Authenticating with LastFM...", 1);
|
logLn("Authenticating with LastFM...", 1);
|
||||||
Caller.getInstance().setUserAgent(configuration.get("requests.useragent"));
|
Caller.getInstance().setUserAgent(configuration.get("requests.useragent"));
|
||||||
logLn(User.getInfo(configuration.get("lastfm.user"), configuration.get("lastfm.apikey")).getName(), 1);
|
logLn(User.getInfo(configuration.get("lastfm.user"), configuration.get("lastfm.apikey")).getName(), 1);
|
||||||
logLn("Reading from LastFM...", 1);
|
logLn("Reading from LastFM...", 1);
|
||||||
Collection<Track> tracks = User.getTopTracks(configuration.get("lastfm.user"), PeriodHelper.getPeriodByString(configuration.get("lastfm.period")), configuration.get("lastfm.apikey"));
|
Collection<Track> tracks = User.getTopTracks(configuration.get("lastfm.user"), PeriodHelper.getPeriodByString(configuration.get("lastfm.period")), configuration.get("lastfm.apikey"));
|
||||||
for (Track track : tracks) {
|
|
||||||
logLn(track.getName() + " by " + track.getArtist(), 3);
|
|
||||||
}
|
|
||||||
logLn("Creating Playlist...", 1);
|
logLn("Creating Playlist...", 1);
|
||||||
//SpotifyApi.Builder build = SpotifyApi.builder();
|
api.setAccessToken(configuration.get("spotify.access"));
|
||||||
//build.setClientId(configuration.get("spotify.clientid"));
|
Playlist list = api.createPlaylist(api.getCurrentUsersProfile().build().execute().getId(), configuration.get("playlist.name")).public_(configuration.containsKey("playlist.public")||configuration.containsKey("playlist.collab")).collaborative(configuration.containsKey("playlist.collab")).setHeader("User-Agent", configuration.get("requests.useragent")).build().execute();
|
||||||
//build.setClientSecret(configuration.get("spotify.secret"));
|
List<String> adders = new LinkedList<>();
|
||||||
//build.setRedirectUri(URI.create("http://localhost:9876/callback/spotify/"));
|
for (Track track : tracks) {
|
||||||
//SpotifyApi api = build.build();
|
logLn("Adding " + track.getName() + " by " + track.getArtist(), 3);
|
||||||
//api.setAccessToken(configuration.get("spotify.access"));
|
StringBuilder searchQuery = new StringBuilder();
|
||||||
//api.createPlaylist(api.getCurrentUsersProfile().build().execute().getId(), configuration.get("playlist.name")).setHeader("User-Agent", configuration.get("requests.useragent"));
|
searchQuery.append("track:").append(track.getName());
|
||||||
|
searchQuery.append(" artist:").append(track.getArtist());
|
||||||
|
if(track.getAlbum()!=null&&!track.getAlbum().equalsIgnoreCase("null")&&!track.getAlbum().isEmpty())
|
||||||
|
searchQuery.append(" album:").append(track.getAlbum());
|
||||||
|
logLn("Search query: " + searchQuery.toString(), 3);
|
||||||
|
se.michaelthelin.spotify.model_objects.specification.Track[] add = api.searchTracks(searchQuery.toString()).market(CountryCode.DE).setHeader("User-Agent", configuration.get("requests.useragent")).build().execute().getItems();
|
||||||
|
if(add.length!=0) {
|
||||||
|
adders.add(add[0].getUri());
|
||||||
|
logLn("Added " + add[0].getName() + " to " + configuration.get("playlist.name"), 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
api.addItemsToPlaylist(list.getId(), adders.toArray(String[]::new)).build().execute();
|
||||||
|
if(configuration.containsKey(configuration.get("playlist.cover"))) api.uploadCustomPlaylistCoverImage(list.getId()).image_data(configuration.get("playlist.cover")).build().execute();
|
||||||
logLn("Done.", 1);
|
logLn("Done.", 1);
|
||||||
// } catch (IOException | ParseException | SpotifyWebApiException e) {
|
// } catch (IOException | ParseException | SpotifyWebApiException e) {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
//TODO: Implement
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package de.b00tload.tools.lastfmtospotifyplaylist.util;
|
||||||
|
|
||||||
|
import se.michaelthelin.spotify.model_objects.credentials.AuthorizationCodeCredentials;
|
||||||
|
|
||||||
|
public class TokenHelper {
|
||||||
|
public static void saveTokens(AuthorizationCodeCredentials cred) {
|
||||||
|
//TODO: Save tokens
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getAccessToken(){
|
||||||
|
//TODO: Read AccessToken
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getRefreshToken(){
|
||||||
|
//TODO: Read RefreshToken
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user