2024-04-14 16:43:09 +02:00
|
|
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
|
using Newtonsoft.Json;
|
2024-02-12 01:57:41 +01:00
|
|
|
|
using UmlautAdaptarr.Models;
|
2024-04-27 18:48:43 +02:00
|
|
|
|
using UmlautAdaptarr.Options.ArrOptions.InstanceOptions;
|
2024-02-12 01:57:41 +01:00
|
|
|
|
using UmlautAdaptarr.Services;
|
|
|
|
|
|
using UmlautAdaptarr.Utilities;
|
|
|
|
|
|
|
2024-04-27 18:48:43 +02:00
|
|
|
|
namespace UmlautAdaptarr.Providers;
|
|
|
|
|
|
|
|
|
|
|
|
public class SonarrClient : ArrClientBase
|
2024-02-12 01:57:41 +01:00
|
|
|
|
{
|
2024-04-27 18:48:43 +02:00
|
|
|
|
private readonly IHttpClientFactory _clientFactory;
|
|
|
|
|
|
private readonly ILogger<SonarrClient> _logger;
|
|
|
|
|
|
|
|
|
|
|
|
private readonly string _mediaType = "tv";
|
|
|
|
|
|
private readonly TitleApiService _titleService;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public SonarrClient([ServiceKey] string instanceName,
|
2024-02-12 01:57:41 +01:00
|
|
|
|
IHttpClientFactory clientFactory,
|
|
|
|
|
|
TitleApiService titleService,
|
2024-04-27 18:48:43 +02:00
|
|
|
|
IOptionsMonitor<SonarrInstanceOptions> options,
|
|
|
|
|
|
ILogger<SonarrClient> logger)
|
2024-02-12 01:57:41 +01:00
|
|
|
|
{
|
2024-04-27 18:48:43 +02:00
|
|
|
|
_clientFactory = clientFactory;
|
|
|
|
|
|
_titleService = titleService;
|
|
|
|
|
|
_logger = logger;
|
2024-02-12 01:57:41 +01:00
|
|
|
|
|
2024-04-27 18:48:43 +02:00
|
|
|
|
InstanceName = instanceName;
|
|
|
|
|
|
Options = options.Get(InstanceName);
|
|
|
|
|
|
_logger.LogInformation($"Init SonarrClient ({InstanceName})");
|
|
|
|
|
|
}
|
2024-02-12 01:57:41 +01:00
|
|
|
|
|
2024-04-27 18:48:43 +02:00
|
|
|
|
public SonarrInstanceOptions Options { get; init; }
|
2024-02-12 01:57:41 +01:00
|
|
|
|
|
2024-04-27 18:48:43 +02:00
|
|
|
|
public override async Task<IEnumerable<SearchItem>> FetchAllItemsAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
var httpClient = _clientFactory.CreateClient();
|
|
|
|
|
|
var items = new List<SearchItem>();
|
2024-02-12 01:57:41 +01:00
|
|
|
|
|
2024-04-27 18:48:43 +02:00
|
|
|
|
try
|
2024-02-12 01:57:41 +01:00
|
|
|
|
{
|
2024-04-27 18:48:43 +02:00
|
|
|
|
var sonarrUrl = $"{Options.Host}/api/v3/series?includeSeasonImages=false&apikey={Options.ApiKey}";
|
|
|
|
|
|
_logger.LogInformation($"Fetching all items from Sonarr: {UrlUtilities.RedactApiKey(sonarrUrl)}");
|
|
|
|
|
|
var response = await httpClient.GetStringAsync(sonarrUrl);
|
|
|
|
|
|
var shows = JsonConvert.DeserializeObject<List<dynamic>>(response);
|
2024-02-12 01:57:41 +01:00
|
|
|
|
|
2024-04-27 18:48:43 +02:00
|
|
|
|
if (shows != null)
|
2024-02-12 01:57:41 +01:00
|
|
|
|
{
|
2024-04-27 18:48:43 +02:00
|
|
|
|
_logger.LogInformation($"Successfully fetched {shows.Count} items from Sonarr ({InstanceName}).");
|
|
|
|
|
|
foreach (var show in shows)
|
2024-02-12 01:57:41 +01:00
|
|
|
|
{
|
|
|
|
|
|
var tvdbId = (string)show.tvdbId;
|
|
|
|
|
|
if (tvdbId == null)
|
|
|
|
|
|
{
|
2024-04-27 18:48:43 +02:00
|
|
|
|
_logger.LogWarning($"Sonarr ({InstanceName}) Show {show.id} doesn't have a tvdbId.");
|
|
|
|
|
|
continue;
|
2024-02-12 01:57:41 +01:00
|
|
|
|
}
|
2024-04-27 18:48:43 +02:00
|
|
|
|
|
|
|
|
|
|
var (germanTitle, aliases) =
|
|
|
|
|
|
await _titleService.FetchGermanTitleAndAliasesByExternalIdAsync(_mediaType, tvdbId);
|
2024-02-12 01:57:41 +01:00
|
|
|
|
var searchItem = new SearchItem
|
|
|
|
|
|
(
|
2024-04-27 18:48:43 +02:00
|
|
|
|
(int)show.id,
|
|
|
|
|
|
tvdbId,
|
|
|
|
|
|
(string)show.title,
|
|
|
|
|
|
(string)show.title,
|
|
|
|
|
|
germanTitle,
|
2024-02-12 01:57:41 +01:00
|
|
|
|
aliases: aliases,
|
|
|
|
|
|
mediaType: _mediaType
|
|
|
|
|
|
);
|
|
|
|
|
|
|
2024-04-27 18:48:43 +02:00
|
|
|
|
items.Add(searchItem);
|
2024-02-12 01:57:41 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-27 18:48:43 +02:00
|
|
|
|
_logger.LogInformation($"Finished fetching all items from Sonarr ({InstanceName})");
|
2024-02-12 01:57:41 +01:00
|
|
|
|
}
|
2024-04-27 18:48:43 +02:00
|
|
|
|
catch (Exception ex)
|
2024-02-12 01:57:41 +01:00
|
|
|
|
{
|
2024-04-27 18:48:43 +02:00
|
|
|
|
_logger.LogError($"Error fetching all shows from Sonarr ({InstanceName}) : {ex.Message}");
|
|
|
|
|
|
}
|
2024-02-12 01:57:41 +01:00
|
|
|
|
|
2024-04-27 18:48:43 +02:00
|
|
|
|
return items;
|
|
|
|
|
|
}
|
2024-02-12 01:57:41 +01:00
|
|
|
|
|
2024-04-27 18:48:43 +02:00
|
|
|
|
public override async Task<SearchItem?> FetchItemByExternalIdAsync(string externalId)
|
|
|
|
|
|
{
|
|
|
|
|
|
var httpClient = _clientFactory.CreateClient();
|
2024-02-12 01:57:41 +01:00
|
|
|
|
|
2024-04-27 18:48:43 +02:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var sonarrUrl =
|
|
|
|
|
|
$"{Options.Host}/api/v3/series?tvdbId={externalId}&includeSeasonImages=false&apikey={Options.ApiKey}";
|
|
|
|
|
|
_logger.LogInformation(
|
|
|
|
|
|
$"Fetching item by external ID from Sonarr ({InstanceName}): {UrlUtilities.RedactApiKey(sonarrUrl)}");
|
|
|
|
|
|
var response = await httpClient.GetStringAsync(sonarrUrl);
|
|
|
|
|
|
var shows = JsonConvert.DeserializeObject<dynamic>(response);
|
|
|
|
|
|
var show = shows?[0];
|
|
|
|
|
|
|
|
|
|
|
|
if (show != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var tvdbId = (string)show.tvdbId;
|
|
|
|
|
|
if (tvdbId == null)
|
2024-02-12 01:57:41 +01:00
|
|
|
|
{
|
2024-04-27 18:48:43 +02:00
|
|
|
|
_logger.LogWarning($"Sonarr ({InstanceName}) Show {show.id} doesn't have a tvdbId.");
|
2024-02-12 01:57:41 +01:00
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-27 18:48:43 +02:00
|
|
|
|
var (germanTitle, aliases) =
|
|
|
|
|
|
await _titleService.FetchGermanTitleAndAliasesByExternalIdAsync(_mediaType, tvdbId);
|
2024-02-12 01:57:41 +01:00
|
|
|
|
|
|
|
|
|
|
var searchItem = new SearchItem
|
|
|
|
|
|
(
|
2024-04-27 18:48:43 +02:00
|
|
|
|
(int)show.id,
|
|
|
|
|
|
tvdbId,
|
|
|
|
|
|
(string)show.title,
|
|
|
|
|
|
(string)show.title,
|
|
|
|
|
|
germanTitle,
|
2024-02-12 01:57:41 +01:00
|
|
|
|
aliases: aliases,
|
|
|
|
|
|
mediaType: _mediaType
|
|
|
|
|
|
);
|
|
|
|
|
|
|
2024-04-27 18:48:43 +02:00
|
|
|
|
_logger.LogInformation($"Successfully fetched show {searchItem.Title} from Sonarr ({InstanceName}).");
|
2024-02-12 01:57:41 +01:00
|
|
|
|
return searchItem;
|
|
|
|
|
|
}
|
2024-04-27 18:48:43 +02:00
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError($"Error fetching single show from Sonarr ({InstanceName}): {ex.Message}");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override async Task<SearchItem?> FetchItemByTitleAsync(string title)
|
|
|
|
|
|
{
|
|
|
|
|
|
var httpClient = _clientFactory.CreateClient();
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var (germanTitle, tvdbId, aliases) =
|
|
|
|
|
|
await _titleService.FetchGermanTitleAndExternalIdAndAliasesByTitle(_mediaType, title);
|
|
|
|
|
|
|
|
|
|
|
|
if (tvdbId == null) return null;
|
|
|
|
|
|
|
|
|
|
|
|
var sonarrUrl =
|
|
|
|
|
|
$"{Options.Host}/api/v3/series?tvdbId={tvdbId}&includeSeasonImages=false&apikey={Options.ApiKey}";
|
|
|
|
|
|
var sonarrApiResponse = await httpClient.GetStringAsync(sonarrUrl);
|
|
|
|
|
|
var shows = JsonConvert.DeserializeObject<dynamic>(sonarrApiResponse);
|
|
|
|
|
|
|
|
|
|
|
|
if (shows == null)
|
2024-02-12 01:57:41 +01:00
|
|
|
|
{
|
2024-04-27 18:48:43 +02:00
|
|
|
|
_logger.LogError($"Parsing Sonarr ({InstanceName}) API response for TVDB ID {tvdbId} resulted in null");
|
|
|
|
|
|
return null;
|
2024-02-12 01:57:41 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-27 18:48:43 +02:00
|
|
|
|
if (shows.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning($"No results found for TVDB ID {tvdbId}");
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var expectedTitle = (string)shows[0].title;
|
|
|
|
|
|
if (expectedTitle == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError($"Sonarr ({InstanceName}) : Title for TVDB ID {tvdbId} is null");
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var searchItem = new SearchItem
|
|
|
|
|
|
(
|
|
|
|
|
|
(int)shows[0].id,
|
|
|
|
|
|
tvdbId,
|
|
|
|
|
|
(string)shows[0].title,
|
|
|
|
|
|
(string)shows[0].title,
|
|
|
|
|
|
germanTitle,
|
|
|
|
|
|
aliases: aliases,
|
|
|
|
|
|
mediaType: _mediaType
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"Successfully fetched show {searchItem.Title} from Sonarr ({InstanceName}).");
|
|
|
|
|
|
return searchItem;
|
2024-02-12 01:57:41 +01:00
|
|
|
|
}
|
2024-04-27 18:48:43 +02:00
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError($"Error fetching single show from Sonarr ({InstanceName}) : {ex.Message}");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
2024-02-12 01:57:41 +01:00
|
|
|
|
}
|
2024-04-27 18:48:43 +02:00
|
|
|
|
}
|