Implemented Playlist naming

closes #5
Also did a minor fix to the playlist building system, where sometimes a different version of the track was selected. Now Track titles have to match.
This commit is contained in:
2023-01-24 04:40:04 +01:00
parent b7830190c6
commit cadb4a98b3
4 changed files with 90 additions and 4 deletions

View File

@@ -5,6 +5,7 @@ import com.neovisionaries.i18n.CountryCode;
import de.b00tload.tools.lastfmtospotifyplaylist.arguments.ArgumentHandler;
import de.b00tload.tools.lastfmtospotifyplaylist.arguments.Arguments;
import de.b00tload.tools.lastfmtospotifyplaylist.util.PeriodHelper;
import de.b00tload.tools.lastfmtospotifyplaylist.util.TimeHelper;
import de.b00tload.tools.lastfmtospotifyplaylist.util.TokenHelper;
import de.umass.lastfm.Caller;
import de.umass.lastfm.Track;
@@ -31,7 +32,7 @@ public class LastFMToSpotify {
public static HashMap<String, String> configuration;
public static void main(String[] args) {
// create hash map with user agent
// create hash map with user agent and default playlist name
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("playlist.name", "LastFMToSpotify@" + LocalDateTime.now(Clock.systemDefaultZone()).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
@@ -105,8 +106,15 @@ public class LastFMToSpotify {
logLn("Search query: " + searchQuery, 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);
// adders.add(add[0].getUri());
// logLn("Added " + add[0].getName() + " to " + configuration.get("playlist.name"), 3);
for(se.michaelthelin.spotify.model_objects.specification.Track t : add){
if(t.getName().equalsIgnoreCase(track.getName())){
adders.add(t.getUri());
logLn("Added " + add[0].getName() + " to " + configuration.get("playlist.name"), 3);
break;
}
}
}
}
api.addItemsToPlaylist(list.getId(), adders.toArray(String[]::new)).build().execute();

View File

@@ -1,12 +1,22 @@
package de.b00tload.tools.lastfmtospotifyplaylist.arguments;
import de.b00tload.tools.lastfmtospotifyplaylist.util.FileHelper;
import de.b00tload.tools.lastfmtospotifyplaylist.util.TimeHelper;
import de.umass.lastfm.Period;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Clock;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.TextStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.IsoFields;
import java.time.temporal.TemporalField;
import java.time.temporal.WeekFields;
import java.util.Locale;
import static de.b00tload.tools.lastfmtospotifyplaylist.LastFMToSpotify.LINE_SEPERATOR;
import static de.b00tload.tools.lastfmtospotifyplaylist.LastFMToSpotify.configuration;
@@ -28,6 +38,7 @@ public class ArgumentHandler {
case BIANNUALLY -> period(Period.SIX_MONTHS);
case YEARLY -> period(Period.TWELVE_MONTHS);
case COVER -> cover(value);
case NAME -> name(value);
}
}
@@ -127,4 +138,43 @@ public class ArgumentHandler {
String base64 = FileHelper.encodeFileToBase64(new File(value.replace("\\", "//")));
configuration.put("playlist.cover", base64);
}
private static void name(String value) {
if (value == null || value.equalsIgnoreCase("")) {
System.out.println("--playlistname must be provided with a playlist name. Check usage: " + Arguments.NAME.getUsage());
System.exit(500);
}
LocalDateTime now = LocalDateTime.now(Clock.systemDefaultZone());
Locale loc = Locale.forLanguageTag(System.getProperty("user.country"));
if(value.matches("(%\\$-?\\d*\\$).*")){
int offsetDays = Integer.parseInt(value.substring(2).split("\\$")[0]);
now = offsetDays < 0 ? now.minusDays(Math.abs(offsetDays)) : now.plusDays(Math.abs(offsetDays));
}
String name = value.replace("%YYYY", String.valueOf(now.getYear())).replace("%YY", String.valueOf(now.getYear()).substring(2))
.replace("%MMMM", now.getMonth().name().charAt(0) + now.getMonth().name().toLowerCase().substring(1))
.replace("%MMM", now.getMonth().getDisplayName(TextStyle.FULL, loc))
.replace("%MM", (String.valueOf(now.getMonth().getValue()).length() == 1 ? "0" + now.getMonth().getValue() : String.valueOf(now.getMonth().getValue())))
.replace("%M", String.valueOf(now.getMonth().getValue()))
.replace("%DD", (String.valueOf(now.getDayOfMonth()).length() == 1 ? "0" + now.getDayOfMonth() : String.valueOf(now.getDayOfMonth())))
.replace("%D", String.valueOf(now.getDayOfMonth()))
.replace("%DDDD", now.getDayOfWeek().getDisplayName(TextStyle.FULL, loc))
.replace("%DDD", now.getDayOfWeek().getDisplayName(TextStyle.SHORT, loc))
.replace("%WW", (String.valueOf(now.get(WeekFields.of(loc).weekOfWeekBasedYear())).length() == 1 ? "0" + now.get(WeekFields.of(loc).weekOfWeekBasedYear()) : String.valueOf(now.get(WeekFields.of(loc).weekOfWeekBasedYear()))))
.replace("%W", String.valueOf(now.get(WeekFields.of(loc).weekOfWeekBasedYear())))
.replace("%HH", (String.valueOf(now.get(ChronoField.HOUR_OF_DAY)).length() == 1 ? "0" + now.get(ChronoField.HOUR_OF_DAY) : String.valueOf(now.get(ChronoField.HOUR_OF_DAY))))
.replace("%H", String.valueOf(now.get(ChronoField.HOUR_OF_DAY)))
.replace("%hh", (String.valueOf(now.get(ChronoField.HOUR_OF_AMPM)).length() == 1 ? "0" + now.get(ChronoField.HOUR_OF_AMPM) : String.valueOf(now.get(ChronoField.HOUR_OF_AMPM))))
.replace("%h", String.valueOf(now.get(ChronoField.HOUR_OF_AMPM)))
.replace("%P", now.get(ChronoField.AMPM_OF_DAY)==0 ? "AM" : "PM")
.replace("%p", now.get(ChronoField.AMPM_OF_DAY)==0 ? "am" : "pm")
.replace("%mm", (String.valueOf(now.getMinute()).length() == 1 ? "0" + now.getMinute() : String.valueOf(now.getMinute())))
.replace("%m", String.valueOf(now.getMinute()))
.replace("%ss", (String.valueOf(now.getSecond()).length() == 1 ? "0" + now.getSecond() : String.valueOf(now.getSecond())))
.replace("%s", String.valueOf(now.getSecond()))
.replace("%o", TimeHelper.getUTCOffset(now))
.replaceAll("%\\$-?\\d*\\$", "")
.replace("%%", "%");
configuration.put("playlist.name", name);
}
}

