using System.Linq; using Nancy; using Nancy.ModelBinding; using Sony.Filtr.Contracts.Abstractions; using Sony.Filtr.Contracts.Entities; using Sony.Filtr.Core; using Sony.Filtr.Playlists.Spotify; using Sony.Filtr.Utility; using Sony.Filtr.Utility.Extensions; using Sony.Filtr.SpotifyWebAPI; using Sony.Filtr.Contracts.Definitions; using Sony.Filtr.Utility.Logging; using System.Threading.Tasks; using System.Collections.Generic; using Sony.Filtr.AppleMusic; namespace Sony.Filtr.AdminAPI.Modules { public class StarredTrackModule : BaseModule { private readonly AppleMusicSongManager _appleMusicSongManager; public StarredTrackModule( IApplicationInstanceManager applicationInstanceManager, StarredContentManager starredContentManager, SpotifyTrackManager spotifyTrackManager, SpotifyWebApi spotifyWebApi, ISonyMusicManager sonyMusicManager, AppleMusicApi appleMusicApi, AppleMusicSongManager appleMusicSongManager, ILogger logger) : base(applicationInstanceManager, logger) { Get["GetStarredTracks", "/starredContent/{userId}", true] = async (parameters, cx) => { var result = await LogActionWrapper.Execute( async () => await GetStarredTracks(starredContentManager, spotifyTrackManager, spotifyWebApi, sonyMusicManager, parameters, Request), Logger, "/starredContent/{userId} -> GetStarredTracks", ExtractRequestData(Request)); return result; }; Post["AddStarredTrack", "/starredContent/{userId}", true] = async (parameters, cx) => { string userId = (string)parameters.userId; string market = (string)Request.Query.market; if (string.IsNullOrWhiteSpace(userId)) { return HttpStatusCode.BadRequest; } var starred = this.Bind(); if (string.IsNullOrWhiteSpace(starred?.Uri)) { return HttpStatusCode.BadRequest; } var trackId = new SpotifyLink(starred.Uri).ExtractTrackID(); string isrc = null; if (string.IsNullOrEmpty(trackId)) { long tempId; if (long.TryParse(starred.Uri, out tempId)) { isrc = (await appleMusicApi.GetSongsAsync(string.IsNullOrEmpty(market) ? "us" : market, new List() { tempId })).Select(x => x.attributes.isrc).FirstOrDefault(); if (isrc == null) { isrc = (await appleMusicSongManager.GetISRCAsync(new List() { tempId })); } } else { return HttpStatusCode.BadRequest; } } else { var spotifyTrack = (await spotifyWebApi.GetAllTracksAsync(new List() { trackId }, market)).FirstOrDefault(); if (spotifyTrack != null && spotifyTrack.external_ids != null && spotifyTrack.external_ids.isrc != null) { isrc = spotifyTrack.external_ids.isrc; } else { var spotifyTrackFromDB = (await spotifyTrackManager.GetFullLocalTracksAsync(new List() { trackId })).FirstOrDefault(); if (spotifyTrackFromDB != null) { isrc = spotifyTrackFromDB.ISRC; } } } var hasAlreadyStarred = starredContentManager.HasStarredContent(userId, starred.Uri); if (!hasAlreadyStarred) { var addedContent = starredContentManager.AddStarredContent(new StarredContent() { Uri = starred.Uri, UserId = userId, ISRC = isrc }); } return HttpStatusCode.Accepted; }; Delete["DeleteStarredTrack", "/starredContent/{userId}"] = parameters => { string userId = (string)parameters.userId; if (string.IsNullOrWhiteSpace(userId)) { return HttpStatusCode.BadRequest; } var starredContentUri = (string)Request.Query.uri; if (string.IsNullOrWhiteSpace(starredContentUri)) { return HttpStatusCode.BadRequest; } var hasStarred = starredContentManager.HasStarredContent(userId, starredContentUri); if (hasStarred) { starredContentManager.RemoveStarredContent(userId, starredContentUri); } return HttpStatusCode.OK; }; } private async Task GetStarredTracks( StarredContentManager starredContentManager, SpotifyTrackManager spotifyTrackManager, SpotifyWebApi spotifyWebApi, ISonyMusicManager sonyMusicManager, dynamic parameters, Request request) { string userId = (string)parameters.userId; if (string.IsNullOrWhiteSpace(userId)) { return new Response { StatusCode = HttpStatusCode.BadRequest, ReasonPhrase = "UserID is required." }; } var limit = Maybe.ToIntOrFallback((string)request.Query.limit, 100); var offset = Maybe.ToIntOrFallback((string)request.Query.offset, 0); var market = (string)request.Query.market; var starredContent = starredContentManager.GetStarredContent(userId); var trackIds = starredContent.Select(x => new SpotifyLink(x.Uri).ExtractTrackID()).OfType().Where(x => !string.IsNullOrEmpty(x)).ToList(); var spotifyTracks = (await spotifyWebApi.GetAllTracksAsync(trackIds)).OfType(); var albumIds = spotifyTracks.Select(x => x.album.id); var spotifyAlbums = await spotifyWebApi.GetAllAlbumInfoAsync(albumIds); var sonyAlbumsList = (await sonyMusicManager.IsSonyAlbumAsync(spotifyAlbums.Select(x => x.external_ids.upc).ToList(), MusicService.Spotify, market)).Distinct().ToList(); var viewModels = starredContent.Select(c => new StarredTrackViewModel() { Uri = IsApple(c.Uri)? c.Uri:spotifyTracks.Where(x => x.uri == c.Uri).Select(x => x.uri).FirstOrDefault(), IsSony = spotifyTrackManager.IsSonyByUrlAndUpc(spotifyTracks, spotifyAlbums, sonyAlbumsList, c.Uri) }).Where(x => !string.IsNullOrEmpty(x.Uri)).ToList(); PaginatedContent paginatedContent = viewModels.Paginate(limit, offset); return Response.AsJson(paginatedContent); } private bool IsApple(string uri) { long tempId; if (long.TryParse(uri, out tempId)) { return true; } return false; } } public class StarredTrackPostObject { public string Uri { get; set; } } public class StarredTrackViewModel { public string Uri { get; set; } public bool? IsSony { get; set; } } }