Package de.umass.lastfm

Source Code of de.umass.lastfm.Track$TrackFactory

/*
* Copyright (c) 2010, 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 <code>Track</code>s and provides bindings to methods
* in the <code>track.</code> namespace.
*
* @author Janni Kovacs
*/
public class Track extends MusicEntry {

  private enum ScrobbleResultType {
    NOW_PLAYING,
    SINGLE_SCROBBLE,
    MULTIPLE_SCROBBLES
  }

  static final ItemFactory<Track> FACTORY = new TrackFactory();

  public static final String ARTIST_PAGE = "artistpage";
  public static final String ALBUM_PAGE = "albumpage";
  public static final String TRACK_PAGE = "trackpage";

  protected String artist;
  protected String artistMbid;

  protected String album;
  protected String albumMbid;
  protected int position = -1;

  protected boolean fullTrackAvailable;
  protected boolean nowPlaying;

  protected Date playedWhen;
  protected int duration;
  protected String location;

  protected Map<String, String> lastFmExtensionInfos = new HashMap<String, String>();


  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. <tt>key</tt> can be one of the following:
   * <ul>
   * <li>artistpage</li>
   * <li>albumpage</li>
   * <li>trackpage</li>
   * <li>buyTrackURL</li>
   * <li>buyAlbumURL</li>
   * <li>freeTrackURL</li>
   * </ul>
   * Or use the available constants in this class.<br/>
   * 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 <code>null</code>,
   * if this data is not available.<br/>
   *
   * @return the date when the track was played or <code>null</code>
   */
  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<Track> 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 <code>null</code> 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 <code>null</code>
   * @param track Track name
   * @param limit Number of maximum results
   * @param apiKey The API key
   * @return a list of possible matches
   */
  public static Collection<Track> search(String artist, String track, int limit, String apiKey) {
    Map<String, String> params = new HashMap<String, String>();
    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 <code>null</code> for the first parameter.
   *
   * @param artist Artist name or <code>null</code> if an MBID is specified
   * @param trackOrMbid Track name or MBID
   * @param apiKey The API key
   * @return list of tags
   */
  public static Collection<Tag> getTopTags(String artist, String trackOrMbid, String apiKey) {
    Map<String, String> params = new HashMap<String, String>();
    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 <code>null</code> for the first parameter.
   *
   * @param artist Artist name or <code>null</code> if an MBID is specified
   * @param trackOrMbid Track name or MBID
   * @param apiKey The API key
   * @return list of fans
   */
  public static Collection<User> getTopFans(String artist, String trackOrMbid, String apiKey) {
    Map<String, String> params = new HashMap<String, String>();
    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 <code>null</code>. 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<String, String> 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.
   * This needs to be supplemented with a scrobbling submission containing the 'love' rating (see the audioscrobbler API).
   *
   * @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.
   * This needs to be supplemented with a scrobbling submission containing the 'ban' rating (see the audioscrobbler API).
   *
   * @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.<br/>
   * You have to provide either an artist and a track name <i>or</i> an mbid. Pass <code>null</code>
   * 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 <code>Track</code>s
   */
  public static Collection<Track> getSimilar(String artist, String trackOrMbid, String apiKey) {
    Map<String, String> params = new HashMap<String, String>();
    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<String> getTags(String artist, String track, Session session) {
    Result result = Caller.getInstance().call("track.getTags", session, "artist", artist, "track", track);
    DomElement element = result.getContentElement();
    Collection<String> tags = new ArrayList<String>();
    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 <code>null</code> 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 <code>null</code> 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 <code>null</code>
   * @param username The username for the context of the request, or <code>null</code>. 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<String, String> params = new HashMap<String, String>();
    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<BuyLink> getBuylinks(String artist, String albumOrMbid, String country, String apiKey) {
    Map<String, String> params = new HashMap<String, String>();
    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<BuyLink> links = new ArrayList<BuyLink>();
    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 <code>null</code> 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 <code>null</code>
   */
  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);
  }

  /**
   * 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<ScrobbleResult> convertToScrobbleResults(Result result, ScrobbleResultType scrobbleResultType) {
    List<ScrobbleResult> scrobbleResults = new ArrayList<ScrobbleResult>();
    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<String, String> params = new HashMap<String, String>();
    // 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());

    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<ScrobbleResult> scrobble(List<ScrobbleData> scrobbleData, Session session) {
    Map<String, String> params = new HashMap<String, String>();
    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());
    }

    Result result = Caller.getInstance().call("track.scrobble", session, params);
    return convertToScrobbleResults(result, ScrobbleResultType.MULTIPLE_SCROBBLES);
  }

  public static ScrobbleResult updateNowPlaying(ScrobbleData scrobbleData, Session session) {
    Map<String, String> params = new HashMap<String, String>();
    // 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<Track> {
    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"))
        track.duration = Integer.parseInt(element.getChildText("duration")) / 1000;
      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;
    }
  }
}
TOP

Related Classes of de.umass.lastfm.Track$TrackFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.