View File

@@ -35,7 +35,9 @@ public enum Arguments {
YEARLY("yearly", "[Optional]" + LINE_SEPERATOR
+ "Creates a playlist from your top tracks from last year.", "--anually", "A"),
COVER("coverart", "[Optional]" + LINE_SEPERATOR
+ "Will set a cover art for the playlist. Must be jpeg/jpg.", "--coverart <path/to/coverart.jpg>", "ca", "cover");
+ "Will set a cover art for the playlist. Must be jpeg/jpg.", "--coverart <path/to/coverart.jpg>", "ca", "cover"),
NAME("playlistname", "[Optional]" + LINE_SEPERATOR
+ "Sets the playlist name. Supports templating. Refer to https://github.com/B00tLoad/LastFMtoSpotifyPlaylist/wiki/Filename-Templating.", "--playlistname <name>", "pName", "pN");
private final String name;
private final String description;

View File

@@ -0,0 +1,26 @@
package de.b00tload.tools.lastfmtospotifyplaylist.util;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
public class TimeHelper {
public static int getUTCOffsetHours(LocalDateTime now){
return (int) Math.floor((double) now.atZone(ZoneId.systemDefault()).getOffset().getTotalSeconds()/3600);
}
public static int getUTCOffsetMinutes(LocalDateTime now){
return (now.atZone(ZoneId.systemDefault()).getOffset().getTotalSeconds()/60);
}
public static String getUTCOffset(LocalDateTime now){
int hour = getUTCOffsetHours(now);
String h = (hour == Math.abs(hour) ? "+" : "-") + (String.valueOf(Math.abs(hour)).length() == 1 ? "0" + Math.abs(hour) : String.valueOf(Math.abs(hour)));
int min = Math.abs(getUTCOffsetMinutes(now))-(Math.abs(hour)*60);
String m = (String.valueOf(Math.abs(min)).length() == 1 ? "0" + Math.abs(min) : String.valueOf(Math.abs(min)));
return h + ":" + m;
}
}