if (iTunesFile != null && (new File(iTunesFile)).exists()) {
iTunesLib = Plist.load(URLDecoder.decode(iTunesFile, System.getProperty("file.encoding"))); // loads the (nested) properties.
Tracks = (Map<?, ?>) iTunesLib.get("Tracks"); // the list of tracks
Playlists = (List<?>) iTunesLib.get("Playlists"); // the list of Playlists
res = new VirtualFolder("iTunes Library", null);
VirtualFolder playlistsFolder = null;
for (Object item : Playlists) {
Playlist = (Map<?, ?>) item;
if (Playlist.containsKey("Visible") && Playlist.get("Visible").equals(Boolean.FALSE))
continue;
if (Playlist.containsKey("Music") && Playlist.get("Music").equals(Boolean.TRUE)) {
// Create virtual folders for artists, albums and genres
VirtualFolder musicFolder = new VirtualFolder(Playlist.get("Name").toString(), null);
res.addChild(musicFolder);
VirtualFolder virtualFolderArtists = new VirtualFolder(Messages.getString("PMS.13"), null);
VirtualFolder virtualFolderAlbums = new VirtualFolder(Messages.getString("PMS.16"), null);
VirtualFolder virtualFolderGenres = new VirtualFolder(Messages.getString("PMS.19"), null);
VirtualFolder virtualFolderAllTracks = new VirtualFolder(Messages.getString("PMS.11"), null);
PlaylistTracks = (List<?>) Playlist.get("Playlist Items"); // list of tracks in a playlist
String artistName;
String albumName;
String genreName;
if (PlaylistTracks != null) {
for (Object t : PlaylistTracks) {
Map<?, ?> td = (Map<?, ?>) t;
track = (Map<?, ?>) Tracks.get(td.get("Track ID").toString());
if (track != null && track.get("Location") != null && track.get("Location").toString().startsWith("file://")) {
String name = Normalizer.normalize((String)track.get("Name"), Normalizer.Form.NFC);
// remove dots from name to prevent media renderer from trimming
name = name.replace('.', '-');
if (track.containsKey("Protected") && track.get("Protected").equals(Boolean.TRUE))
name = String.format(Messages.getString("RootFolder.1"), name);
boolean isCompilation = (track.containsKey("Compilation") && track.get("Compilation").equals(Boolean.TRUE));
artistName = (String) (isCompilation ? "Compilation" :
track.containsKey("Album Artist") ? track.get("Album Artist") : track.get("Artist"));
albumName = (String) track.get("Album");
genreName = (String) track.get("Genre");
if (artistName == null) {
artistName = "Unknown Artist";
} else {
artistName = Normalizer.normalize(artistName, Normalizer.Form.NFC);
}
if (albumName == null) {
albumName = "Unknown Album";
} else {
albumName = Normalizer.normalize(albumName, Normalizer.Form.NFC);
}
if (genreName == null) {
genreName = "Unknown Genre";
} else if ("".equals(genreName.replaceAll("[^a-zA-Z]", ""))) {
// This prevents us from adding blank or numerical genres
genreName = "Unknown Genre";
} else {
genreName = Normalizer.normalize(genreName, Normalizer.Form.NFC);
}
// Replace   with space and then trim
artistName = artistName.replace('\u0160', ' ').trim();
albumName = albumName.replace('\u0160', ' ').trim();
genreName = genreName.replace('\u0160', ' ').trim();
URI tURI2 = new URI(track.get("Location").toString());
File refFile = new File(URLDecoder.decode(tURI2.toURL().getFile(), "UTF-8"));
RealFile file = new RealFile(refFile, name);
// ARTISTS FOLDER - Put the track into the artist's album folder and the artist's "All tracks" folder
{
VirtualFolder individualArtistFolder = null;
VirtualFolder individualArtistAllTracksFolder = null;
VirtualFolder individualArtistAlbumFolder = null;
for (DLNAResource artist : virtualFolderArtists.getChildren()) {
if (areNamesEqual(artist.getName(), artistName)) {
individualArtistFolder = (VirtualFolder) artist;
for (DLNAResource album : individualArtistFolder.getChildren()) {
if (areNamesEqual(album.getName(), albumName)) {
individualArtistAlbumFolder = (VirtualFolder) album;
}
}
break;
}
}
if (individualArtistFolder == null) {
individualArtistFolder = new VirtualFolder(artistName, null);
virtualFolderArtists.addChild(individualArtistFolder);
individualArtistAllTracksFolder = new VirtualFolder(Messages.getString("PMS.11"), null);
individualArtistFolder.addChild(individualArtistAllTracksFolder);
} else {
individualArtistAllTracksFolder = (VirtualFolder)individualArtistFolder.getChildren().get(0);
}
if (individualArtistAlbumFolder == null) {
individualArtistAlbumFolder = new VirtualFolder(albumName, null);
individualArtistFolder.addChild(individualArtistAlbumFolder);
}
individualArtistAlbumFolder.addChild(file.clone());
individualArtistAllTracksFolder.addChild(file);
}
// ALBUMS FOLDER - Put the track into its album folder
{
if (!isCompilation)
albumName += " – " + artistName;
VirtualFolder individualAlbumFolder = null;
for (DLNAResource album : virtualFolderAlbums.getChildren()) {
if (areNamesEqual(album.getName(), albumName)) {
individualAlbumFolder = (VirtualFolder) album;
break;
}
}
if (individualAlbumFolder == null) {
individualAlbumFolder = new VirtualFolder(albumName, null);
virtualFolderAlbums.addChild(individualAlbumFolder);
}
individualAlbumFolder.addChild(file.clone());
}
// GENRES FOLDER - Put the track into its genre folder
{
VirtualFolder individualGenreFolder = null;
for (DLNAResource genre : virtualFolderGenres.getChildren()) {
if (areNamesEqual(genre.getName(), genreName)) {
individualGenreFolder = (VirtualFolder) genre;
break;
}
}
if (individualGenreFolder == null) {
individualGenreFolder = new VirtualFolder(genreName, null);
virtualFolderGenres.addChild(individualGenreFolder);
}
individualGenreFolder.addChild(file.clone());
}
// ALL TRACKS - Put the track into the global "All tracks" folder
virtualFolderAllTracks.addChild(file.clone());
}
}
}
musicFolder.addChild(virtualFolderArtists);
musicFolder.addChild(virtualFolderAlbums);
musicFolder.addChild(virtualFolderGenres);
musicFolder.addChild(virtualFolderAllTracks);
// Sort the virtual folders alphabetically
Collections.sort(virtualFolderArtists.getChildren(), new Comparator<DLNAResource>() {
@Override
public int compare(DLNAResource o1, DLNAResource o2) {
VirtualFolder a = (VirtualFolder) o1;
VirtualFolder b = (VirtualFolder) o2;
return a.getName().compareToIgnoreCase(b.getName());
}
});
Collections.sort(virtualFolderAlbums.getChildren(), new Comparator<DLNAResource>() {
@Override
public int compare(DLNAResource o1, DLNAResource o2) {
VirtualFolder a = (VirtualFolder) o1;
VirtualFolder b = (VirtualFolder) o2;
return a.getName().compareToIgnoreCase(b.getName());
}
});
Collections.sort(virtualFolderGenres.getChildren(), new Comparator<DLNAResource>() {
@Override
public int compare(DLNAResource o1, DLNAResource o2) {
VirtualFolder a = (VirtualFolder) o1;
VirtualFolder b = (VirtualFolder) o2;
return a.getName().compareToIgnoreCase(b.getName());
}
});
} else {
// Add all playlists
VirtualFolder pf = new VirtualFolder(Playlist.get("Name").toString(), null);
PlaylistTracks = (List<?>) Playlist.get("Playlist Items"); // list of tracks in a playlist
if (PlaylistTracks != null) {
for (Object t : PlaylistTracks) {
Map<?, ?> td = (Map<?, ?>) t;
track = (Map<?, ?>) Tracks.get(td.get("Track ID").toString());
if (track != null
&& track.get("Location") != null
&& track.get("Location").toString().startsWith("file://")
) {
String name = Normalizer.normalize(track.get("Name").toString(), Normalizer.Form.NFC);
// remove dots from name to prevent media renderer from trimming
name = name.replace('.', '-');
if (track.containsKey("Protected") && track.get("Protected").equals(Boolean.TRUE))
name = String.format(Messages.getString("RootFolder.1"), name);
URI tURI2 = new URI(track.get("Location").toString());
RealFile file = new RealFile(new File(URLDecoder.decode(tURI2.toURL().getFile(), "UTF-8")), name);
pf.addChild(file);
}
}
}
int kind = Playlist.containsKey("Distinguished Kind") ? ((Number)Playlist.get("Distinguished Kind")).intValue() : -1;
if (kind >= 0 && kind != 17 && kind != 19 && kind != 20) {
// System folder, but not voice memos (17) and purchased items (19 & 20)
res.addChild(pf);
} else {
// User playlist or playlist folder
if (playlistsFolder == null) {
playlistsFolder = new VirtualFolder("Playlists", null);
res.addChild(playlistsFolder);
}
playlistsFolder.addChild(pf);
}
}