Skip to content

Commit 2eb438d

Browse files
author
Meyn
committed
Improve Last.fm Recommendations
1 parent 0db07c5 commit 2eb438d

File tree

8 files changed

+349
-199
lines changed

8 files changed

+349
-199
lines changed

Tubifarry/ImportLists/LastFMRecomendation/LastFMRecommend.cs

Lines changed: 0 additions & 26 deletions
This file was deleted.

Tubifarry/ImportLists/LastFMRecomendation/LastFMRecommendParser.cs

Lines changed: 0 additions & 169 deletions
This file was deleted.

Tubifarry/ImportLists/LastFMRecomendation/LastFmModels.cs renamed to Tubifarry/ImportLists/LastFmRecommendation/LastFmModels.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using NzbDrone.Core.ImportLists.LastFm;
22

3-
namespace Tubifarry.ImportLists.LastFmRecomendation
3+
namespace Tubifarry.ImportLists.LastFmRecommendation
44
{
55
public class LastFmTopResponse
66
{

Tubifarry/ImportLists/LastFmRecomendation/LastFmRecomendRequestGenerator.cs renamed to Tubifarry/ImportLists/LastFmRecommendation/LastFmRecomendRequestGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using NzbDrone.Core.ImportLists;
33
using NzbDrone.Core.ImportLists.LastFm;
44

5-
namespace Tubifarry.ImportLists.LastFmRecomendation
5+
namespace Tubifarry.ImportLists.LastFmRecommendation
66
{
77
public class LastFmRecomendRequestGenerator : IImportListRequestGenerator
88
{
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using FluentValidation.Results;
2+
using NLog;
3+
using NzbDrone.Common.Extensions;
4+
using NzbDrone.Common.Http;
5+
using NzbDrone.Core.Configuration;
6+
using NzbDrone.Core.ImportLists;
7+
using NzbDrone.Core.ImportLists.Exceptions;
8+
using NzbDrone.Core.Indexers.Exceptions;
9+
using NzbDrone.Core.Parser;
10+
using System.Net;
11+
12+
namespace Tubifarry.ImportLists.LastFmRecommendation
13+
{
14+
internal class LastFmRecommend : HttpImportListBase<LastFmRecommendSettings>
15+
{
16+
private readonly IHttpClient _client;
17+
public override string Name => "Last.fm Recommend";
18+
public override TimeSpan MinRefreshInterval => TimeSpan.FromDays(7);
19+
public override ImportListType ListType => ImportListType.LastFm;
20+
21+
public override int PageSize => 100;
22+
public override TimeSpan RateLimit => TimeSpan.FromSeconds(5);
23+
24+
public LastFmRecommend(IHttpClient httpClient, IImportListStatusService importListStatusService, IConfigService configService, IParsingService parsingService, Logger logger) : base(httpClient, importListStatusService, configService, parsingService, logger) => _client = httpClient;
25+
26+
public override IImportListRequestGenerator GetRequestGenerator() => new LastFmRecomendRequestGenerator(Settings);
27+
28+
public override IParseImportListResponse GetParser() => new LastFmRecommendParser(Settings, _client);
29+
30+
protected override void Test(List<ValidationFailure> failures)
31+
{
32+
failures.AddIfNotNull(TestConnection());
33+
}
34+
35+
protected override ValidationFailure? TestConnection()
36+
{
37+
try
38+
{
39+
IImportListRequestGenerator generator = GetRequestGenerator();
40+
ImportListRequest listItems = generator.GetListItems().GetAllTiers().First().First();
41+
ImportListResponse response = FetchImportListResponse(listItems);
42+
43+
// Validate HTTP status first
44+
if (response.HttpResponse.StatusCode != HttpStatusCode.OK)
45+
{
46+
return new ValidationFailure(string.Empty, "Connection failed: Server returned HTTP " +
47+
$"{(int)response.HttpResponse.StatusCode} ({response.HttpResponse.StatusCode})");
48+
}
49+
50+
// Enhanced content type validation
51+
string? contentType = response.HttpResponse.Headers.ContentType;
52+
if (contentType == null ||
53+
!IsJsonContentType(contentType))
54+
{
55+
string receivedType = contentType ?? "null/no-content-type";
56+
return new ValidationFailure(string.Empty, $"Unexpected content type: {receivedType}. " + "Server must return JSON (application/json or similar)");
57+
}
58+
return null;
59+
}
60+
catch (RequestLimitReachedException)
61+
{
62+
_logger.Warn("API request limit reached");
63+
return new ValidationFailure(string.Empty, "API rate limit exceeded - try again later");
64+
}
65+
catch (UnsupportedFeedException ex)
66+
{
67+
_logger.Warn(ex, "Feed format not supported");
68+
return new ValidationFailure(string.Empty, $"Unsupported feed format: {ex.Message}");
69+
}
70+
catch (ImportListException ex)
71+
{
72+
_logger.Warn(ex, "Connection failed");
73+
return new ValidationFailure(string.Empty, $"Connection error: {ex.Message}");
74+
}
75+
catch (Exception ex)
76+
{
77+
_logger.Error(ex, "Critical connection failure");
78+
return new ValidationFailure(string.Empty, "Configuration error - check logs for details");
79+
}
80+
}
81+
82+
private static bool IsJsonContentType(string mediaType) => mediaType.Equals("application/json", StringComparison.OrdinalIgnoreCase) ||
83+
mediaType.Equals("text/json", StringComparison.OrdinalIgnoreCase) ||
84+
mediaType.EndsWith("+json", StringComparison.OrdinalIgnoreCase);
85+
86+
}
87+
}

0 commit comments

Comments
 (0)