using System; using System.Collections.Generic; using System.Linq; using Nancy; using Sony.Filtr.Applications; using Sony.Filtr.Contracts.Definitions; using Sony.Filtr.Contracts.Entities; using Sony.Filtr.Contracts.Entities.Buzz; using Sony.Filtr.Utility; using Nancy.ModelBinding; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Sony.Filtr.AdminAPI.Utility; using Sony.Filtr.AdminSearch; using Sony.Filtr.AdminSearch.Models; using System.Threading.Tasks; namespace Sony.Filtr.AdminAPI.Modules.SpotifySpecific { public class SearchModule : BaseModule { public SearchModule(ApplicationInstanceManager applicationInstanceManager, AdminSearchManager adminSearchManager) : base(applicationInstanceManager) { Get["GetSearchResults", "/spotifySearch/", true] = async (parameters, cx) => { var searchTerm = (string)Request.Query.search; if (string.IsNullOrWhiteSpace(searchTerm)) { return HttpStatusCode.BadRequest; } var limit = Maybe.ToIntOrFallback((string)Request.Query.limit, 10); var searchBuzzUsersTask = adminSearchManager.SearchBuzzUsersAsync(searchTerm, MusicService.Spotify, limit); var searchSpotifyPlaylistResultTask = adminSearchManager.SearchSpotifyPlaylistAsync(searchTerm, limit); var buzzUsers = await searchBuzzUsersTask; var spotifyPlaylists = await searchSpotifyPlaylistResultTask; var resultModel = BuildSearchResultViewModel(spotifyPlaylists, buzzUsers); return Response.AsJson(resultModel); }; Get["GetSearchResults", "/amazonSearch/", true] = async (parameters, cx) => { var searchTerm = (string)Request.Query.search; if (string.IsNullOrWhiteSpace(searchTerm)) { return HttpStatusCode.BadRequest; } var limit = Maybe.ToIntOrFallback((string)Request.Query.limit, 10); var searchAmazonPlaylistResultTask = adminSearchManager.SearchAmazonPlaylistAsync(searchTerm, limit); var spotifyPlaylists = await searchAmazonPlaylistResultTask; var resultModel = BuildAmazonSearchResultViewModel(spotifyPlaylists); return Response.AsJson(resultModel); }; Get["GetSearchHistory", "/spotifySearchHistory/{userId}", true] = async (parameters, cx) => { var userId = (string)parameters.userId; if (string.IsNullOrWhiteSpace(userId)) { return HttpStatusCode.BadRequest; } var limit = Maybe.ToIntOrFallback((string)Request.Query.limit, 25); var offset = Maybe.ToIntOrFallback((string)Request.Query.offset, 0); var paginatedViewModels = await GetSearchItems(userId, limit, offset, Vendors.Spotify); return Response.AsJson(paginatedViewModels); }; Get["GetSearchHistory", "/appleMusicSearchHistory/{userId}", true] = async (parameters, cx) => { var userId = (string)parameters.userId; if (string.IsNullOrWhiteSpace(userId)) { return HttpStatusCode.BadRequest; } var limit = Maybe.ToIntOrFallback((string)Request.Query.limit, 25); var offset = Maybe.ToIntOrFallback((string)Request.Query.offset, 0); var paginatedViewModels = await GetSearchItems(userId, limit, offset, Vendors.AppleMusic); return Response.AsJson(paginatedViewModels); }; Get["GetSearchHistory", "/amazonSearchHistory/{userId}", true] = async (parameters, cx) => { var userId = (string)parameters.userId; if (string.IsNullOrWhiteSpace(userId)) { return HttpStatusCode.BadRequest; } var limit = Maybe.ToIntOrFallback((string)Request.Query.limit, 25); var offset = Maybe.ToIntOrFallback((string)Request.Query.offset, 0); var paginatedViewModels = await GetSearchItems(userId, limit, offset, Vendors.Amazon); return Response.AsJson(paginatedViewModels); }; Post["AddSearchHistory", "/spotifySearchHistory/{userId}", true] = async (parameters, cx) => { var userId = (string)parameters.userId; if (string.IsNullOrWhiteSpace(userId)) { return HttpStatusCode.BadRequest; } var historyItem = this.Bind(); if (string.IsNullOrWhiteSpace(historyItem?.Uri)) return HttpStatusCode.BadRequest; await AddSearchItem(historyItem, userId, "Spotify"); return HttpStatusCode.Accepted; }; Post["AddSearchHistory", "/appleMusicSearchHistory/{userId}", true] = async (parameters, cx) => { var userId = (string)parameters.userId; if (string.IsNullOrWhiteSpace(userId)) { return HttpStatusCode.BadRequest; } var historyItem = this.Bind(); if (string.IsNullOrWhiteSpace(historyItem?.Uri)) return HttpStatusCode.BadRequest; await AddSearchItem(historyItem, userId, "AppleMusic"); return HttpStatusCode.Accepted; }; Post["AddSearchHistory", "/amazonSearchHistory/{userId}", true] = async (parameters, cx) => { var userId = (string)parameters.userId; if (string.IsNullOrWhiteSpace(userId)) { return HttpStatusCode.BadRequest; } var historyItem = this.Bind(); if (string.IsNullOrWhiteSpace(historyItem?.Uri)) return HttpStatusCode.BadRequest; await AddSearchItem(historyItem, userId, "Amazon"); return HttpStatusCode.Accepted; }; async Task AddSearchItem(SearchHistoryItemCreateModel historyItem, string userId, string source) { var link = new SpotifyLink(historyItem.Uri); var itemType = GetItemType(link); await adminSearchManager.AddSearchHistoryItemAsync(userId, source, historyItem.Uri, itemType, historyItem.SearchTerm); } async Task> GetSearchItems(string userId, int limit, int offset, Vendors source) { var searchHistory = await adminSearchManager.GetSearchHistoryItemsAsync(userId, source, limit, offset); var viewModels = searchHistory.Items.Select(h => new SearchHistoryItemViewModel() { ItemType = h.SearchResultType, Uri = h.SearchResultUri, LatestTimestamp = h.Timestamp, AccountName = h.PlaylistOwnerName }).ToList(); var paginatedViewModels = new PaginatedContent() { Items = viewModels, Pagination = searchHistory.Pagination }; return paginatedViewModels; } } private static SearchHistoryItemType GetItemType(SpotifyLink link) { var itemType = SearchHistoryItemType.User; if (link.IsAlbum()) itemType = SearchHistoryItemType.Album; else if (link.IsArtist()) itemType = SearchHistoryItemType.Artist; else if (link.IsPlaylist()) itemType = SearchHistoryItemType.Playlist; else if (link.IsTrack()) itemType = SearchHistoryItemType.Track; return itemType; } private SearchResultViewModel BuildSearchResultViewModel(List playlistSearchResults, List buzzUsers) { var resultModel = new SearchResultViewModel() { Playlists = playlistSearchResults.Select(BuildPlaylist).ToList(), Users = buzzUsers.Select(BuildUser).ToList() }; return resultModel; } private AmazonSearchResultViewModel BuildAmazonSearchResultViewModel(List playlistSearchResults) { var resultModel = new AmazonSearchResultViewModel() { Playlists = playlistSearchResults.Select(BuildPlaylist).ToList() }; return resultModel; } private SearchUserViewModel BuildUser(BuzzUser buzzUser) { return new SearchUserViewModel() { Name = string.IsNullOrWhiteSpace(buzzUser.DisplayName) ? buzzUser.Username : buzzUser.DisplayName, CountryCode = buzzUser.CountryCode, Subscribers = buzzUser.Subscribers, Uri = SpotifyLink.ParseUserLink(buzzUser.Username).Uri, ImageUrl = ImageUrlUtility.GetAbsoluteImageUrl(buzzUser.Image), }; } private SpotifySearchPlaylistViewModel BuildPlaylist(SpotifyPlaylistIndexItem playlist) { return new SpotifySearchPlaylistViewModel() { Name = playlist.Name, Uri = playlist.PlaylistUri, CountryCode = playlist.CountryCode, Subscribers = playlist.Followers, Image = ImageUrlUtility.GetAbsoluteImageUrl(playlist.Image), AccountName = playlist.UserDisplayName ?? playlist.User, }; } private AmazonSearchPlaylistViewModel BuildPlaylist(AmazonPlaylistIndexItem playlist) { return new AmazonSearchPlaylistViewModel() { Name = playlist.Name, PlaylistUri = playlist.PlaylistUri, CountryCode = playlist.CountryCode, AmazonPlaylistId = playlist.AmazonPlaylistId, ImageUri = playlist.ImageUri, DspPlaylistId = playlist.DspPlaylistId, PlaylistId = playlist.PlaylistId, Rank = playlist.Rank, TracksNumber = playlist.TracksNumber }; } } public class SearchResultViewModel { public List Playlists { get; set; } public List Users { get; set; } } public class AmazonSearchResultViewModel { public List Playlists { get; set; } } public class AmazonSearchPlaylistViewModel { public string Name { get; set; } public string PlaylistId { get; set; } public string PlaylistUri { get; set; } public int TracksNumber { get; set; } public string CountryCode { get; set; } public string Rank { get; set; } public int DspPlaylistId { get; set; } public string AmazonPlaylistId { get; set; } public string ImageUri { get; set; } } public class SpotifySearchPlaylistViewModel { public string Name { get; set; } public string Uri { get; set; } public string Image { get; set; } public int? Subscribers { get; set; } public string CountryCode { get; set; } public string AccountName { get; set; } } public class SearchUserViewModel { public string Name { get; set; } public string Uri { get; set; } public int? Subscribers { get; set; } public string CountryCode { get; set; } public string ImageUrl { get; set; } } public class SearchHistoryItemViewModel { [JsonConverter(typeof(StringEnumConverter))] public SearchHistoryItemType ItemType { get; set; } public string Uri { get; set; } public DateTime LatestTimestamp { get; set; } public string AccountName { get; set; } } public class SearchHistoryItemCreateModel { public string Uri { get; set; } public string SearchTerm { get; set; } } }