/******************************************************************************* * Copyright (c) 2013 Jens Kristian Villadsen. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * * Contributors: * Jens Kristian Villadsen - Lead developer, owner and creator ******************************************************************************/ package org.dyndns.jkiddo.logic.desk; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.util.Calendar; import java.util.Collection; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; import org.apache.tika.exception.TikaException; import org.apache.tika.metadata.Metadata; import org.apache.tika.metadata.TikaCoreProperties; import org.apache.tika.metadata.XMPDM; import org.apache.tika.parser.AutoDetectParser; import org.apache.tika.parser.ParseContext; import org.apache.tika.parser.Parser; import org.apache.tika.sax.BodyContentHandler; import org.dyndns.jkiddo.dmap.chunks.audio.AlbumArtist; import org.dyndns.jkiddo.dmap.chunks.audio.SongAlbum; import org.dyndns.jkiddo.dmap.chunks.audio.SongAlbumId; import org.dyndns.jkiddo.dmap.chunks.audio.SongArtist; import org.dyndns.jkiddo.dmap.chunks.audio.SongArtistId; import org.dyndns.jkiddo.dmap.chunks.audio.SongArtworkCount; import org.dyndns.jkiddo.dmap.chunks.audio.SongBitrate; import org.dyndns.jkiddo.dmap.chunks.audio.SongCodecType; import org.dyndns.jkiddo.dmap.chunks.audio.SongDataKind; import org.dyndns.jkiddo.dmap.chunks.audio.SongDateAdded; import org.dyndns.jkiddo.dmap.chunks.audio.SongDateModified; import org.dyndns.jkiddo.dmap.chunks.audio.SongDescription; import org.dyndns.jkiddo.dmap.chunks.audio.SongExtraData; import org.dyndns.jkiddo.dmap.chunks.audio.SongFormat; import org.dyndns.jkiddo.dmap.chunks.audio.SongGenre; import org.dyndns.jkiddo.dmap.chunks.audio.SongSampleRate; import org.dyndns.jkiddo.dmap.chunks.audio.SongSize; import org.dyndns.jkiddo.dmap.chunks.audio.SongTime; import org.dyndns.jkiddo.dmap.chunks.audio.SortAlbum; import org.dyndns.jkiddo.dmap.chunks.audio.SortAlbumArtist; import org.dyndns.jkiddo.dmap.chunks.audio.SortArtist; import org.dyndns.jkiddo.dmap.chunks.audio.SortName; import org.dyndns.jkiddo.dmap.chunks.audio.extension.ExtendedMediaKind; import org.dyndns.jkiddo.dmap.chunks.audio.extension.MediaKind; import org.dyndns.jkiddo.dmp.chunks.media.ContainerItemId; import org.dyndns.jkiddo.dmp.chunks.media.ItemId; import org.dyndns.jkiddo.dmp.chunks.media.ItemKind; import org.dyndns.jkiddo.dmp.chunks.media.ItemName; import org.dyndns.jkiddo.dmp.chunks.media.Listing; import org.dyndns.jkiddo.dmp.chunks.media.ListingItem; import org.dyndns.jkiddo.dmp.chunks.media.PersistentId; import org.dyndns.jkiddo.dmp.model.MediaItem; import org.dyndns.jkiddo.logic.interfaces.IMusicStoreReader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; import com.google.common.base.Strings; import com.google.common.collect.Lists; public class DeskMusicStoreReader implements IMusicStoreReader { /** * */ private static final Logger LOGGER = LoggerFactory.getLogger(DeskMusicStoreReader.class); private Collection<MediaItem> mapOfSongToFile; private final File path; private final Parser parser; public DeskMusicStoreReader(final String path) { parser = new AutoDetectParser(); this.mapOfSongToFile = Lists.newArrayList(); this.path = new File(path); } public DeskMusicStoreReader(final File path) { parser = new AutoDetectParser(); this.mapOfSongToFile = Lists.newArrayList(); this.path = path; } public DeskMusicStoreReader() { this(System.getProperty("user.dir") + System.getProperty("file.separator") + "etc"); this.mapOfSongToFile = Lists.newArrayList(); } @Override public Collection<MediaItem> readTunes() { try { traverseRootPathRecursively(path); } catch(final Exception e) { LOGGER.info(e.getMessage(), e); } return mapOfSongToFile; } protected void traverseRootPathRecursively(final File f) throws FileNotFoundException, IOException, InterruptedException, SAXException, TikaException { if(f.isDirectory()) { final File[] contents = f.listFiles(); if(contents != null) { for (final File content : contents) { traverseRootPathRecursively(content); } } else LOGGER.debug("Symlink'ish ... " + f.getAbsolutePath()); } else if(isMusic(f)) { mapOfSongToFile.add(populateSong(f)); } } private MediaItem populateSong(final File file) throws IOException, SAXException, TikaException { final BodyContentHandler handler = new BodyContentHandler(); final Metadata metadata = new Metadata(); final InputStream content = new FileInputStream(file); parser.parse(content, handler, metadata, new ParseContext()); final MediaItem song = new MediaItem(); song.setItemName(metadata.get(TikaCoreProperties.TITLE)); if(Strings.isNullOrEmpty(metadata.get(TikaCoreProperties.TITLE))) { song.setItemName(file.getName()); } // song.setGenre(metadata.get(XMPDM.GENRE)); try { // song.setTrackNumber(metadata.getInt(XMPDM.TRACK_NUMBER)); } catch(final Exception e) { LOGGER.debug(e.getMessage(), e); } song.setSongAlbum(metadata.get(XMPDM.ALBUM)); song.setSongArtist(metadata.get(XMPDM.ARTIST)); // song.setComposer(metadata.get(XMPDM.COMPOSER)); // song.setSize(file.length()); try { song.setSongTime((int) Double.parseDouble(metadata.get(XMPDM.DURATION))); } catch(final Exception e) { LOGGER.debug(e.getMessage(), e); } try { final Calendar c = Calendar.getInstance(); c.setTime(metadata.getDate(XMPDM.SHOT_DATE)); // song.setYear(c.get(Calendar.YEAR)); } catch(final Exception e) { LOGGER.debug(e.getMessage(), e); } song.setExternalIdentifer(file.getAbsolutePath()); return song; } private static boolean isMusic(final File f) { if(f.getPath().endsWith(".mp3") || f.getPath().endsWith(".wav")) return true; return false; } @Override public URI getTune(final String tune) throws Exception { return new File(tune).toURI(); } /* * class MusicItem implements IMusicItem { private String artist; private String album; private String title; private long duration; public String getTitle() { return title; } * @Override public String getArtist() { return artist; } * @Override public String getAlbum() { return album; } * @Override public void setArtist(String artist) { this.artist = artist; } * @Override public void setAlbum(String album) { this.album = album; } * @Override public void setTitle(String title) { this.title = title; } * @Override public void setComposer(String composer) { // TODO Auto-generated method stub } * @Override public void setGenre(String genre) { // TODO Auto-generated method stub } * @Override public void setTrackNumber(int trackNumber) { // TODO Auto-generated method stub } * @Override public void setYear(int Year) { // TODO Auto-generated method stub } * @Override public void setSize(long size) { // TODO Auto-generated method stub } * @Override public long getSize() { // TODO Auto-generated method stub return 0; } * @Override public long getDuration() { return duration; } * @Override public void setDuration(long value) { duration = value; } } */ @Override public void readTunesMemoryOptimized(final Listing listing, final Map<Long, String> map) throws Exception { final Collection<MediaItem> songs = readTunes(); System.gc(); final AtomicLong id = new AtomicLong(1); for(final MediaItem song : songs) { final ListingItem item = new ListingItem(); item.add(new ItemKind(ItemKind.AUDIO)); item.add(new SongDataKind(SongDataKind.UNKNOWN)); item.add(new SongArtist(song.getSongArtist())); item.add(new SongArtistId(666)); item.add(new SongSize(0x430000)); item.add(new SongTime(1000)); item.add(new SongDateAdded(403958)); item.add(new ItemName(song.getItemName())); item.add(new SongGenre("Other")); item.add(new ContainerItemId(id.get())); item.add(new ItemId(id.get())); item.add(new SongSampleRate(SongSampleRate.KHZ_44100)); item.add(new SongDescription("MPEG audio file")); item.add(new SongAlbum(song.getSongAlbum())); item.add(new SongAlbumId(123456)); item.add(new SongBitrate(0x80)); item.add(new ExtendedMediaKind(ExtendedMediaKind.UNKNOWN_ONE)); item.add(new AlbumArtist("Unknown")); item.add(new SortArtist("WonderWall")); item.add(new SongDateModified(123456)); item.add(new SortName("Unknown")); item.add(new SongCodecType(SongCodecType.MPEG)); item.add(new PersistentId(id.get())); item.add(new MediaKind(MediaKind.KIND_1)); item.add(new SortAlbum("")); item.add(new SongFormat(SongFormat.MP3)); item.add(new SortAlbumArtist("unknown")); item.add(new SongExtraData(1)); item.add(new SongArtworkCount(1)); listing.add(item); map.put(Long.valueOf(id.getAndIncrement()), song.getExternalIdentifer()); } songs.clear(); } }