// Track.cs // // Copyright (C) 2008 Amr Hassan // // 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // using System; using System.Collections.Generic; using System.Globalization; using System.Xml; namespace Lastfm.Services { /// /// A Last.fm track. /// public class Track : Base, IEquatable, IShareable, ITaggable, IHasURL { /// /// The track title. /// public string Title {get; private set;} /// /// The artist. /// public Artist Artist {get; private set;} /// /// MBID /// public string MBID { get; private set; } /// /// The track wiki on Last.fm. /// public Wiki Wiki { get { return new TrackWiki(this, Session); } } public Track(string artistName, string title, string mbid, Session session) : base(session) { Title = title; Artist = new Artist(artistName, Session); MBID = mbid; } public Track(string artistName, string title, Session session) :base(session) { Title = title; Artist = new Artist(artistName, Session); } public Track(Artist artist, string title, Session session) :base(session) { Title = title; Artist = artist; } /// /// String representation of the object. /// /// /// A /// public override string ToString () { return this.Artist + " - " + this.Title; } internal override RequestParameters getParams () { RequestParameters p = new Lastfm.RequestParameters(); p["artist"] = Artist.Name; p["track"] = Title; return p; } /// /// A unique Last.fm ID. /// /// /// A /// public int GetID() { XmlDocument doc = request("track.getInfo"); return Int32.Parse(extract(doc, "id")); } /// /// Returns the duration. /// /// /// A /// public TimeSpan GetDuration() { XmlDocument doc = request("track.getInfo"); // Duration is returned in milliseconds. return new TimeSpan(0, 0, 0, 0, Int32.Parse(extract(doc, "duration"))); } /// /// Returns true if the track is available for streaming. /// /// /// A /// public bool IsStreamable() { XmlDocument doc = request("track.getInfo"); int value = Int32.Parse(extract(doc, "streamable")); if (value == 1) return true; else return false; } /// /// Returns the album of this track. /// /// /// A /// public Album GetAlbum() { XmlDocument doc = request("track.getInfo"); if (doc.GetElementsByTagName("album").Count > 0) { XmlNode n = doc.GetElementsByTagName("album")[0]; string artist = extract(n, "artist"); string title = extract(n, "title"); return new Album(artist, title, Session); }else{ return null; } } /// /// Ban this track. /// public void Ban() { //This method requires authentication requireAuthentication(); request("track.ban"); } public TopTrack[] GetSimilar() { XmlDocument document = base.request("track.getSimilar"); List list = new List(); foreach (XmlNode node in document.GetElementsByTagName("track")) { Track track = new Track(base.extract(node, "name", 1), base.extract(node, "name"), base.Session); NumberFormatInfo provider = new NumberFormatInfo { NumberDecimalSeparator = "." }; int playcount = (int)(double.Parse(base.extract(node, "match"), provider) * 100.0); list.Add(new TopTrack(track, playcount)); } return list.ToArray(); } /// /// Love this track. /// public void Love() { //This method requires authentication requireAuthentication(); request("track.love"); } /// /// Check to see if this object equals another. /// /// /// A /// /// /// A /// public bool Equals(Track track) { return(track.Title == this.Title && track.Artist.Name == this.Artist.Name); } /// /// Share this track with others. /// /// /// A /// /// /// A /// public void Share(Recipients recipients, string message) { if (recipients.Count > 1) { foreach(string recipient in recipients) { Recipients r = new Recipients(); r.Add(recipient); Share(r, message); } return; } requireAuthentication(); RequestParameters p = getParams(); p["recipient"] = recipients[0]; p["message"] = message; request("track.Share", p); } /// /// Share this track with others. /// /// /// A /// public void Share(Recipients recipients) { if (recipients.Count > 1) { foreach(string recipient in recipients) { Recipients r = new Recipients(); r.Add(recipient); Share(r); } return; } requireAuthentication(); RequestParameters p = getParams(); p["recipient"] = recipients[0]; request("track.Share", p); } /// /// Search for tracks on Last.fm. /// /// /// A /// /// /// A /// /// /// A /// /// /// A /// public static TrackSearch Search(string artist, string title, Session session) { return new TrackSearch(artist, title, session); } /// /// Search for tracks on Last.fm. /// /// /// A /// /// /// A /// /// /// A /// public static TrackSearch Search(string title, Session session) { return new TrackSearch(title, session); } /// /// Add tags to this track. /// /// /// A /// public void AddTags(params Tag[] tags) { //This method requires authentication requireAuthentication(); foreach(Tag tag in tags) { RequestParameters p = getParams(); p["tags"] = tag.Name; request("track.addTags", p); } } /// /// Add tags to this track. /// /// /// A /// public void AddTags(params string[] tags) { foreach(string tag in tags) AddTags(new Tag(tag, Session)); } /// /// Add tags to this track. /// /// /// A /// public void AddTags(TagCollection tags) { foreach(Tag tag in tags) AddTags(tag); } /// /// Returns the tags set by the authenticated user to this track. /// /// /// A /// public Tag[] GetTags() { //This method requires authentication requireAuthentication(); XmlDocument doc = request("track.getTags"); TagCollection collection = new TagCollection(Session); foreach(string name in this.extractAll(doc, "name")) collection.Add(name); return collection.ToArray(); } /// /// Return the top tags. /// /// /// A /// public TopTag[] GetTopTags() { XmlDocument doc = request("track.getTopTags"); List list = new List(); foreach(XmlNode n in doc.GetElementsByTagName("tag")) list.Add(new TopTag(new Tag(extract(n, "name"), Session), Int32.Parse(extract(n, "count")))); return list.ToArray(); } /// /// Returns the top tags. /// /// /// A /// /// /// A /// public TopTag[] GetTopTags(int limit) { return this.sublist(GetTopTags(), limit); } /// /// Remove a bunch of tags from this track. /// /// /// A /// public void RemoveTags(params Tag[] tags) { //This method requires authentication requireAuthentication(); foreach(Tag tag in tags) { RequestParameters p = getParams(); p["tag"] = tag.Name; request("track.removeTag", p); } } /// /// Remove a bunch of tags from this track. /// /// /// A /// public void RemoveTags(params string[] tags) { //This method requires authentication requireAuthentication(); foreach(string tag in tags) RemoveTags(new Tag(tag, Session)); } /// /// Remove a bunch of tags from this track. /// /// /// A /// public void RemoveTags(TagCollection tags) { foreach(Tag tag in tags) RemoveTags(tag); } /// /// Set the tags of this tracks to only those tags. /// /// /// A /// public void SetTags(string[] tags) { List list = new List(); foreach(string name in tags) list.Add(new Tag(name, Session)); SetTags(list.ToArray()); } /// /// Set the tags of this tracks to only those tags. /// /// /// A /// public void SetTags(Tag[] tags) { List newSet = new List(tags); List current = new List(GetTags()); List toAdd = new List(); List toRemove = new List(); foreach(Tag tag in newSet) if(!current.Contains(tag)) toAdd.Add(tag); foreach(Tag tag in current) if(!newSet.Contains(tag)) toRemove.Add(tag); if (toAdd.Count > 0) AddTags(toAdd.ToArray()); if (toRemove.Count > 0) RemoveTags(toRemove.ToArray()); } /// /// Set the tags of this tracks to only those tags. /// /// /// A /// public void SetTags(TagCollection tags) { SetTags(tags.ToArray()); } /// /// Clear all the tags from this track. /// public void ClearTags() { foreach(Tag tag in GetTags()) RemoveTags(tag); } /// /// Returns the top fans. /// /// /// A /// public TopFan[] GetTopFans() { XmlDocument doc = request("track.getTopFans"); List list = new List(); foreach(XmlNode node in doc.GetElementsByTagName("user")) list.Add(new TopFan(new User(extract(node, "name"), Session), Int32.Parse(extract(node, "weight")))); return list.ToArray(); } /// /// Returns the top fans. /// /// /// A /// /// /// A /// public TopFan[] GetTopFans(int limit) { return sublist(GetTopFans(), limit); } /// /// Returns the track's MusicBrainz id. /// /// /// A /// public string GetMBID() { XmlDocument doc = request("track.getInfo"); return doc.GetElementsByTagName("mbid")[0].InnerText; } /// /// Returns a track by its MusicBrainz id. /// /// /// A /// /// /// A /// /// /// A /// public static Track GetByMBID(string mbid, Session session) { RequestParameters p = new Lastfm.RequestParameters(); p["mbid"] = mbid; XmlDocument doc = (new Request("track.getInfo", session, p)).execute(); string title = doc.GetElementsByTagName("name")[0].InnerText; string artist = doc.GetElementsByTagName("name")[1].InnerText; return new Track(artist, title, session); } /// /// Returns the Last.fm page of this object. /// /// /// A /// /// /// A /// public string GetURL(SiteLanguage language) { string domain = getSiteDomain(language); return "http://" + domain + "/music/" + urlSafe(Artist.Name) + "/_/" + urlSafe(Title); } /// /// The object's Last.fm page url. /// public string URL { get { return GetURL(SiteLanguage.English); } } /// /// Add this track to a /// /// /// A /// public void AddToPlaylist(Playlist playlist) { playlist.AddTrack(this); } } }