343 lines
13 KiB
C#
343 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.ServiceModel;
|
|
using System.ServiceModel.Activation;
|
|
using System.ServiceModel.Web;
|
|
using System.Text;
|
|
using JamesRSkemp.Music;
|
|
using System.Web.Hosting;
|
|
using System.Configuration;
|
|
using System.ComponentModel;
|
|
using System.Web;
|
|
|
|
namespace JamesRSkemp.Media.Web {
|
|
[ServiceContract]
|
|
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
|
|
[JavascriptCallbackBehavior(UrlParameterName = "callback")]
|
|
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
|
|
public class MusicService {
|
|
|
|
/// <summary>
|
|
/// Full path to the Xml file to use for data.
|
|
/// </summary>
|
|
String musicXml = HostingEnvironment.MapPath(ConfigurationManager.AppSettings["musicXmlLocation"].ToString());
|
|
|
|
/*
|
|
New items to create:
|
|
return tracks never played
|
|
currently part of Plays, but shouldn't be - Plays should change to different method
|
|
return tracks with a particular title
|
|
verify plays ordering is okay
|
|
either tweaks Plays/Date to allow for basing this on the last track's play date, or create new method to do so (instead of by today)
|
|
|
|
|
|
|
|
items currently don't sort, but should
|
|
data should be cached if possible - see how it impacts memory and performance (the latter is pretty quick)
|
|
*/
|
|
|
|
[WebGet(UriTemplate = "Testing/ReturnText/{text}")]
|
|
[Description("Return whatever text is passed.")]
|
|
public String ReturnText(String text) {
|
|
return text;
|
|
}
|
|
|
|
#region Xml Information
|
|
[WebGet(UriTemplate = "Data/UpdateDate")]
|
|
[Description("Get the date and time the data was last updated.")]
|
|
public String GetFileDate() {
|
|
return Track.GetUpdateDate(musicXml).ToString();
|
|
}
|
|
#endregion
|
|
|
|
#region Artists
|
|
[WebGet(UriTemplate = "Artists")]
|
|
[Description("Get a listing of artists, and a count of tracks by them.")]
|
|
public List<ArtistCount> GetArtists() {
|
|
return Track.GetTracks(musicXml).GroupBy(t => t.Artist).Select(t => new ArtistCount { Artist = t.Key, Count = t.Count() }).OrderBy(t => t.Artist).ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a listing of tracks by a particular artist.
|
|
/// </summary>
|
|
/// <param name="artist">Exact name of the artist to return tracks for.</param>
|
|
/// <returns>List of Track by particular artist.</returns>
|
|
[WebGet(UriTemplate = "Artists/{artist}")]
|
|
[Description("Get a listing of tracks by a particular artist.")]
|
|
public List<Track> GetArtistTracks(String artist) {
|
|
return Track.GetTracks(musicXml).Where(t => t.Artist == artist).ToList();
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Artists/{artist}/Ratings")]
|
|
[Description("Get all ratings used for a particular artist.")]
|
|
public List<RatingCount> GetArtistRatings(String artist) {
|
|
return GetArtistTracks(artist).Where(t => t.Rating != null).GroupBy(t => t.Rating).Select(t => new RatingCount { Rating = (t.Key ?? 0), Count = t.Count() }).OrderByDescending(t => t.Rating).ToList();
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Artists/{artist}/Ratings/{rating}")]
|
|
[Description("Get a listing of tracks by a particular artist, that have been given a particular rating.")]
|
|
public List<Track> GetArtistRatingTracks(String artist, String rating) {
|
|
return GetArtistTracks(artist).Where(t => t.Rating == int.Parse(rating)).ToList();
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Artists/{artist}/Albums")]
|
|
[Description("Get a listing of albums, with counts, for a particular artist.")]
|
|
public List<AlbumCount> GetArtistsAlbums(String artist) {
|
|
return GetArtistTracks(artist).GroupBy(t => t.Album).Select(t => new AlbumCount { Album = t.Key.TrimEnd(), Count = t.Count() }).ToList();
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Artists/{artist}/Albums/{album}")]
|
|
[Description("Get a listing of tracks for a particular album, by a particular artist.")]
|
|
public List<Track> GetArtistsAlbumTracks(String artist, String album) {
|
|
return GetArtistTracks(artist).Where(t => t.Album.TrimEnd() == album).ToList();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Albums
|
|
[WebGet(UriTemplate = "Albums")]
|
|
[Description("Get a listing of albums, with a count of tracks.")]
|
|
public List<AlbumCount> GetAlbums() {
|
|
return Track.GetTracks(musicXml).GroupBy(t => t.Album).Select(t => new AlbumCount { Album = t.Key, Count = t.Count() }).ToList();
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Albums/{album}")]
|
|
[Description("Get a listing of tracks for a particular album.")]
|
|
public List<Track> GetAlbumTracks(String album) {
|
|
return Track.GetTracks(musicXml).Where(t => t.Album.TrimEnd() == album).ToList();
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Albums?album={album}")]
|
|
[Description("Get a listing of tracks for a particular album.")]
|
|
public List<Track> GetAlbumTracksQueryString(String album) {
|
|
album = HttpUtility.UrlDecode(album);
|
|
return Track.GetTracks(musicXml).Where(t => t.Album == album).ToList();
|
|
}
|
|
#endregion
|
|
|
|
#region Ratings
|
|
[WebGet(UriTemplate = "Ratings")]
|
|
[Description("Get a listing of ratings, with the number of tracks with that rating.")]
|
|
public List<RatingCount> GetRatings() {
|
|
return Track.GetTracks(musicXml).GroupBy(t => t.Rating).Select(t => new RatingCount { Rating = (t.Key ?? 0), Count = t.Count() }).OrderByDescending(t => t.Rating).ToList();
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Ratings/{rating}")]
|
|
[Description("Get a listing of tracks with a particular rating. Returns a maximum of 1000 tracks.")]
|
|
public List<Track> GetRatingTracks(String rating) {
|
|
return Track.GetTracks(musicXml).Where(t => t.Rating == int.Parse(rating)).Take(1000).ToList();
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Ratings/{rating}/{page}")]
|
|
[Description("Get a listing of tracks with a particular rating. Returns 1000 records per page.")]
|
|
public List<Track> GetRatingTracksPaged(String rating, String page) {
|
|
return Track.GetTracks(musicXml).Where(t => t.Rating == int.Parse(rating)).Skip((int.Parse(page) - 1) * 1000).Take(1000).ToList();
|
|
}
|
|
#endregion
|
|
|
|
#region Added
|
|
[WebGet(UriTemplate = "Added/{year}")]
|
|
[Description("Get a listing of tracks that were last played in a particular year.")]
|
|
public List<Track> GetTracksAddedYear(String year) {
|
|
return Track.GetTracks(musicXml).Where(t => t.DateAdded != null && ((DateTime)t.DateAdded).Year == int.Parse(year)).OrderByDescending(t => t.DateAdded).ToList();
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Added/{year}/{month}")]
|
|
[Description("Get a listing of tracks that were last played in a particular year and month.")]
|
|
public List<Track> GetTracksAddedYearMonth(String year, String month) {
|
|
return GetTracksAddedYear(year).Where(t => t.DateAdded != null && ((DateTime)t.DateAdded).Month == int.Parse(month)).OrderByDescending(t => t.DateAdded).ToList();
|
|
}
|
|
#endregion
|
|
|
|
#region Genres
|
|
[WebGet(UriTemplate = "Genres")]
|
|
[Description("Get a listing of music genres, with the number of tracks given that genre.")]
|
|
public List<GenreCount> GetGenres() {
|
|
return Track.GetTracks(musicXml).GroupBy(t => t.Genre).Select(t => new GenreCount { Genre = t.Key, Count = t.Count() }).OrderBy(t => t.Genre).ToList();
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Genres/{genre}")]
|
|
[Description("Get a listing of tracks in a particular genre.")]
|
|
public List<Track> GetGenreTracks(String genre) {
|
|
return Track.GetTracks(musicXml).Where(t => t.Genre == genre).ToList();
|
|
}
|
|
#endregion
|
|
|
|
#region Played
|
|
[WebGet(UriTemplate = "Played/{year}")]
|
|
[Description("Get a listing of tracks that were last played in a particular year.")]
|
|
public List<Track> GetTracksPlayedYear(String year) {
|
|
return Track.GetTracks(musicXml).Where(t => t.LastPlayed != null && ((DateTime)t.LastPlayed).Year == int.Parse(year)).OrderByDescending(t => t.LastPlayed).ToList();
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Played/{year}/{month}")]
|
|
[Description("Get a listing of tracks that were last played in a particular year and month.")]
|
|
public List<Track> GetTracksPlayedYearMonth(String year, String month) {
|
|
return GetTracksPlayedYear(year).Where(t => t.LastPlayed != null && ((DateTime)t.LastPlayed).Month == int.Parse(month)).OrderByDescending(t => t.LastPlayed).ToList();
|
|
}
|
|
#endregion
|
|
|
|
#region Plays
|
|
[WebGet(UriTemplate = "Plays/Count/{count}")]
|
|
[Description("Get the last x tracks played, ordered by the last date played.")]
|
|
public List<Track> GetTracksPlayedLast(String count) {
|
|
return Track.GetTracks(musicXml).OrderByDescending(t => t.LastPlayed).Take(int.Parse(count)).ToList();
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Plays/Date/{days}")]
|
|
[Description("Get a listing of tracks, ordered by the last date played, over the last x days.")]
|
|
public List<Track> GetTracksByPlayDate(String days) {
|
|
return Track.GetTracks(musicXml).Where(t => t.LastPlayed >= DateTime.Now.AddDays(-int.Parse(days))).OrderByDescending(t => t.LastPlayed).ToList();
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Plays/Track/{count}")]
|
|
[Description("Get a listing of x tracks, ordered by the number of times if was played.")]
|
|
public List<Track> GetTracksByPlays(String count) {
|
|
if (count.ToLower() == "never") {
|
|
return Track.GetTracks(musicXml).Where(t => t.PlayCount == 0).ToList();
|
|
} else {
|
|
return Track.GetTracks(musicXml).OrderByDescending(t => t.PlayCount).Take(int.Parse(count)).ToList();
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Years
|
|
[WebGet(UriTemplate = "Years")]
|
|
[Description("Get a listing of years of tracks, with the number of tracks with that year.")]
|
|
public List<YearCount> GetYears() {
|
|
return Track.GetTracks(musicXml).GroupBy(t => t.Year).Select(t => new YearCount { Year = (t.Key ?? 0), Count = t.Count() }).OrderByDescending(t => t.Year).ToList();
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Years/{year}")]
|
|
[Description("Get a listing of tracks released in a particular year.")]
|
|
public List<Track> GetYearsTracks(String year) {
|
|
return Track.GetTracks(musicXml).Where(t => t.Year == int.Parse(year)).ToList();
|
|
}
|
|
#endregion
|
|
|
|
#region Track titles
|
|
|
|
[WebGet(UriTemplate = "Titles?title={title}&album={album}&artist={artist}")]
|
|
[Description("Get a listing of tracks with a particular title/name, and album and/or artist.")]
|
|
public List<Track> GetTracksQueryString(String title, String album, String artist) {
|
|
//title = System.Web.HttpUtility.UrlDecode(title);
|
|
//album = System.Web.HttpUtility.UrlDecode(album);
|
|
//artist = System.Web.HttpUtility.UrlDecode(artist);
|
|
|
|
if (String.IsNullOrWhiteSpace(title)) {
|
|
throw new WebFaultException(System.Net.HttpStatusCode.NotImplemented);
|
|
} else if (String.IsNullOrWhiteSpace(album) && String.IsNullOrWhiteSpace(artist)) {
|
|
return GetTitleTracks(title);
|
|
} else if (String.IsNullOrWhiteSpace(album)) {
|
|
return GetTitleArtistTracks(title, artist);
|
|
} else if (String.IsNullOrWhiteSpace(artist)) {
|
|
return GetTitleAlbumTracks(title, album);
|
|
} else {
|
|
return Track.GetTracks(musicXml).Where(t => t.Name == title && t.Album == album && t.Artist == artist).ToList();
|
|
}
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Titles/{title}")]
|
|
[Description("Get a listing of tracks with a particular title/name.")]
|
|
public List<Track> GetTitleTracks(String title) {
|
|
return Track.GetTracks(musicXml).Where(t => t.Name == title).ToList();
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Titles/{title}/Albums/{album}")]
|
|
[Description("Get a listing of tracks with a particular title/name, from a particular album.")]
|
|
public List<Track> GetTitleAlbumTracks(String title, String album) {
|
|
return Track.GetTracks(musicXml).Where(t => t.Name == title && t.Album == album).ToList();
|
|
}
|
|
|
|
[WebGet(UriTemplate = "Titles/{title}/Artists/{artist}")]
|
|
[Description("Get a listing of tracks with a particular title/name, by a particular artist.")]
|
|
public List<Track> GetTitleArtistTracks(String title, String artist) {
|
|
return Track.GetTracks(musicXml).Where(t => t.Name == title && t.Artist == artist).ToList();
|
|
}
|
|
|
|
/*
|
|
TODO:
|
|
/Titles
|
|
/Titles/{title}/Albums
|
|
/Titles/{title}/Artists
|
|
/Titles/?title={title}&album={album}&artist={artist} (and just check for those that aren't defined?)
|
|
*/
|
|
|
|
#endregion
|
|
|
|
#region Custom objects returned by methods.
|
|
/// <summary>
|
|
/// Artist name with a count of tracks by that artist.
|
|
/// </summary>
|
|
public class ArtistCount {
|
|
/// <summary>
|
|
/// Name of an artist.
|
|
/// </summary>
|
|
public String Artist { get; set; }
|
|
/// <summary>
|
|
/// Tracks by the artist.
|
|
/// </summary>
|
|
public int Count { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Album name with a count of tracks in it, across all discs.
|
|
/// </summary>
|
|
public class AlbumCount {
|
|
/// <summary>
|
|
/// Name of the album.
|
|
/// </summary>
|
|
public String Album { get; set; }
|
|
/// <summary>
|
|
/// Total number of tracks in the album, across all discs.
|
|
/// </summary>
|
|
public int Count { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Genre with a count of tracks assigned it.
|
|
/// </summary>
|
|
public class GenreCount {
|
|
/// <summary>
|
|
/// Name of the genre.
|
|
/// </summary>
|
|
public String Genre { get; set; }
|
|
/// <summary>
|
|
/// Tracks of this genre.
|
|
/// </summary>
|
|
public int Count { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Rating value with a count of tracks using that rating.
|
|
/// </summary>
|
|
public class RatingCount {
|
|
/// <summary>
|
|
/// Rating between 0 and 5, inclusive.
|
|
/// </summary>
|
|
public int Rating { get; set; }
|
|
/// <summary>
|
|
/// Number of tracks with that rating.
|
|
/// </summary>
|
|
public int Count { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Four digit years with a count of tracks released that year.
|
|
/// </summary>
|
|
public class YearCount {
|
|
/// <summary>
|
|
/// Four digit year of track or album the track is on.
|
|
/// </summary>
|
|
public int Year { get; set; }
|
|
/// <summary>
|
|
/// Number of tracks released that year.
|
|
/// </summary>
|
|
public int Count { get; set; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
} |