84 lines
3.7 KiB
C#
84 lines
3.7 KiB
C#
using ErsatzTV.Core;
|
|
using ErsatzTV.Core.Domain;
|
|
using ErsatzTV.Core.Interfaces.Plex;
|
|
using ErsatzTV.Core.Interfaces.Repositories;
|
|
using ErsatzTV.Core.Plex;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace ErsatzTV.Application.Plex;
|
|
|
|
public class GetPlexConnectionParametersHandler : PlexBaseConnectionHandler, IRequestHandler<GetPlexConnectionParameters,
|
|
Either<BaseError, PlexConnectionParametersViewModel>>
|
|
{
|
|
private readonly IMediaSourceRepository _mediaSourceRepository;
|
|
private readonly IMemoryCache _memoryCache;
|
|
private readonly IPlexServerApiClient _plexServerApiClient;
|
|
private readonly IPlexSecretStore _plexSecretStore;
|
|
private readonly ILogger<GetPlexConnectionParametersHandler> _logger;
|
|
|
|
public GetPlexConnectionParametersHandler(
|
|
IMemoryCache memoryCache,
|
|
IPlexServerApiClient plexServerApiClient,
|
|
IMediaSourceRepository mediaSourceRepository,
|
|
IPlexSecretStore plexSecretStore,
|
|
ILogger<GetPlexConnectionParametersHandler> logger)
|
|
: base(plexServerApiClient, mediaSourceRepository, logger)
|
|
{
|
|
_memoryCache = memoryCache;
|
|
_plexServerApiClient = plexServerApiClient;
|
|
_mediaSourceRepository = mediaSourceRepository;
|
|
_plexSecretStore = plexSecretStore;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task<Either<BaseError, PlexConnectionParametersViewModel>> Handle(
|
|
GetPlexConnectionParameters request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
if (_memoryCache.TryGetValue(request, out PlexConnectionParametersViewModel parameters))
|
|
{
|
|
return parameters;
|
|
}
|
|
|
|
Option<PlexMediaSource> maybeMediaSource = await _mediaSourceRepository.GetPlex(request.PlexMediaSourceId);
|
|
foreach (PlexMediaSource mediaSource in maybeMediaSource)
|
|
{
|
|
Option<PlexServerAuthToken> maybeToken =
|
|
await _plexSecretStore.GetServerAuthToken(mediaSource.ClientIdentifier);
|
|
foreach (PlexServerAuthToken token in maybeToken)
|
|
{
|
|
// try to keep the same connection
|
|
Option<PlexConnection> maybeActiveConnection = mediaSource.Connections.Filter(c => c.IsActive).HeadOrNone();
|
|
foreach (PlexConnection activeConnection in maybeActiveConnection)
|
|
{
|
|
if (await _plexServerApiClient.Ping(activeConnection, token, cancellationToken))
|
|
{
|
|
_logger.LogDebug("Plex connection is still active at {Uri}", activeConnection.Uri);
|
|
var p = new PlexConnectionParametersViewModel(new Uri(activeConnection.Uri), token.AuthToken);
|
|
_memoryCache.Set(request, p, TimeSpan.FromSeconds(30));
|
|
return p;
|
|
}
|
|
}
|
|
|
|
_logger.LogInformation("Plex connection is no longer active, searching for a new connection");
|
|
|
|
// check all connections for a working one
|
|
Option<PlexConnection> maybeConnection = await FindConnectionToActivate(mediaSource, token);
|
|
foreach (PlexConnection connection in maybeConnection)
|
|
{
|
|
var p = new PlexConnectionParametersViewModel(new Uri(connection.Uri), token.AuthToken);
|
|
_memoryCache.Set(request, p, TimeSpan.FromMinutes(30));
|
|
return p;
|
|
}
|
|
|
|
return BaseError.New($"Plex media source {request.PlexMediaSourceId} requires an active connection");
|
|
}
|
|
|
|
return BaseError.New($"Plex media source {request.PlexMediaSourceId} requires a token");
|
|
}
|
|
|
|
return BaseError.New($"Plex media source {request.PlexMediaSourceId} does not exist.");
|
|
}
|
|
}
|