1- using NLog ;
2- using NzbDrone . Common . Http ;
1+ using NLog ;
32using NzbDrone . Common . Instrumentation ;
43using NzbDrone . Core . ImportLists ;
54using NzbDrone . Core . ImportLists . Exceptions ;
@@ -11,146 +10,58 @@ namespace Tubifarry.ImportLists.ListenBrainz.ListenBrainzCFRecommendations
1110{
1211 public class ListenBrainzCFRecommendationsParser : IParseImportListResponse
1312 {
14- private readonly ListenBrainzCFRecommendationsSettings _settings ;
15- private readonly IHttpClient _httpClient ;
1613 private readonly Logger _logger ;
1714
18- public ListenBrainzCFRecommendationsParser ( ListenBrainzCFRecommendationsSettings settings , IHttpClient httpClient )
15+ public ListenBrainzCFRecommendationsParser ( )
1916 {
20- _settings = settings ;
21- _httpClient = httpClient ;
2217 _logger = NzbDroneLogger . GetLogger ( this ) ;
2318 }
2419
2520 public IList < ImportListItemInfo > ParseResponse ( ImportListResponse importListResponse )
2621 {
27- List < ImportListItemInfo > items = new ( ) ;
28-
2922 if ( ! PreProcess ( importListResponse ) )
30- return items ;
23+ return new List < ImportListItemInfo > ( ) ;
3124
3225 try
3326 {
34- items . AddRange ( ParseRecordingRecommendations ( importListResponse . Content ) ) ;
27+ IList < ImportListItemInfo > items = ParseRecordingRecommendations ( importListResponse . Content ) ;
28+ _logger . Trace ( "Successfully parsed {0} recording recommendations" , items . Count ) ;
29+ return items ;
3530 }
3631 catch ( Exception ex )
3732 {
38- _logger . Error ( ex , "Error parsing ListenBrainz recording recommendations response " ) ;
39- throw new ImportListException ( importListResponse , "Error parsing response" , ex ) ;
33+ _logger . Error ( ex , "Failed to parse ListenBrainz recording recommendations" ) ;
34+ throw new ImportListException ( importListResponse , "Failed to parse response" , ex ) ;
4035 }
41-
42- _logger . Debug ( $ "Parsed { items . Count } items from ListenBrainz recording recommendations") ;
43- return items ;
4436 }
4537
4638 private IList < ImportListItemInfo > ParseRecordingRecommendations ( string content )
4739 {
48- List < ImportListItemInfo > items = new ( ) ;
4940 RecordingRecommendationResponse ? response = JsonSerializer . Deserialize < RecordingRecommendationResponse > ( content , GetJsonOptions ( ) ) ;
41+ IReadOnlyList < RecordingRecommendation > ? recommendations = response ? . Payload ? . Mbids ;
5042
51- if ( response ? . Payload ? . Mbids == null )
43+ if ( recommendations ? . Any ( ) != true )
5244 {
53- _logger . Debug ( "No recording recommendations found " ) ;
54- return items ;
45+ _logger . Debug ( "No recording recommendations available " ) ;
46+ return new List < ImportListItemInfo > ( ) ;
5547 }
5648
57- _logger . Debug ( $ "Found { response . Payload . Mbids . Count } recording recommendations") ;
49+ _logger . Trace ( "Processing {0 } recording recommendations", recommendations . Count ) ;
5850
59- // Group recordings by their MBIDs to batch the MusicBrainz lookup
60- List < string > recordingMbids = response . Payload . Mbids . Select ( r => r . RecordingMbid ) . ToList ( ) ;
61-
62- // We need to look up the artist information for each recording via MusicBrainz API
63- // Since we can't use the MusicBrainz API directly here, we'll use ListenBrainz's lookup
64- HashSet < string > artistMbids = new ( ) ;
65-
66- foreach ( RecordingRecommendation recommendation in response . Payload . Mbids )
67- {
68- try
51+ return recommendations
52+ . Where ( r => ! string . IsNullOrWhiteSpace ( r . RecordingMbid ) )
53+ . Select ( r => new ImportListItemInfo
6954 {
70- List < string > artistInfo = LookupRecordingArtist ( recommendation . RecordingMbid ) ;
71- if ( artistInfo != null )
72- {
73- foreach ( string artistId in artistInfo )
74- {
75- artistMbids . Add ( artistId ) ;
76- }
77- }
78- }
79- catch ( Exception ex )
80- {
81- _logger . Debug ( ex , $ "Error looking up artist for recording { recommendation . RecordingMbid } ") ;
82- }
83- }
84-
85- // Convert artist MBIDs to ImportListItemInfo
86- foreach ( string artistMbid in artistMbids )
87- {
88- items . Add ( new ImportListItemInfo
89- {
90- ArtistMusicBrainzId = artistMbid
91- } ) ;
92- }
93-
94- return items ;
55+ AlbumMusicBrainzId = r . RecordingMbid ,
56+ Album = r . RecordingMbid
57+ } )
58+ . ToList ( ) ;
9559 }
9660
97- private List < string > LookupRecordingArtist ( string recordingMbid )
61+ private static JsonSerializerOptions GetJsonOptions ( ) => new ( )
9862 {
99- List < string > artistMbids = new ( ) ;
100-
101- try
102- {
103- // Use MusicBrainz API to look up recording details
104- HttpRequestBuilder request = new HttpRequestBuilder ( "https://musicbrainz.org" )
105- . AddQueryParam ( "fmt" , "json" )
106- . AddQueryParam ( "inc" , "artist-credits" )
107- . Accept ( HttpAccept . Json ) ;
108-
109- HttpRequest httpRequest = request . Build ( ) ;
110- httpRequest . Url = new HttpUri ( $ "https://musicbrainz.org/ws/2/recording/{ recordingMbid } ?fmt=json&inc=artist-credits") ;
111-
112- // Add User-Agent as required by MusicBrainz
113- httpRequest . Headers . Add ( "User-Agent" , "Lidarr-ListenBrainz-Plugin/1.0 (https://github.com/Lidarr/Lidarr)" ) ;
114-
115- // Rate limit for MusicBrainz (1 request per second)
116- Thread . Sleep ( 1000 ) ;
117-
118- HttpResponse response = _httpClient . Execute ( httpRequest ) ;
119-
120- if ( response . StatusCode != HttpStatusCode . OK )
121- {
122- _logger . Debug ( $ "Failed to lookup recording { recordingMbid } : HTTP { response . StatusCode } ") ;
123- return artistMbids ;
124- }
125-
126- MusicBrainzRecordingResponse ? recordingData = JsonSerializer . Deserialize < MusicBrainzRecordingResponse > ( response . Content , GetJsonOptions ( ) ) ;
127-
128- if ( recordingData ? . ArtistCredits != null )
129- {
130- foreach ( MusicBrainzArtistCredit credit in recordingData . ArtistCredits )
131- {
132- if ( ! string . IsNullOrEmpty ( credit . Artist ? . Id ) )
133- {
134- artistMbids . Add ( credit . Artist . Id ) ;
135- }
136- }
137- }
138- }
139- catch ( Exception ex )
140- {
141- _logger . Debug ( ex , $ "Error looking up recording { recordingMbid } in MusicBrainz") ;
142- }
143-
144- return artistMbids ;
145- }
146-
147- private JsonSerializerOptions GetJsonOptions ( )
148- {
149- return new JsonSerializerOptions
150- {
151- PropertyNameCaseInsensitive = true
152- } ;
153- }
63+ PropertyNameCaseInsensitive = true
64+ } ;
15465
15566 private bool PreProcess ( ImportListResponse importListResponse )
15667 {
@@ -162,10 +73,10 @@ private bool PreProcess(ImportListResponse importListResponse)
16273
16374 if ( importListResponse . HttpResponse . StatusCode != HttpStatusCode . OK )
16475 {
165- throw new ImportListException ( importListResponse , "Unexpected StatusCode [ {0}] " , importListResponse . HttpResponse . StatusCode ) ;
76+ throw new ImportListException ( importListResponse , "Unexpected status code {0}" , importListResponse . HttpResponse . StatusCode ) ;
16677 }
16778
16879 return true ;
16980 }
17081 }
171- }
82+ }
0 commit comments