@ -22,13 +22,11 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
private readonly Logger _logger ;
private readonly IHttpRequestBuilderFactory _requestBuilder ;
private readonly IHttpRequestBuilderFactory _internalRequestBuilder ;
public SkyHookProxy ( IHttpClient httpClient , ILidarrCloudRequestBuilder requestBuilder , Logger logger )
{
_httpClient = httpClient ;
_requestBuilder = requestBuilder . Search ;
_internalRequestBuilder = requestBuilder . InternalSearch ;
_logger = logger ;
}
@ -67,153 +65,97 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
public List < Series > SearchForNewSeries ( string title )
{
try
{
var lowerTitle = title . ToLowerInvariant ( ) ;
Console . WriteLine ( "Searching for " + lowerTitle ) ;
//if (lowerTitle.StartsWith("tvdb:") || lowerTitle.StartsWith("tvdbid:"))
//{
// var slug = lowerTitle.Split(':')[1].Trim();
// int tvdbId;
// if (slug.IsNullOrWhiteSpace() || slug.Any(char.IsWhiteSpace) || !int.TryParse(slug, out tvdbId) || tvdbId <= 0)
// {
// return new List<Series>();
// }
// try
// {
// return new List<Series> { GetSeriesInfo(tvdbId).Item1 };
// }
// catch (SeriesNotFoundException)
// {
// return new List<Series>();
// }
//}
// Majora: Temporarily, use iTunes to test.
var httpRequest = _requestBuilder . Create ( )
. AddQueryParam ( "entity" , "album" )
. AddQueryParam ( "term" , title . ToLower ( ) . Trim ( ) )
. Build ( ) ;
Console . WriteLine ( "httpRequest: " , httpRequest ) ;
// TODO: Remove this API
var tempList = new List < Series > ( ) ;
var tempSeries = new Series ( ) ;
tempSeries . Title = "AFI" ;
tempList . Add ( tempSeries ) ;
return tempList ;
}
var httpResponse = _httpClient . Get < List < ShowResource > > ( httpRequest ) ;
//Console.WriteLine("Response: ", httpResponse.GetType());
//_logger.Info("Response: ", httpResponse.Resource.ResultCount);
public Tuple < Artist , List < Track > > GetArtistInfo ( string spotifyId )
{
//_logger.Info("HTTP Response: ", httpResponse.Resource.ResultCount);
var tempList = new List < Series > ( ) ;
var tempSeries = new Series ( ) ;
tempSeries . Title = "AFI" ;
tempList . Add ( tempSeries ) ;
return tempList ;
return httpResponse . Resource . SelectList ( MapSeries ) ;
}
catch ( HttpException )
{
throw new SkyHookException ( "Search for '{0}' failed. Unable to communicate with SkyHook." , title ) ;
}
catch ( Exception ex )
{
_logger . Warn ( ex , ex . Message ) ;
throw new SkyHookException ( "Search for '{0}' failed. Invalid response received from SkyHook." , title ) ;
}
}
_logger . Debug ( "Getting Artist with SpotifyId of {0}" , spotifyId ) ;
//public Artist GetArtistInfo(int itunesId)
//{
// Console.WriteLine("[GetArtistInfo] id:" + itunesId);
// //https://itunes.apple.com/lookup?id=909253
// //var httpRequest = _requestBuilder.Create()
// // .SetSegment("route", "lookup")
// // .AddQueryParam("id", itunesId.ToString())
// // .Build();
// // TODO: Add special header, add Overview to Artist model
// var httpRequest = _requestBuilder.Create()
// .SetSegment("route", "viewArtist")
// .AddQueryParam("id", itunesId.ToString())
// .Build();
// httpRequest.Headers.Add("X-Apple-Store-Front", "143459-2,32 t:music3");
// httpRequest.AllowAutoRedirect = true;
// httpRequest.SuppressHttpError = true;
// var httpResponse = _httpClient.Get<ArtistResource>(httpRequest);
// if (httpResponse.HasHttpError)
// {
// if (httpResponse.StatusCode == HttpStatusCode.NotFound)
// {
// throw new ArtistNotFoundException(itunesId);
// }
// else
// {
// throw new HttpException(httpRequest, httpResponse);
// }
// }
// Console.WriteLine("GetArtistInfo, GetArtistInfo");
// return MapArtists(httpResponse.Resource)[0];
//}
///v1/albums/{id}
/ /
public Tuple < Artist , List < Track > > GetArtistInfo ( int itunesId )
{
// TODO: [GetArtistInfo]: This needs to return a set of tracks from iTunes.
// This call is expected to return information about an artist and the tracks that make up said artist.
// To do this, we need 2-3 API calls. 1st is to gather information about the artist and the albums the artist has. This is https://itunes.apple.com/search?entity=album&id=itunesId
// Next call is to populate the overview field and calls the internal API
// Finally, we need to, for each album, get all tracks, which means calling this N times: https://itunes.apple.com/search?entity=musicTrack&term=artistName (id will not work)
_logger . Debug ( "Getting Artist with iTunesID of {0}" , itunesId ) ;
var httpRequest1 = _requestBuilder . Create ( )
. SetSegment ( "route" , "lookup" )
. AddQueryParam ( "id" , itunesId . ToString ( ) )
// We need to perform a direct lookup of the artist
var httpRequest = _requestBuilder . Create ( )
. SetSegment ( "route" , "artists/" + spotifyId )
//.SetSegment("route", "search")
//.AddQueryParam("type", "artist,album")
//.AddQueryParam("q", spotifyId.ToString())
. Build ( ) ;
var httpRequest2 = _internalRequestBuilder . Create ( )
. SetSegment ( "route" , "viewArtist" )
. AddQueryParam ( "id" , itunesId . ToString ( ) )
. Build ( ) ;
httpRequest2 . Headers . Add ( "X-Apple-Store-Front" , "143459-2,32 t:music3" ) ;
httpRequest2 . Headers . ContentType = "application/json" ;
httpRequest 1 . AllowAutoRedirect = true ;
httpRequest 1 . SuppressHttpError = true ;
httpRequest . AllowAutoRedirect = true ;
httpRequest . SuppressHttpError = true ;
var httpResponse = _httpClient . Get < Artist Resource> ( httpRequest 1 ) ;
var httpResponse = _httpClient . Get < ArtistInfoResource > ( httpRequest ) ;
if ( httpResponse . HasHttpError )
{
if ( httpResponse . StatusCode = = HttpStatusCode . NotFound )
{
throw new ArtistNotFoundException ( itunes Id) ;
throw new ArtistNotFoundException ( spotifyId ) ;
}
else
{
throw new HttpException ( httpRequest 1 , httpResponse ) ;
throw new HttpException ( httpRequest , httpResponse ) ;
}
}
List < Artist > artists = MapArtists ( httpResponse . Resource ) ;
List < Artist > newArtists = new List < Artist > ( artists . Count ) ;
int count = 0 ;
foreach ( var artist in artists )
Artist artist = new Artist ( ) ;
artist . ArtistName = httpResponse . Resource . Name ;
artist . SpotifyId = httpResponse . Resource . Id ;
artist . Genres = httpResponse . Resource . Genres ;
//Artist artist = MapArtists(httpResponse.Resource)[0];
artist = MapAlbums ( artist ) ;
// TODO: implement tracks api call
return new Tuple < Artist , List < Track > > ( artist , new List < Track > ( ) ) ;
}
private Artist MapAlbums ( Artist artist )
{
// Find all albums for the artist and all tracks for said album
///v1/artists/{id}/albums
var httpRequest = _requestBuilder . Create ( )
. SetSegment ( "route" , "artists/" + artist . SpotifyId + "/albums" )
. Build ( ) ;
httpRequest . AllowAutoRedirect = true ;
httpRequest . SuppressHttpError = true ;
var httpResponse = _httpClient . Get < AlbumResultResource > ( httpRequest ) ;
if ( httpResponse . HasHttpError )
{
throw new HttpException ( httpRequest , httpResponse ) ;
}
List < Album > albums = new List < Album > ( ) ;
foreach ( var albumResource in httpResponse . Resource . Items )
{
newArtists . Add ( AddOverview ( artist ) ) ;
count + + ;
Album album = new Album ( ) ;
album . AlbumId = albumResource . Id ;
album . Title = albumResource . Name ;
album . ArtworkUrl = albumResource . Images [ 0 ] . Url ;
albums . Add ( album ) ;
}
// I don't know how we are getting tracks from iTunes yet.
return new Tuple < Artist , List < Track > > ( newArtists [ 0 ] , new List < Track > ( ) ) ;
// TODO: We now need to get all tracks for each album
artist . Albums = albums ;
return artist ;
}
public List < Artist > SearchForNewArtist ( string title )
@ -227,16 +169,14 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
{
var slug = lowerTitle . Split ( ':' ) [ 1 ] . Trim ( ) ;
int itunesId ;
if ( slug . IsNullOrWhiteSpace ( ) | | slug . Any ( char . IsWhiteSpace ) | | ! int . TryParse ( slug , out itunesId ) | | itunesId < = 0 )
if ( slug . IsNullOrWhiteSpace ( ) | | slug . Any ( char . IsWhiteSpace ) )
{
return new List < Artist > ( ) ;
}
try
{
return new List < Artist > { GetArtistInfo ( itunesId ) . Item1 } ;
return new List < Artist > { GetArtistInfo ( slug ) . Item1 } ;
}
catch ( ArtistNotFoundException )
{
@ -246,8 +186,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
var httpRequest = _requestBuilder . Create ( )
. SetSegment ( "route" , "search" )
. AddQueryParam ( " enti ty", " album")
. AddQueryParam ( " term ", title . ToLower ( ) . Trim ( ) )
. AddQueryParam ( " type ", " artist, album")
. AddQueryParam ( " q ", title . ToLower ( ) . Trim ( ) )
. Build ( ) ;
@ -256,16 +196,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
List < Artist > artists = MapArtists ( httpResponse . Resource ) ;
List < Artist > newArtists = new List < Artist > ( artists . Count ) ;
int count = 0 ;
foreach ( var artist in artists )
{
newArtists . Add ( AddOverview ( artist ) ) ;
count + + ;
}
return newA rtists;
return artists ;
}
catch ( HttpException )
{
@ -278,77 +210,52 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
}
}
private Artist AddOverview ( Artist artist )
{
var httpRequest = _internalRequestBuilder . Create ( )
. SetSegment ( "route" , "viewArtist" )
. AddQueryParam ( "id" , artist . ItunesId . ToString ( ) )
. Build ( ) ;
httpRequest . Headers . Add ( "X-Apple-Store-Front" , "143459-2,32 t:music3" ) ;
httpRequest . Headers . ContentType = "application/json" ;
var httpResponse = _httpClient . Get < ArtistResource > ( httpRequest ) ;
if ( ! httpResponse . HasHttpError )
{
artist . Overview = httpResponse . Resource . StorePlatformData . Artist . Results [ artist . ItunesId ] . artistBio ;
}
return artist ;
}
private Artist MapArtistInfo ( ArtistInfoResource resource )
{
// This expects ArtistInfoResource, thus just need to populate one artist
Artist artist = new Artist ( ) ;
artist . Overview = resource . artistBio ;
artist . ArtistName = resource . name ;
foreach ( var genre in resource . genreNames )
{
artist . Genres . Add ( genre ) ;
}
//artist.Overview = resource.artistBio;
//artist.ArtistName = resource.name;
//foreach(var genre in resource.genreNames)
//{
// artist.Genres.Add(genre);
//}
return artist ;
}
private List < Artist > MapArtists ( ArtistResource resource )
{
Album tempAlbum ;
List < Artist > artists = new List < Artist > ( ) ;
foreach ( var album in resource . Result s)
foreach ( var artistResource in resource . Artists . Item s)
{
int index = artists . FindIndex ( a = > a . ItunesId = = album . ArtistId ) ;
tempAlbum = MapAlbum ( album ) ;
Artist artist = new Artist ( ) ;
artist . ArtistName = artistResource . Name ;
artist . SpotifyId = artistResource . Id ;
artist . Genres = artistResource . Genres ;
//artist.ArtistSlug = a//TODO implement artistSlug mapping;
artists . Add ( artist ) ;
}
if ( index > = 0 )
{
artists [ index ] . Albums . Add ( tempAlbum ) ;
}
else
{
Artist tempArtist = new Artist ( ) ;
tempArtist . ItunesId = album . ArtistId ;
tempArtist . ArtistName = album . ArtistName ;
tempArtist . Genres . Add ( album . PrimaryGenreName ) ;
tempArtist . Albums . Add ( tempAlbum ) ;
artists . Add ( tempArtist ) ;
}
// Maybe? Get all the albums for said artist
}
return artists ;
}
private Album MapAlbum ( AlbumResource albumQuery )
{
Album album = new Album ( ) ;
album . AlbumId = albumQuery . CollectionId ;
album . Title = albumQuery . CollectionName ;
album . Year = albumQuery . ReleaseDate . Year ;
album . ArtworkUrl = albumQuery . ArtworkUrl100 ;
album . Explicitness = albumQuery . CollectionExplicitness ;
return album ;
}
//private Album MapAlbum(AlbumResource albumQuery)
//{
// Album album = new Album();
// album.AlbumId = albumQuery.CollectionId;
// album.Title = albumQuery.CollectionName;
// album.Year = albumQuery.ReleaseDate.Year;
// album.ArtworkUrl = albumQuery.ArtworkUrl100;
// album.Explicitness = albumQuery.CollectionExplicitness;
// return album;
// }
private static Series MapSeries ( ShowResource show )
{