Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
de.umass.lastfm.Track Maven / Gradle / Ivy
/*
* Copyright (c) 2012, the Last.fm Java Project and Committers
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package de.umass.lastfm;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import de.umass.lastfm.scrobble.IgnoredMessageCode;
import de.umass.lastfm.scrobble.ScrobbleData;
import de.umass.lastfm.scrobble.ScrobbleResult;
import de.umass.util.MapUtilities;
import de.umass.util.StringUtilities;
import de.umass.xml.DomElement;
/**
* Bean that contains information related to Track
s and provides bindings to methods
* in the track.
namespace.
*
* @author Janni Kovacs
*/
public class Track extends MusicEntry {
private enum ScrobbleResultType {
NOW_PLAYING,
SINGLE_SCROBBLE,
MULTIPLE_SCROBBLES
}
static final ItemFactory FACTORY = new TrackFactory();
public static final String ARTIST_PAGE = "artistpage";
public static final String ALBUM_PAGE = "albumpage";
public static final String TRACK_PAGE = "trackpage";
private String artist;
private String artistMbid;
protected String album; // protected for use in Playlist.playlistFromElement
private String albumMbid;
private int position = -1;
private boolean fullTrackAvailable;
private boolean nowPlaying;
private Date playedWhen;
protected int duration; // protected for use in Playlist.playlistFromElement
protected String location; // protected for use in Playlist.playlistFromElement
protected Map lastFmExtensionInfos = new HashMap(); // protected for use in Playlist.playlistFromElement
protected Track(String name, String url, String artist) {
super(name, url);
this.artist = artist;
}
protected Track(String name, String url, String mbid, int playcount, int listeners, boolean streamable,
String artist, String artistMbid, boolean fullTrackAvailable, boolean nowPlaying) {
super(name, url, mbid, playcount, listeners, streamable);
this.artist = artist;
this.artistMbid = artistMbid;
this.fullTrackAvailable = fullTrackAvailable;
this.nowPlaying = nowPlaying;
}
/**
* Returns the duration of the song, if available, in seconds. The duration attribute is only available
* for tracks retrieved by {@link Playlist#fetch(String, String) Playlist.fetch} and
* {@link Track#getInfo(String, String, String) Track.getInfo}.
*
* @return duration in seconds
*/
public int getDuration() {
return duration;
}
public String getArtist() {
return artist;
}
public String getArtistMbid() {
return artistMbid;
}
public String getAlbum() {
return album;
}
public String getAlbumMbid() {
return albumMbid;
}
public boolean isFullTrackAvailable() {
return fullTrackAvailable;
}
public boolean isNowPlaying() {
return nowPlaying;
}
/**
* Returns the location (URL) of this Track. This information is only available with the {@link Radio} services.
*
* @return the location
*/
public String getLocation() {
return location;
}
/**
* Returns last.fm specific information about this Track. Only available in Tracks fetched from
* radio playlists. key can be one of the following:
*
* artistpage
* albumpage
* trackpage
* buyTrackURL
* buyAlbumURL
* freeTrackURL
*
* Or use the available constants in this class.
* Note that the key string is case sensitive.
*
* @param key A key
* @return associated value
* @see #ARTIST_PAGE
* @see #ALBUM_PAGE
* @see #TRACK_PAGE
*/
public String getLastFmInfo(String key) {
return lastFmExtensionInfos.get(key);
}
/**
* Returns the time when the track was played, if this data is available (e.g. for recent tracks) or null
,
* if this data is not available.
*
* @return the date when the track was played or null
*/
public Date getPlayedWhen() {
return playedWhen;
}
/**
* Returns the position of this track in its associated album, or -1 if not available.
*
* @return the album position
*/
public int getPosition() {
return position;
}
/**
* Searches for a track with the given name and returns a list of possible matches.
*
* @param track Track name
* @param apiKey The API key
* @return a list of possible matches
* @see #search(String, String, int, String)
*/
public static Collection search(String track, String apiKey) {
return search(null, track, 30, apiKey);
}
/**
* Searches for a track with the given name and returns a list of possible matches.
* Specify an artist name or a limit to narrow down search results.
* Pass null
for the artist parameter if you want to specify a limit but don't want
* to define an artist.
*
* @param artist Artist's name or null
* @param track Track name
* @param limit Number of maximum results
* @param apiKey The API key
* @return a list of possible matches
*/
public static Collection search(String artist, String track, int limit, String apiKey) {
Map params = new HashMap();
params.put("track", track);
params.put("limit", String.valueOf(limit));
MapUtilities.nullSafePut(params, "artist", artist);
Result result = Caller.getInstance().call("track.search", apiKey, params);
if(!result.isSuccessful())
return Collections.emptyList();
DomElement element = result.getContentElement();
DomElement matches = element.getChild("trackmatches");
return ResponseBuilder.buildCollection(matches, Track.class);
}
/**
* Retrieves the top tags for the given track. You either have to specify a track and artist name or
* a mbid. If you specify an mbid you may pass null
for the first parameter.
*
* @param artist Artist name or null
if an MBID is specified
* @param trackOrMbid Track name or MBID
* @param apiKey The API key
* @return list of tags
*/
public static Collection getTopTags(String artist, String trackOrMbid, String apiKey) {
Map params = new HashMap();
if (StringUtilities.isMbid(trackOrMbid)) {
params.put("mbid", trackOrMbid);
} else {
params.put("artist", artist);
params.put("track", trackOrMbid);
}
Result result = Caller.getInstance().call("track.getTopTags", apiKey, params);
return ResponseBuilder.buildCollection(result, Tag.class);
}
/**
* Retrieves the top fans for the given track. You either have to specify a track and artist name or
* a mbid. If you specify an mbid you may pass null
for the first parameter.
*
* @param artist Artist name or null
if an MBID is specified
* @param trackOrMbid Track name or MBID
* @param apiKey The API key
* @return list of fans
*/
public static Collection getTopFans(String artist, String trackOrMbid, String apiKey) {
Map params = new HashMap();
if (StringUtilities.isMbid(trackOrMbid)) {
params.put("mbid", trackOrMbid);
} else {
params.put("artist", artist);
params.put("track", trackOrMbid);
}
Result result = Caller.getInstance().call("track.getTopFans", apiKey, params);
return ResponseBuilder.buildCollection(result, User.class);
}
/**
* Tag an album using a list of user supplied tags.
*
* @param artist The artist name in question
* @param track The track name in question
* @param tags A comma delimited list of user supplied tags to apply to this track. Accepts a maximum of 10 tags.
* @param session A Session instance.
* @return the Result of the operation
*/
public static Result addTags(String artist, String track, String tags, Session session) {
return Caller.getInstance().call("track.addTags", session, "artist", artist, "track", track, "tags", tags);
}
/**
* Remove a user's tag from a track.
*
* @param artist The artist name in question
* @param track The track name in question
* @param tag A single user tag to remove from this track.
* @param session A Session instance.
* @return the Result of the operation
*/
public static Result removeTag(String artist, String track, String tag, Session session) {
return Caller.getInstance().call("track.removeTag", session, "artist", artist, "track", track, "tag", tag);
}
/**
* Share a track twith one or more Last.fm users or other friends.
*
* @param artist An artist name.
* @param track A track name.
* @param message A message to send with the recommendation or null
. If not supplied a default message will be used.
* @param recipient A comma delimited list of email addresses or Last.fm usernames. Maximum is 10.
* @param session A Session instance
* @return the Result of the operation
*/
public static Result share(String artist, String track, String message, String recipient, Session session) {
Map params = StringUtilities.map("artist", artist, "track", track, "recipient", recipient);
MapUtilities.nullSafePut(params, "message", message);
return Caller.getInstance().call("track.share", session, params);
}
/**
* Love a track for a user profile.
*
* @param artist An artist name
* @param track A track name
* @param session A Session instance
* @return the Result of the operation
*/
public static Result love(String artist, String track, Session session) {
return Caller.getInstance().call("track.love", session, "artist", artist, "track", track);
}
/**
* UnLove a track for a user profile.
*
* @param artist An artist name
* @param track A track name
* @param session A Session instance
* @return the Result of the operation
*/
public static Result unlove(String artist, String track, Session session) {
return Caller.getInstance().call("track.unlove", session, "artist", artist, "track", track);
}
/**
* Ban a track for a given user profile.
*
* @param artist An artist name
* @param track A track name
* @param session A Session instance
* @return the Result of the operation
*/
public static Result ban(String artist, String track, Session session) {
return Caller.getInstance().call("track.ban", session, "artist", artist, "track", track);
}
/**
* UnBan a track for a given user profile.
*
* @param artist An artist name
* @param track A track name
* @param session A Session instance
* @return the Result of the operation
*/
public static Result unban(String artist, String track, Session session) {
return Caller.getInstance().call("track.unban", session, "artist", artist, "track", track);
}
/**
* Get the similar tracks for this track on Last.fm, based on listening data.
* You have to provide either an artist and a track name or an mbid. Pass null
* for parameters you don't need.
*
* @param artist The artist name in question
* @param trackOrMbid The track name in question or the track's MBID
* @param apiKey A Last.fm API key.
* @return a list of similar Track
s
*/
public static Collection getSimilar(String artist, String trackOrMbid, String apiKey) {
Map params = new HashMap();
if (StringUtilities.isMbid(trackOrMbid)) {
params.put("mbid", trackOrMbid);
} else {
params.put("artist", artist);
params.put("track", trackOrMbid);
}
Result result = Caller.getInstance().call("track.getSimilar", apiKey, params);
return ResponseBuilder.buildCollection(result, Track.class);
}
/**
* Get the tags applied by an individual user to an track on Last.fm.
*
* @param artist The artist name in question
* @param track The track name in question
* @param session A Session instance
* @return a list of tags
*/
public static Collection getTags(String artist, String track, Session session) {
Result result = Caller.getInstance().call("track.getTags", session, "artist", artist, "track", track);
DomElement element = result.getContentElement();
Collection tags = new ArrayList();
for (DomElement domElement : element.getChildren("tag")) {
tags.add(domElement.getChildText("name"));
}
return tags;
}
/**
* Get the metadata for a track on Last.fm using the artist/track name or a musicbrainz id.
*
* @param artist The artist name in question or null
if an mbid is specified
* @param trackOrMbid The track name in question or the musicbrainz id for the track
* @param apiKey A Last.fm API key.
* @return Track information
*/
public static Track getInfo(String artist, String trackOrMbid, String apiKey) {
return getInfo(artist, trackOrMbid, null, null, apiKey);
}
/**
* Get the metadata for a track on Last.fm using the artist/track name or a musicbrainz id.
*
* @param artist The artist name in question or null
if an mbid is specified
* @param trackOrMbid The track name in question or the musicbrainz id for the track
* @param locale The language to fetch info in, or null
* @param username The username for the context of the request, or null
. If supplied, the user's playcount for this track and whether they have loved the track is included in the response
* @param apiKey A Last.fm API key.
* @return Track information
*/
public static Track getInfo(String artist, String trackOrMbid, Locale locale, String username, String apiKey) {
Map params = new HashMap();
if (StringUtilities.isMbid(trackOrMbid)) {
params.put("mbid", trackOrMbid);
} else {
params.put("artist", artist);
params.put("track", trackOrMbid);
}
if (locale != null && locale.getLanguage().length() != 0) {
params.put("lang", locale.getLanguage());
}
MapUtilities.nullSafePut(params, "username", username);
Result result = Caller.getInstance().call("track.getInfo", apiKey, params);
if (!result.isSuccessful())
return null;
DomElement content = result.getContentElement();
DomElement album = content.getChild("album");
Track track = FACTORY.createItemFromElement(content);
if (album != null) {
String pos = album.getAttribute("position");
if ((pos != null) && pos.length() != 0) {
track.position = Integer.parseInt(pos);
}
track.album = album.getChildText("title");
track.albumMbid = album.getChildText("mbid");
ImageHolder.loadImages(track, album);
}
return track;
}
/**
* Get a list of Buy Links for a particular Track. It is required that you supply either the artist and track params or the mbid param.
*
* @param artist The artist name in question
* @param albumOrMbid Track name or MBID
* @param country A country name, as defined by the ISO 3166-1 country names standard
* @param apiKey A Last.fm API key
* @return a Collection of {@link BuyLink}s
*/
public static Collection getBuylinks(String artist, String albumOrMbid, String country, String apiKey) {
Map params = new HashMap();
if (StringUtilities.isMbid(albumOrMbid)) {
params.put("mbid", albumOrMbid);
} else {
params.put("artist", artist);
params.put("album", albumOrMbid);
}
params.put("country", country);
Result result = Caller.getInstance().call("track.getBuylinks", apiKey, params);
if (!result.isSuccessful())
return Collections.emptyList();
DomElement element = result.getContentElement();
DomElement physicals = element.getChild("physicals");
DomElement downloads = element.getChild("downloads");
Collection links = new ArrayList();
for (DomElement e : physicals.getChildren("affiliation")) {
links.add(BuyLink.linkFromElement(BuyLink.StoreType.PHYSICAl, e));
}
for (DomElement e : downloads.getChildren("affiliation")) {
links.add(BuyLink.linkFromElement(BuyLink.StoreType.DIGITAL, e));
}
return links;
}
/**
* Use the last.fm corrections data to check whether the supplied track has a correction to a canonical track. This method returns a new
* {@link Track} object containing the corrected data, or null
if the supplied Artist/Track combination was not found.
*
* @param artist The artist name to correct
* @param track The track name to correct
* @param apiKey A Last.fm API key
* @return a new {@link Track}, or null
*/
public static Track getCorrection(String artist, String track, String apiKey) {
Result result = Caller.getInstance().call("track.getCorrection", apiKey, "artist", artist, "track", track);
if (!result.isSuccessful())
return null;
DomElement correctionElement = result.getContentElement().getChild("correction");
if (correctionElement == null)
return new Track(track, null, artist);
DomElement trackElem = correctionElement.getChild("track");
return FACTORY.createItemFromElement(trackElem);
}
/**
* Get shouts for a track.
*
* @param artist The artist name
* @param trackOrMbid The track name or a mausicbrainz id
* @param apiKey A Last.fm API key.
* @return a page of Shout
s
*/
public static PaginatedResult getShouts(String artist, String trackOrMbid, String apiKey) {
return getShouts(artist, trackOrMbid, -1, -1, apiKey);
}
/**
* Get shouts for a track.
*
* @param artist The artist name
* @param trackOrMbid The track name or a mausicbrainz id
* @param page The page number to fetch
* @param apiKey A Last.fm API key.
* @return a page of Shout
s
*/
public static PaginatedResult getShouts(String artist, String trackOrMbid, int page, String apiKey) {
return getShouts(artist, trackOrMbid, page, -1, apiKey);
}
/**
* Get shouts for a track.
*
* @param artist The artist name
* @param trackOrMbid The track name or a mausicbrainz id
* @param page The page number to fetch
* @param limit An integer used to limit the number of shouts returned per page or -1 for default
* @param apiKey A Last.fm API key.
* @return a page of Shout
s
*/
public static PaginatedResult getShouts(String artist, String trackOrMbid, int page, int limit, String apiKey) {
Map params = new HashMap();
if (StringUtilities.isMbid(trackOrMbid)) {
params.put("mbid", trackOrMbid);
} else {
params.put("artist", artist);
params.put("track", trackOrMbid);
}
MapUtilities.nullSafePut(params, "limit", limit);
MapUtilities.nullSafePut(params, "page", page);
Result result = Caller.getInstance().call("track.getShouts", apiKey, params);
return ResponseBuilder.buildPaginatedResult(result, Shout.class);
}
/**
* Converts a generic web services Result object into a more specific ScrobbleResult.
*
* @param result Web services Result.
* @param scrobbleResultType The type of scrobble result contained within the Result.
* @return A ScrobbleResult containing the original Result information plus extra fields specific to scrobble and now playing results.
*/
private static List convertToScrobbleResults(Result result, ScrobbleResultType scrobbleResultType) {
List scrobbleResults = new ArrayList();
if (!result.isSuccessful()) {
// if result failed then we have no extra information
ScrobbleResult scrobbleResult = new ScrobbleResult(result);
scrobbleResults.add(scrobbleResult);
} else {
DomElement element = result.getContentElement();
if (scrobbleResultType == ScrobbleResultType.NOW_PLAYING) {
ScrobbleResult scrobbleResult = new ScrobbleResult(result);
parseIntoScrobbleResult(element, scrobbleResult);
scrobbleResults.add(scrobbleResult);
} else if (scrobbleResultType == ScrobbleResultType.SINGLE_SCROBBLE) {
ScrobbleResult scrobbleResult = new ScrobbleResult(result);
parseIntoScrobbleResult(element.getChild("scrobble"), scrobbleResult);
scrobbleResults.add(scrobbleResult);
} else if (scrobbleResultType == ScrobbleResultType.MULTIPLE_SCROBBLES) {
for (DomElement scrobbleElement : element.getChildren("scrobble")) {
ScrobbleResult scrobbleResult = new ScrobbleResult(result);
parseIntoScrobbleResult(scrobbleElement, scrobbleResult);
scrobbleResults.add(scrobbleResult);
}
}
}
return scrobbleResults;
}
/**
* Parses a DomElement containing scrobble or now playing response data into the passed ScrobbleResult.
*
* @param scrobbleElement DomElement containing scrobble or now playing response data.
* @param scrobbleResult ScrobbleResult to add the response data to.
*/
private static void parseIntoScrobbleResult(DomElement scrobbleElement, ScrobbleResult scrobbleResult) {
DomElement trackElement = scrobbleElement.getChild("track");
scrobbleResult.setTrack(trackElement.getText());
scrobbleResult.setArtistCorrected(StringUtilities.convertToBoolean(trackElement.getAttribute("corrected")));
DomElement artistElement = scrobbleElement.getChild("artist");
scrobbleResult.setArtist(artistElement.getText());
scrobbleResult.setArtistCorrected(StringUtilities.convertToBoolean(artistElement.getAttribute("corrected")));
DomElement albumElement = scrobbleElement.getChild("album");
scrobbleResult.setAlbum(albumElement.getText());
scrobbleResult.setAlbumCorrected(StringUtilities.convertToBoolean(albumElement.getAttribute("corrected")));
DomElement albumArtistElement = scrobbleElement.getChild("albumArtist");
scrobbleResult.setAlbumArtist(albumArtistElement.getText());
scrobbleResult.setAlbumArtistCorrected(StringUtilities.convertToBoolean(albumArtistElement.getAttribute("corrected")));
String timeString = scrobbleElement.getChildText("timestamp");
if (timeString != null) {
// will be non-null for scrobble results only
scrobbleResult.setTimestamp(Integer.parseInt(timeString));
}
DomElement ignoredMessageElement = scrobbleElement.getChild("ignoredMessage");
int ignoredMessageCode = Integer.parseInt(ignoredMessageElement.getAttribute("code"));
if (ignoredMessageCode > 0) {
scrobbleResult.setIgnored(true);
scrobbleResult.setIgnoredMessageCode(IgnoredMessageCode.valueOfCode(ignoredMessageCode));
scrobbleResult.setIgnoredMessage(ignoredMessageElement.getText());
}
}
public static ScrobbleResult scrobble(ScrobbleData scrobbleData, Session session) {
Map params = new HashMap();
// required params
params.put("artist", scrobbleData.getArtist());
params.put("track", scrobbleData.getTrack());
params.put("timestamp", String.valueOf(scrobbleData.getTimestamp()));
// optional params
MapUtilities.nullSafePut(params, "album", scrobbleData.getAlbum());
MapUtilities.nullSafePut(params, "albumArtist", scrobbleData.getAlbumArtist());
MapUtilities.nullSafePut(params, "duration", scrobbleData.getDuration());
MapUtilities.nullSafePut(params, "mbid", scrobbleData.getMusicBrainzId());
MapUtilities.nullSafePut(params, "trackNumber", scrobbleData.getTrackNumber());
MapUtilities.nullSafePut(params, "streamId", scrobbleData.getStreamId());
params.put("chosenByUser", StringUtilities.convertFromBoolean(scrobbleData.isChosenByUser()));
Result result = Caller.getInstance().call("track.scrobble", session, params);
return convertToScrobbleResults(result, ScrobbleResultType.SINGLE_SCROBBLE).get(0);
}
public static ScrobbleResult scrobble(String artistName, String trackName, int timestamp, Session session) {
ScrobbleData scrobbleData = new ScrobbleData(artistName, trackName, timestamp);
return scrobble(scrobbleData, session);
}
public static List scrobble(List scrobbleData, Session session) {
Map params = new HashMap();
for (int i = 0; i < scrobbleData.size(); i++) {
ScrobbleData scrobble = scrobbleData.get(i);
// required params
params.put("artist[" + i + "]", scrobble.getArtist());
params.put("track[" + i + "]", scrobble.getTrack());
params.put("timestamp[" + i + "]", String.valueOf(scrobble.getTimestamp()));
// optional params
MapUtilities.nullSafePut(params, "album[" + i + "]", scrobble.getAlbum());
MapUtilities.nullSafePut(params, "albumArtist[" + i + "]", scrobble.getAlbumArtist());
MapUtilities.nullSafePut(params, "duration[" + i + "]", scrobble.getDuration());
MapUtilities.nullSafePut(params, "mbid[" + i + "]", scrobble.getMusicBrainzId());
MapUtilities.nullSafePut(params, "trackNumber[" + i + "]", scrobble.getTrackNumber());
MapUtilities.nullSafePut(params, "streamId[" + i + "]", scrobble.getStreamId());
params.put("chosenByUser[" + i + "]", StringUtilities.convertFromBoolean(scrobble.isChosenByUser()));
}
Result result = Caller.getInstance().call("track.scrobble", session, params);
return convertToScrobbleResults(result, ScrobbleResultType.MULTIPLE_SCROBBLES);
}
public static ScrobbleResult updateNowPlaying(ScrobbleData scrobbleData, Session session) {
Map params = new HashMap();
// required params
params.put("artist", scrobbleData.getArtist());
params.put("track", scrobbleData.getTrack());
// optional params
MapUtilities.nullSafePut(params, "album", scrobbleData.getAlbum());
MapUtilities.nullSafePut(params, "albumArtist", scrobbleData.getAlbumArtist());
MapUtilities.nullSafePut(params, "duration", scrobbleData.getDuration());
MapUtilities.nullSafePut(params, "mbid", scrobbleData.getMusicBrainzId());
MapUtilities.nullSafePut(params, "trackNumber", scrobbleData.getTrackNumber());
MapUtilities.nullSafePut(params, "streamId", scrobbleData.getStreamId());
Result result = Caller.getInstance().call("track.updateNowPlaying", session, params);
return convertToScrobbleResults(result, ScrobbleResultType.NOW_PLAYING).get(0);
}
public static ScrobbleResult updateNowPlaying(String artistName, String trackName, Session session) {
ScrobbleData scrobbleData = new ScrobbleData();
scrobbleData.setArtist(artistName);
scrobbleData.setTrack(trackName);
return updateNowPlaying(scrobbleData, session);
}
@Override
public String toString() {
return "Track[name=" + name + ",artist=" + artist + ", album=" + album + ", position=" + position + ", duration=" + duration
+ ", location=" + location + ", nowPlaying=" + nowPlaying + ", fullTrackAvailable=" + fullTrackAvailable + ", playedWhen="
+ playedWhen + ", artistMbId=" + artistMbid + ", albumMbId" + albumMbid + "]";
}
private static class TrackFactory implements ItemFactory {
public Track createItemFromElement(DomElement element) {
Track track = new Track(null, null, null);
MusicEntry.loadStandardInfo(track, element);
final String nowPlayingAttr = element.getAttribute("nowplaying");
if (nowPlayingAttr != null)
track.nowPlaying = Boolean.valueOf(nowPlayingAttr);
if (element.hasChild("duration")) {
String duration = element.getChildText("duration");
if(duration.length() != 0) {
int durationLength = Integer.parseInt(duration);
// So it seems last.fm couldn't decide which format to send the duration in.
// It's supplied in milliseconds for Playlist.fetch and Track.getInfo but Artist.getTopTracks returns (much saner) seconds
// so we're doing a little sanity check for the duration to be over or under 10'000 and decide what to do
track.duration = durationLength > 10000 ? durationLength / 1000 : durationLength;
}
}
DomElement album = element.getChild("album");
if (album != null) {
track.album = album.getText();
track.albumMbid = album.getAttribute("mbid");
}
DomElement artist = element.getChild("artist");
if (artist.getChild("name") != null) {
track.artist = artist.getChildText("name");
track.artistMbid = artist.getChildText("mbid");
} else {
track.artist = artist.getText();
track.artistMbid = artist.getAttribute("mbid");
}
DomElement date = element.getChild("date");
if (date != null) {
String uts = date.getAttribute("uts");
long utsTime = Long.parseLong(uts);
track.playedWhen = new Date(utsTime * 1000);
}
DomElement stream = element.getChild("streamable");
if (stream != null) {
String s = stream.getAttribute("fulltrack");
track.fullTrackAvailable = s != null && Integer.parseInt(s) == 1;
}
return track;
}
}
}