mirror of https://github.com/ErsatzTV/ErsatzTV.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
3.5 KiB
87 lines
3.5 KiB
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; |
|
|
|
namespace ErsatzTV.Application.Plex; |
|
|
|
public class GetPlexConnectionParametersHandler : IRequestHandler<GetPlexConnectionParameters, |
|
Either<BaseError, PlexConnectionParametersViewModel>> |
|
{ |
|
private readonly IMediaSourceRepository _mediaSourceRepository; |
|
private readonly IMemoryCache _memoryCache; |
|
private readonly IPlexSecretStore _plexSecretStore; |
|
|
|
public GetPlexConnectionParametersHandler( |
|
IMemoryCache memoryCache, |
|
IMediaSourceRepository mediaSourceRepository, |
|
IPlexSecretStore plexSecretStore) |
|
{ |
|
_memoryCache = memoryCache; |
|
_mediaSourceRepository = mediaSourceRepository; |
|
_plexSecretStore = plexSecretStore; |
|
} |
|
|
|
public async Task<Either<BaseError, PlexConnectionParametersViewModel>> Handle( |
|
GetPlexConnectionParameters request, |
|
CancellationToken cancellationToken) |
|
{ |
|
if (_memoryCache.TryGetValue(request, out PlexConnectionParametersViewModel parameters)) |
|
{ |
|
return parameters; |
|
} |
|
|
|
Either<BaseError, PlexConnectionParametersViewModel> maybeParameters = |
|
await Validate(request) |
|
.MapT( |
|
cp => new PlexConnectionParametersViewModel( |
|
new Uri(cp.ActiveConnection.Uri), |
|
cp.PlexServerAuthToken.AuthToken)) |
|
.Map(v => v.ToEither<PlexConnectionParametersViewModel>()); |
|
|
|
return maybeParameters.Match( |
|
p => |
|
{ |
|
_memoryCache.Set(request, p, TimeSpan.FromHours(1)); |
|
return maybeParameters; |
|
}, |
|
error => error); |
|
} |
|
|
|
private Task<Validation<BaseError, ConnectionParameters>> Validate(GetPlexConnectionParameters request) => |
|
PlexMediaSourceMustExist(request) |
|
.BindT(MediaSourceMustHaveActiveConnection) |
|
.BindT(MediaSourceMustHaveToken); |
|
|
|
private Task<Validation<BaseError, PlexMediaSource>> PlexMediaSourceMustExist( |
|
GetPlexConnectionParameters request) => |
|
_mediaSourceRepository.GetPlex(request.PlexMediaSourceId) |
|
.Map( |
|
v => v.ToValidation<BaseError>( |
|
$"Plex media source {request.PlexMediaSourceId} does not exist.")); |
|
|
|
private Validation<BaseError, ConnectionParameters> MediaSourceMustHaveActiveConnection( |
|
PlexMediaSource plexMediaSource) |
|
{ |
|
Option<PlexConnection> maybeConnection = |
|
plexMediaSource.Connections.SingleOrDefault(c => c.IsActive); |
|
return maybeConnection.Map(connection => new ConnectionParameters(plexMediaSource, connection)) |
|
.ToValidation<BaseError>("Plex media source requires an active connection"); |
|
} |
|
|
|
private async Task<Validation<BaseError, ConnectionParameters>> MediaSourceMustHaveToken( |
|
ConnectionParameters connectionParameters) |
|
{ |
|
Option<PlexServerAuthToken> maybeToken = await |
|
_plexSecretStore.GetServerAuthToken(connectionParameters.PlexMediaSource.ClientIdentifier); |
|
return maybeToken.Map(token => connectionParameters with { PlexServerAuthToken = token }) |
|
.ToValidation<BaseError>("Plex media source requires a token"); |
|
} |
|
|
|
private sealed record ConnectionParameters(PlexMediaSource PlexMediaSource, PlexConnection ActiveConnection) |
|
{ |
|
public PlexServerAuthToken PlexServerAuthToken { get; set; } |
|
} |
|
}
|
|
|