/***************************************************************************
* Copyright 2005-2009 Last.fm Ltd. *
* Portions contributed by Casey Link, Lukasz Wisniewski, *
* Mike Jennings, and Michael Novak Jr. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
package fm.last.api.impl;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import android.util.Log;
import fm.last.api.Album;
import fm.last.api.Artist;
import fm.last.api.Event;
import fm.last.api.Friends;
import fm.last.api.Geo;
import fm.last.api.LastFmServer;
import fm.last.api.MD5;
import fm.last.api.Metro;
import fm.last.api.RadioPlayList;
import fm.last.api.Session;
import fm.last.api.SessionInfo;
import fm.last.api.Station;
import fm.last.api.Tag;
import fm.last.api.Tasteometer;
import fm.last.api.Track;
import fm.last.api.User;
import fm.last.api.WSError;
import fm.last.util.UrlUtil;
import fm.last.util.XMLUtil;
import fm.last.xml.XMLBuilder;
/**
* An implementation of LastFmServer
*
* @author Mike Jennings
* @author Casey Link
*/
final class LastFmServerImpl implements LastFmServer {
private String api_key;
private String shared_secret;
private String baseUrl;
private class Parser<T> {
@SuppressWarnings("unchecked")
public T getItem(String baseUrl, Map<String, String> params, String nodeName, XMLBuilder<?> builder) throws IOException, WSError {
String response = UrlUtil.doGet(baseUrl, params);
Document responseXML = null;
try {
responseXML = XMLUtil.stringToDocument(response);
} catch (SAXException e) {
throw new IOException(e.getMessage());
}
Node lfmNode = XMLUtil.findNamedElementNode(responseXML, "lfm");
String status = lfmNode.getAttributes().getNamedItem("status").getNodeValue();
if (!status.contains("ok")) {
Node errorNode = XMLUtil.findNamedElementNode(lfmNode, "error");
if (errorNode != null) {
WSErrorBuilder eb = new WSErrorBuilder();
throw eb.build(params.get("method"), errorNode);
}
return null;
} else {
Node itemNode = XMLUtil.findNamedElementNode(lfmNode, nodeName);
return (T)builder.build(itemNode);
}
}
@SuppressWarnings("unchecked")
public List<T> getList(String baseUrl, Map<String, String> params, String nodeName, String elementName, XMLBuilder<?> builder) throws IOException, WSError {
String response = UrlUtil.doGet(baseUrl, params);
Document responseXML = null;
try {
responseXML = XMLUtil.stringToDocument(response);
} catch (SAXException e) {
throw new IOException(e.getMessage());
}
Node lfmNode = XMLUtil.findNamedElementNode(responseXML, "lfm");
String status = lfmNode.getAttributes().getNamedItem("status").getNodeValue();
if (!status.contains("ok")) {
Node errorNode = XMLUtil.findNamedElementNode(lfmNode, "error");
if (errorNode != null) {
WSErrorBuilder eb = new WSErrorBuilder();
throw eb.build(params.get("method"), errorNode);
}
return null;
} else {
Node baseNode = XMLUtil.findNamedElementNode(lfmNode, nodeName);
List<Node> elementNodes = XMLUtil.findNamedElementNodes(baseNode, elementName);
ArrayList<T> items = new ArrayList<T>();
for (Node itemNode : elementNodes) {
items.add((T)builder.build(itemNode));
}
return items;
}
}
}
public void post(String baseUrl, Map<String, String> params) throws IOException, WSError {
String response = UrlUtil.doPost(baseUrl, params);
Document responseXML = null;
try {
responseXML = XMLUtil.stringToDocument(response);
} catch (SAXException e) {
Log.e("Last.fm", "Bad XML: " + response);
throw new IOException(e.getMessage());
}
Node lfmNode = XMLUtil.findNamedElementNode(responseXML, "lfm");
String status = lfmNode.getAttributes().getNamedItem("status").getNodeValue();
if (!status.contains("ok")) {
Node errorNode = XMLUtil.findNamedElementNode(lfmNode, "error");
if (errorNode != null) {
WSErrorBuilder eb = new WSErrorBuilder();
throw eb.build(params.get("method"), errorNode);
}
}
}
LastFmServerImpl(String baseUrl, String api_key, String shared_secret) {
this.baseUrl = baseUrl;
this.api_key = api_key;
this.shared_secret = shared_secret;
}
private Map<String, String> createParams(String method) {
Map<String, String> params = new HashMap<String, String>();
params.put("method", method);
params.put("api_key", api_key);
return params;
}
/**
* "sign" parameters in the way that last.fm expects.
*
* See: http://www.last.fm/api/authspec#8
*
* @param params
*/
private void signParams(Map<String, String> params) {
StringBuilder sb = new StringBuilder();
SortedSet<String> keySet = new TreeSet<String>(params.keySet());
for (String key : keySet) {
sb.append(key).append(params.get(key));
}
sb.append(shared_secret);
String signature = sb.toString();
String api_sig = MD5.getInstance().hash(signature);
// now we pad to 32 chars if we need to:
while (32 - api_sig.length() > 0)
api_sig = "0" + api_sig;
params.put("api_sig", api_sig);
}
/**
* See: http://www.last.fm/api/show?service=119
*
* @param artist
* @return
* @throws IOException
*/
public Artist[] getSimilarArtists(String artist, String limit) throws IOException, WSError {
Map<String, String> params = createParams("artist.getsimilar");
if (artist != null) {
params.put("artist", artist);
}
if (limit != null) {
params.put("limit", limit);
}
List<Artist> artists = new Parser<Artist>().getList(baseUrl, params, "similarartists", "artist", new ArtistBuilder());
return artists.toArray(new Artist[artists.size()]);
}
public Artist[] searchForArtist(String artist) throws IOException, WSError {
Map<String, String> params = createParams("artist.search");
if (artist != null) {
params.put("artist", artist);
}
return SearchFunctions.searchForArtist(baseUrl, params);
}
public Tag[] searchForTag(String tag) throws IOException, WSError {
Map<String, String> params = createParams("tag.search");
if (tag != null) {
params.put("tag", tag);
}
return SearchFunctions.searchForTag(baseUrl, params);
}
public Track[] searchForTrack(String track) throws IOException, WSError {
Map<String, String> params = createParams("track.search");
if (track != null) {
params.put("track", track);
}
return SearchFunctions.searchForTrack(baseUrl, params);
}
public Event[] searchForEvent(String event) throws IOException {
Map<String, String> params = createParams("event.search");
if (event != null) {
params.put("event", event);
}
return SearchFunctions.searchForEvent(baseUrl, params);
}
public Event[] searchForFestival(String event) throws IOException {
Map<String, String> params = createParams("event.search");
if (event != null) {
params.put("event", event);
}
params.put("festivalsonly", "1");
return SearchFunctions.searchForEvent(baseUrl, params);
}
public Serializable[] multiSearch(String query) throws IOException, WSError {
Map<String, String> params = createParams("search.multi");
if (query != null) {
params.put("term", query);
}
return SearchFunctions.multiSearch(baseUrl, params);
}
public Friends getFriends(String user, String recenttracks, String limit) throws IOException, WSError {
Map<String, String> params = createParams("user.getFriends");
if (user != null) {
params.put("user", user);
}
if (recenttracks != null) {
params.put("recenttracks", recenttracks);
}
if (limit != null) {
params.put("limit", limit);
}
return FriendFunctions.getFriends(baseUrl, params);
}
public Track getTrackInfo(String artist, String track, String mbid) throws IOException, WSError {
Map<String, String> params = createParams("track.getInfo");
if (artist != null) {
params.put("artist", artist);
}
if (track != null) {
params.put("track", track);
}
if (mbid != null) {
params.put("mbid", mbid);
}
return new Parser<Track>().getItem(baseUrl, params, "track", new TrackBuilder());
}
public Session getMobileSession(String username, String authToken) throws IOException, WSError {
Map<String, String> params = new HashMap<String, String>();
if (username != null) {
params.put("username", username);
}
if (authToken != null) {
params.put("authToken", authToken);
}
params.put("method", "auth.getMobileSession");
params.put("api_key", api_key);
signParams(params);
return new Parser<Session>().getItem(baseUrl, params, "session", new SessionBuilder());
}
public SessionInfo getSessionInfo(String sk) throws IOException, WSError {
Map<String, String> params = createParams("auth.getSessionInfo");
if (sk != null) {
params.put("sk", sk);
signParams(params);
}
return new Parser<SessionInfo>().getItem(baseUrl, params, "application", new SessionInfoBuilder());
}
public Station tuneToStation(String station, String sk, String lang) throws IOException, WSError {
Map<String, String> params = createParams("radio.tune");
if (station != null) {
params.put("station", station);
}
if (sk != null) {
params.put("sk", sk);
}
if (lang != null) {
params.put("lang", lang);
}
params.put("additional_info", "1");
signParams(params);
return RadioFunctions.tuneToStation(baseUrl, params);
}
public RadioPlayList getRadioPlayList(String bitrate, String rtp, String discovery, String multiplier, String sk) throws IOException, WSError {
Map<String, String> params = createParams("radio.getPlaylist");
if (sk != null) {
params.put("sk", sk);
}
if (bitrate == null)
bitrate = "128";
params.put("bitrate", bitrate);
params.put("speed_multiplier", multiplier);
params.put("rtp", rtp);
params.put("discovery", discovery);
params.put("additional_info", "1");
signParams(params);
return RadioFunctions.getRadioPlaylist(baseUrl, params);
}
public User getUserInfo(String user, String sk) throws IOException, WSError {
Map<String, String> params = createParams("user.getInfo");
if (user != null) {
params.put("user", user);
}
if (sk != null) {
params.put("sk", sk);
signParams(params);
}
return new Parser<User>().getItem(baseUrl, params, "user", new UserBuilder());
}
public Event getEventInfo(String event, String sk) throws IOException {
Map<String, String> params = createParams("event.getInfo");
if (event != null) {
params.put("event", event);
}
if (sk != null) {
params.put("sk", sk);
signParams(params);
}
return new Parser<Event>().getItem(baseUrl, params, "event", new EventBuilder());
}
public Tag[] getTrackTopTags(String artist, String track, String mbid) throws IOException, WSError {
Map<String, String> params = createParams("track.getTopTags");
if (artist != null) {
params.put("artist", artist);
}
if (track != null) {
params.put("track", track);
}
if (mbid != null) {
params.put("mbid", mbid);
}
List<Tag> tags = new Parser<Tag>().getList(baseUrl, params, "toptags", "tag", new TagBuilder());
return tags.toArray(new Tag[tags.size()]);
}
public Tag[] getArtistTopTags(String artist, String mbid) throws IOException, WSError {
Map<String, String> params = createParams("artist.getTopTags");
if (artist != null) {
params.put("artist", artist);
}
if (mbid != null) {
params.put("mbid", mbid);
}
List<Tag> tags = new Parser<Tag>().getList(baseUrl, params, "toptags", "tag", new TagBuilder());
return tags.toArray(new Tag[tags.size()]);
}
public Tag[] getUserTopTags(String user, Integer limit) throws IOException, WSError {
Map<String, String> params = createParams("user.getTopTags");
if (user != null) {
params.put("user", user);
}
if (limit != null) {
params.put("limit", limit.toString());
}
List<Tag> tags = new Parser<Tag>().getList(baseUrl, params, "toptags", "tag", new TagBuilder());
return tags.toArray(new Tag[tags.size()]);
}
public Tag[] getTrackTags(String artist, String track, String sk) throws IOException, WSError {
Map<String, String> params = createParams("track.getTags");
if (artist != null) {
params.put("artist", artist);
}
if (track != null) {
params.put("track", track);
}
if (sk != null) {
params.put("sk", sk);
}
signParams(params);
List<Tag> tags = new Parser<Tag>().getList(baseUrl, params, "tags", "tag", new TagBuilder());
return tags.toArray(new Tag[tags.size()]);
}
public Tag[] getArtistTags(String artist, String sk) throws IOException, WSError {
Map<String, String> params = createParams("artist.getTags");
if (artist != null) {
params.put("artist", artist);
}
if (sk != null) {
params.put("sk", sk);
}
signParams(params);
List<Tag> tags = new Parser<Tag>().getList(baseUrl, params, "tags", "tag", new TagBuilder());
return tags.toArray(new Tag[tags.size()]);
}
public void addTrackTags(String artist, String track, String[] tag, String sk) throws IOException, WSError {
Map<String, String> params = createParams("track.addTags");
if (artist != null) {
params.put("artist", artist);
}
if (track != null) {
params.put("track", track);
}
if (tag != null) {
params.put("tags", TagFunctions.buildTags(tag));
}
if (sk != null) {
params.put("sk", sk);
}
signParams(params);
post(baseUrl, params);
}
public void removeTrackTag(String artist, String track, String tag, String sk) throws IOException, WSError {
Map<String, String> params = createParams("track.removeTag");
if (artist != null) {
params.put("artist", artist);
}
if (track != null) {
params.put("track", track);
}
if (tag != null) {
params.put("tag", tag);
}
if (sk != null) {
params.put("sk", sk);
}
signParams(params);
post(baseUrl, params);
}
public void addArtistTags(String artist, String[] tag, String sk) throws IOException, WSError {
Map<String, String> params = createParams("artist.addTags");
if (artist != null) {
params.put("artist", artist);
}
if (tag != null) {
params.put("tags", TagFunctions.buildTags(tag));
}
if (sk != null) {
params.put("sk", sk);
}
signParams(params);
post(baseUrl, params);
}
public void removeArtistTag(String artist, String tag, String sk) throws IOException, WSError {
Map<String, String> params = createParams("artist.removeTag");
if (artist != null) {
params.put("artist", artist);
}
if (tag != null) {
params.put("tag", tag);
}
if (sk != null) {
params.put("sk", sk);
}
signParams(params);
post(baseUrl, params);
}
public Artist getArtistInfo(String artist, String mbid, String lang, String username) throws IOException, WSError {
Map<String, String> params = createParams("artist.getInfo");
if (artist != null) {
params.put("artist", artist);
}
if (mbid != null) {
params.put("mbid", mbid);
}
if (lang != null) {
params.put("lang", lang);
}
if (username != null) {
params.put("username", username);
}
return new Parser<Artist>().getItem(baseUrl, params, "artist", new ArtistBuilder());
}
public User[] getTrackTopFans(String track, String artist, String mbid) throws IOException, WSError {
Map<String, String> params = createParams("track.getTopFans");
if (track != null) {
params.put("track", track);
}
if (artist != null) {
params.put("artist", artist);
}
if (mbid != null) {
params.put("mbid", mbid);
}
List<User> users = new Parser<User>().getList(baseUrl, params, "topfans", "user", new UserBuilder());
return users.toArray(new User[users.size()]);
}
public User[] getArtistTopFans(String artist, String mbid) throws IOException, WSError {
Map<String, String> params = createParams("artist.getTopFans");
if (artist != null) {
params.put("artist", artist);
}
if (mbid != null) {
params.put("mbid", mbid);
}
List<User> users = new Parser<User>().getList(baseUrl, params, "topfans", "user", new UserBuilder());
return users.toArray(new User[users.size()]);
}
public Event[] getArtistEvents(String artist) throws IOException, WSError {
Map<String, String> params = createParams("artist.getEvents");
if (artist != null) {
params.put("artist", artist);
}
List<Event> events = new Parser<Event>().getList(baseUrl, params, "events", "event", new EventBuilder());
return events.toArray(new Event[events.size()]);
}
public Event[] getUserEvents(String user) throws IOException, WSError {
Map<String, String> params = createParams("user.getEvents");
if (user != null) {
params.put("user", user);
}
List<Event> events = new Parser<Event>().getList(baseUrl, params, "events", "event", new EventBuilder());
return events.toArray(new Event[events.size()]);
}
public Event[] getPastUserEvents(String user) throws IOException, WSError {
Map<String, String> params = createParams("user.getPastEvents");
if (user != null) {
params.put("user", user);
}
List<Event> events = new Parser<Event>().getList(baseUrl, params, "events", "event", new EventBuilder());
return events.toArray(new Event[events.size()]);
}
public Event[] getUserFriendsEvents(String user) throws IOException, WSError {
Map<String, String> params = createParams("user.getFriendsEvents");
if (user != null) {
params.put("user", user);
}
List<Event> events = new Parser<Event>().getList(baseUrl, params, "events", "event", new EventBuilder());
return events.toArray(new Event[events.size()]);
}
public Event[] getUserRecommendedEvents(String user, String sk) throws IOException, WSError {
Map<String, String> params = createParams("user.getRecommendedEvents");
params.put("user", user);
params.put("sk", sk);
signParams(params);
List<Event> events = new Parser<Event>().getList(baseUrl, params, "events", "event", new EventBuilder());
return events.toArray(new Event[events.size()]);
}
public Event[] getNearbyEvents(String latitude, String longitude) throws IOException, WSError {
Map<String, String> params = createParams("geo.getEvents");
params.put("lat", latitude);
params.put("long", longitude);
params.put("distance", "50");
List<Event> events = new Parser<Event>().getList(baseUrl, params, "events", "event", new EventBuilder());
return events.toArray(new Event[events.size()]);
}
public Event[] getFestivalsForMetro(String metro, int page, String sk) throws IOException {
Map<String, String> params = createParams("geo.getEvents");
params.put("location", metro);
params.put("limit", "50");
params.put("festivalsonly", "1");
params.put("page", String.valueOf(page));
if(sk != null) {
params.put("sk", sk);
signParams(params);
}
List<Event> events = new Parser<Event>().getList(baseUrl, params, "events", "event", new EventBuilder());
return events.toArray(new Event[events.size()]);
}
public Event[] getUserFestivals(String user) throws IOException {
Map<String, String> params = createParams("user.getEvents");
if (user != null) {
params.put("user", user);
}
params.put("festivalsonly", "1");
List<Event> events = new Parser<Event>().getList(baseUrl, params, "events", "event", new EventBuilder());
return events.toArray(new Event[events.size()]);
}
public Event[] getUserFriendsFestivals(String user) throws IOException {
Map<String, String> params = createParams("user.getFriendsEvents");
if (user != null) {
params.put("user", user);
}
params.put("festivalsonly", "1");
List<Event> events = new Parser<Event>().getList(baseUrl, params, "events", "event", new EventBuilder());
return events.toArray(new Event[events.size()]);
}
public Artist[] getRecommendedLineupForEvent(String event, String sk) throws IOException {
Map<String, String> params = createParams("event.getRecommendedLineup");
if (event != null) {
params.put("event", event);
}
if (sk != null) {
params.put("sk", sk);
signParams(params);
}
List<Artist> artists = new Parser<Artist>().getList(baseUrl, params, "artists", "artist", new ArtistBuilder());
return artists.toArray(new Artist[artists.size()]);
}
public void attendEvent(String event, String status, String sk) throws IOException, WSError {
Map<String, String> params = createParams("event.attend");
params.put("event", event);
params.put("status", status);
params.put("sk", sk);
signParams(params);
post(baseUrl, params);
}
public Artist[] getUserTopArtists(String user, String period) throws IOException {
Map<String, String> params = createParams("user.getTopArtists");
if (user != null) {
params.put("user", user);
}
if (period != null) {
params.put("period", period);
}
List<Artist> artists = new Parser<Artist>().getList(baseUrl, params, "topartists", "artist", new ArtistBuilder());
return artists.toArray(new Artist[artists.size()]);
}
public Artist[] getUserRecommendedArtists(String user, String sk) throws IOException {
Map<String, String> params = createParams("user.getRecommendedArtists");
if (user != null) {
params.put("user", user);
}
params.put("sk", sk);
signParams(params);
List<Artist> artists = new Parser<Artist>().getList(baseUrl, params, "recommendations", "artist", new ArtistBuilder());
return artists.toArray(new Artist[artists.size()]);
}
public Album[] getUserTopAlbums(String user, String period) throws IOException {
Map<String, String> params = createParams("user.getTopAlbums");
if (user != null) {
params.put("user", user);
}
if (period != null) {
params.put("period", period);
}
List<Album> albums = new Parser<Album>().getList(baseUrl, params, "topalbums", "album", new AlbumBuilder());
return albums.toArray(new Album[albums.size()]);
}
public Track[] getUserTopTracks(String user, String period) throws IOException {
Map<String, String> params = createParams("user.getTopTracks");
if (user != null) {
params.put("user", user);
}
if (period != null) {
params.put("period", period);
}
List<Track> tracks = new Parser<Track>().getList(baseUrl, params, "toptracks", "track", new TrackBuilder());
return tracks.toArray(new Track[tracks.size()]);
}
public Track[] getUserRecentTracks(String user, String nowPlaying, int limit) throws IOException {
Map<String, String> params = createParams("user.getRecentTracks");
if (user != null) {
params.put("user", user);
}
if (nowPlaying != null && nowPlaying.length() > 0)
params.put("nowPlaying", nowPlaying);
if (limit > 0) {
params.put("limit", String.valueOf(limit));
}
List<Track> tracks = new Parser<Track>().getList(baseUrl, params, "recenttracks", "track", new TrackBuilder());
return tracks.toArray(new Track[tracks.size()]);
}
public void libraryAddAlbum(String album, String sk) throws IOException {
Map<String, String> params = createParams("library.addAlbum");
params.put("album", album);
params.put("sk", sk);
signParams(params);
post(baseUrl, params);
}
public void libraryAddArtist(String artist, String sk) throws IOException {
Map<String, String> params = createParams("library.addArtist");
params.put("artist", artist);
params.put("sk", sk);
signParams(params);
post(baseUrl, params);
}
public void libraryAddTrack(String track, String sk) throws IOException {
Map<String, String> params = createParams("library.addTrack");
params.put("track", track);
params.put("sk", sk);
signParams(params);
post(baseUrl, params);
}
public Tasteometer tasteometerCompare(String user1, String user2, int limit) throws IOException {
Map<String, String> params = createParams("tasteometer.compare");
params.put("type1", "user");
params.put("type2", "user");
params.put("value1", user1);
params.put("value2", user2);
if (limit > 0)
params.put("limit", String.valueOf(limit));
return TasteometerFunctions.compare(baseUrl, params);
}
public RadioPlayList[] getUserPlaylists(String username) throws IOException {
Map<String, String> params = createParams("user.getPlaylists");
params.put("user", username);
List<RadioPlayList> playlists = new Parser<RadioPlayList>().getList(baseUrl, params, "playlists", "playlist", new RadioPlayListBuilder());
return playlists.toArray(new RadioPlayList[playlists.size()]);
}
public Album getAlbumInfo(String artist, String album) throws IOException {
Map<String, String> params = createParams("album.getInfo");
if (artist != null)
params.put("artist", artist);
if (album != null)
params.put("album", album);
return new Parser<Album>().getItem(baseUrl, params, "album", new AlbumBuilder());
}
public void loveTrack(String artist, String track, String sk) throws IOException {
Map<String, String> params = createParams("track.love");
params.put("artist", artist);
params.put("track", track);
params.put("sk", sk);
signParams(params);
post(baseUrl, params);
}
public void banTrack(String artist, String track, String sk) throws IOException {
Map<String, String> params = createParams("track.ban");
params.put("artist", artist);
params.put("track", track);
params.put("sk", sk);
signParams(params);
post(baseUrl, params);
}
public void scrobbleTrack(String artist, String track, String album, long timestamp, int duration, String context, String streamid, String sk) throws IOException {
Map<String, String> params = createParams("track.scrobble");
params.put("artist", artist);
params.put("track", track);
if (album != null)
params.put("album", album);
if (streamid != null && streamid.length() > 0)
params.put("streamId", streamid);
params.put("timestamp", String.valueOf(timestamp));
if (duration > 0)
params.put("duration", String.valueOf(duration));
params.put("sk", sk);
signParams(params);
post(baseUrl, params);
}
public void updateNowPlaying(String artist, String track, String album, int duration, String context, String sk) throws IOException {
Map<String, String> params = createParams("track.updateNowPlaying");
params.put("artist", artist);
params.put("track", track);
if (album != null)
params.put("album", album);
if (duration > 0)
params.put("duration", String.valueOf(duration));
params.put("sk", sk);
signParams(params);
post(baseUrl, params);
}
public void removeNowPlaying(String artist, String track, String album, int duration, String context, String sk) throws IOException {
Map<String, String> params = createParams("track.removeNowPlaying");
params.put("artist", artist);
params.put("track", track);
if (album != null)
params.put("album", album);
if (duration > 0)
params.put("duration", String.valueOf(duration));
params.put("sk", sk);
signParams(params);
post(baseUrl, params);
}
public void shareTrack(String artist, String track, String recipient, String sk) throws IOException {
Map<String, String> params = createParams("track.share");
params.put("artist", artist);
params.put("track", track);
params.put("recipient", recipient);
params.put("sk", sk);
signParams(params);
post(baseUrl, params);
}
public void shareArtist(String artist, String recipient, String sk) throws IOException {
Map<String, String> params = createParams("artist.share");
params.put("artist", artist);
params.put("recipient", recipient);
params.put("sk", sk);
signParams(params);
post(baseUrl, params);
}
public void shareEvent(String event, String recipient, String sk) throws IOException {
Map<String, String> params = createParams("event.share");
params.put("event", event);
params.put("recipient", recipient);
params.put("sk", sk);
signParams(params);
post(baseUrl, params);
}
public void addTrackToPlaylist(String artist, String track, String playlistId, String sk) throws IOException {
Map<String, String> params = createParams("playlist.addTrack");
params.put("artist", artist);
params.put("track", track);
params.put("playlistID", playlistId);
params.put("sk", sk);
signParams(params);
post(baseUrl, params);
}
public RadioPlayList[] createPlaylist(String title, String description, String sk) throws IOException {
Map<String, String> params = createParams("playlist.create");
params.put("title", title);
params.put("description", description);
params.put("sk", sk);
signParams(params);
List<RadioPlayList> playlists = new Parser<RadioPlayList>().getList(baseUrl, params, "playlists", "playlist", new RadioPlayListBuilder());
return playlists.toArray(new RadioPlayList[playlists.size()]);
}
public Station[] getUserRecentStations(String user, String sk) throws IOException {
Map<String, String> params = createParams("user.getRecentStations");
params.put("user", user);
params.put("sk", sk);
signParams(params);
List<Station> stations = new Parser<Station>().getList(baseUrl, params, "recentstations", "station", new StationBuilder());
return stations.toArray(new Station[stations.size()]);
}
public Station searchForStation(String station) throws IOException {
Map<String, String> params = createParams("radio.search");
params.put("name", station);
return RadioFunctions.searchForStation(baseUrl, params);
}
public Artist[] topArtistsForTag(String tag) throws IOException {
Map<String, String> params = createParams("tag.getTopArtists");
params.put("tag", tag);
List<Artist> artists = new Parser<Artist>().getList(baseUrl, params, "topartists", "artist", new ArtistBuilder());
return artists.toArray(new Artist[artists.size()]);
}
public void signUp(String username, String password, String email) throws IOException {
Map<String, String> params = createParams("user.signUp");
params.put("username", username);
params.put("password", password);
params.put("email", email);
signParams(params);
post(baseUrl, params);
}
public Geo getGeo() throws IOException {
Map<String, String> params = createParams("bespoke.getGeo");
return new Parser<Geo>().getItem(baseUrl, params, "geo", new GeoBuilder());
}
public List<Metro> getMetros() throws IOException {
Map<String, String> params = createParams("geo.getMetros");
return new Parser<Metro>().getList(baseUrl, params, "metros", "metro", new MetroBuilder());
}
}