package model.collector.lastfm; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.stream.XMLStreamException; import logging.LogUtil; import model.audio.Genres; import model.collector.Album; import model.collector.Track; import model.collector.interfaces.IID3DataCollector; import model.exception.CollectorException; import model.structure.ID3TagData; import model.util.Util; public class LastfmTrackCollector implements IID3DataCollector { /** * the logger */ private final Logger logger = Logger.getLogger(this.getClass().getName()); /** * the song title */ private String title; /** * the song artist */ private String artist; /** * the album where this song is in */ private String album; /** * the track */ private Track theTrack; /** * the album */ private Album theAlbum; /** * true if track data could be found, else false */ private boolean isFound; /** * the API key */ private String apiKey = "92da8a4f1911c555fde3b4985e3682c0"; /** * the API track url */ private String trackURL = "http://ws.audioscrobbler.com/2.0/?method=track.getInfo&api_key=" + apiKey + "&artist={0}&track={1}"; /** * the API album url */ private String albumURL = "http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=" + apiKey + "&artist={0}&album={1}"; /** * Constructor * * @param apiKey * the api key */ public LastfmTrackCollector(String apiKey) { this(); this.apiKey = apiKey; } /** * Constructor */ public LastfmTrackCollector() { this.title = null; this.artist = null; this.album = null; this.theTrack = new Track(); this.theAlbum = new Album(); this.isFound = false; } /* * (non-Javadoc) * * @see model.collector.interfaces.ICollector#getCollectorName() */ @Override public String getCollectorName() { return "Lastfm"; } /* * (non-Javadoc) * * @see model.collector.interfaces.ICollector#init() */ @Override public void init() throws CollectorException { try { // search for track information if (this.title != null && this.artist != null && this.title.trim().length() != 0 && this.artist.trim().length() != 0) { XMLTrackParser p = new XMLTrackParser(this.trackURL.replace("{0}", this.artist).replace("{1}", this.title)); this.theTrack = p.getTrack(); if ((this.album == null || this.album.trim().length() == 0) && this.theTrack.getAlbum() != null && this.theTrack.getAlbum().trim().length() != 0) this.album = replaceSpecialCharacters(this.theTrack.getAlbum()); if (this.theTrack != null) this.isFound = true; } // search for album information if (this.artist != null && this.album != null && this.album.trim().length() != 0 && this.artist.trim().length() != 0) { String cache = (this.artist + this.album).toLowerCase(); this.theAlbum = Cache.getAlbum(cache); logger.log(Level.FINER, "Album: " + this.album + " artist: " + this.artist + " cached: " + (this.theAlbum != null)); if (this.theAlbum == null) { XMLAlbumParser p = new XMLAlbumParser(this.albumURL.replace("{0}", this.artist).replace("{1}", this.album)); this.theAlbum = p.getAlbum(); Cache.addAlbum(this.artist + this.album, this.theAlbum); } } } catch (XMLStreamException | IOException e) { logger.log(Level.SEVERE, "Error while getting id3 data:\n" + LogUtil.getStackTrace(e), e); throw new CollectorException("Error while parsing"); } } /* * (non-Javadoc) * * @see model.collector.interfaces.ICollector#isDataFound() */ @Override public boolean isDataFound() { return this.isFound; } /** * replaces some special characters with its ascii codes * * @param str * given string * * @return modified string */ private String replaceSpecialCharacters(String str) { str = str.replace("_", ""); str = str.replace(" ", "%20"); str = str.replace("'", "%27"); str = str.replace("&", "%26"); return str; } /** * pads the first number to the same digits as the 2nd num e.g. 5 and 10 * given, result would be 05 * * @param num1 * first num, the num which will be padded * @param num2 * the second num * * @return the padded number */ private String padNumbers(int num1, int num2) { String result = Integer.toString(num1); while (result.length() < Integer.toString(num2).length()) result = "0" + result; return result; } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getTitle() */ @Override public String getTitle() { return this.theTrack.getTitle(); } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getArtist() */ @Override public String getArtist() { return this.theTrack.getArtist(); } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getAlbumArtist() */ @Override public String getAlbumArtist() { return this.theTrack.getArtist(); } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getAlbum() */ @Override public String getAlbum() { return this.theAlbum.getName(); } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getYear() */ @Override public String getYear() { return this.theAlbum.getYear(); } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getTrack() */ @Override public String getTrack() { if (this.theTrack.getTrackNr() == -1) return searchTrackNr(); return searchTrackNr(padNumbers(this.theTrack.getTrackNr(), this.theAlbum.getMaxTracks())); } /** * searches the track depending on the * * @param num * given padded track number which will be the default value of * no number in the list of tracks can be found * * @return the track number of this track in this album */ private String searchTrackNr(String num) { String result = searchTrackNr(); if (num == null) return num; return result; } /** * searches the album tracks for this song and returns the track number of * this track in this album * * @return the track number */ private String searchTrackNr() { for (Track track : this.theAlbum.getTracks()) { logger.log(Level.FINER, "search Track: " + this.theTrack.getTitle() + "(" + this.theTrack.getMatchLength() + ") current: " + track.getTitle() + "(" + track.getTitle().length() + ")"); // to compare the tracks replace all special characters like ' and ´ // to get better results if (removeSpecialcharacters(track.getTitle()).toLowerCase().trim().contains(removeSpecialcharacters(this.theTrack.getTitle()).toLowerCase().trim())) { // check if the current title is shorter than the old title, if // so -> new title, else not new title // if (removeSpecialcharacters(track.getTitle()).length() <= // this.theTrack.getMatchLength()) { this.theTrack.setTrackNr(track.getTrackNr()); this.theTrack.setMatchLength(track.getTitle().length()); this.theTrack.setTitle(track.getTitle()); return padNumbers(this.theTrack.getTrackNr(), this.theAlbum.getMaxTracks()); // } } } return null; } /** * replaces some special characters with its ascii codes * * @param str * given string * * @return modified string */ private String removeSpecialcharacters(String str) { str = str.replace("'", ""); str = str.replace("´", ""); str = str.replace("`", ""); str = str.replace(".", ""); str = str.replace(",", ""); return str; } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getMaxTracks() */ @Override public String getMaxTracks() { if (this.theAlbum.getMaxTracks() == 0) return null; return Integer.toString(this.theAlbum.getMaxTracks()); } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getCD() */ @Override public String getCD() { return null; } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getMaxCD() */ @Override public String getMaxCD() { return null; } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getGenre() */ @Override public int getGenre() { int genre = 12; for (String tag : this.theTrack.getTags()) { genre = Genres.getGenreLoose(tag); if (genre >= 0 && genre <= 148) return genre; } return genre; } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getComment() */ @Override public String getComment() { return null; } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getComposer() */ @Override public String getComposer() { return null; } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getOrigArtist() */ @Override public String getOrigArtist() { return null; } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getCopyright() */ @Override public String getCopyright() { return null; } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getURL() */ @Override public String getURL() { return null; } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getEncoder() */ @Override public String getEncoder() { return null; } /* * (non-Javadoc) * * @see model.collector.interfaces.IID3DataCollector#getAllAlbumTracks() */ @Override public List<Track> getAllAlbumTracks() { if (theAlbum == null) return new ArrayList<Track>(); return this.theAlbum.getTracks(); } /* * (non-Javadoc) * * @see * model.collector.interfaces.IID3DataCollector#setData(model.structure. * ID3TagData) */ @Override public void setData(ID3TagData data) { this.title = Util.stripExtraData(replaceSpecialCharacters(data.getTitle())); this.artist = Util.stripExtraData(replaceSpecialCharacters(data.getArtist())); this.album = Util.stripExtraData(replaceSpecialCharacters(data.getAlbum())); } }