@ -8,6 +8,7 @@ using ErsatzTV.Core.Domain;
@@ -8,6 +8,7 @@ using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Locking ;
using ErsatzTV.Core.Interfaces.Plex ;
using ErsatzTV.Core.Interfaces.Repositories ;
using ErsatzTV.Core.Plex ;
using LanguageExt ;
using MediatR ;
using Microsoft.Extensions.Logging ;
@ -23,16 +24,22 @@ namespace ErsatzTV.Application.Plex.Commands
@@ -23,16 +24,22 @@ namespace ErsatzTV.Application.Plex.Commands
private readonly ILogger < SynchronizePlexMediaSourcesHandler > _l ogger ;
private readonly IMediaSourceRepository _ mediaSourceRepository ;
private readonly IPlexTvApiClient _ plexTvApiClient ;
private readonly IPlexServerApiClient _ plexServerApiClient ;
private readonly IPlexSecretStore _ plexSecretStore ;
public SynchronizePlexMediaSourcesHandler (
IMediaSourceRepository mediaSourceRepository ,
IPlexTvApiClient plexTvApiClient ,
IPlexServerApiClient plexServerApiClient ,
IPlexSecretStore plexSecretStore ,
ChannelWriter < IPlexBackgroundServiceRequest > channel ,
IEntityLocker entityLocker ,
ILogger < SynchronizePlexMediaSourcesHandler > logger )
{
_ mediaSourceRepository = mediaSourceRepository ;
_ plexTvApiClient = plexTvApiClient ;
_ plexServerApiClient = plexServerApiClient ;
_ plexSecretStore = plexSecretStore ;
_ channel = channel ;
_ entityLocker = entityLocker ;
_l ogger = logger ;
@ -69,32 +76,76 @@ namespace ErsatzTV.Application.Plex.Commands
@@ -69,32 +76,76 @@ namespace ErsatzTV.Application.Plex.Commands
return allExisting ;
}
private Task SynchronizeServer ( List < PlexMediaSource > allExisting , PlexMediaSource server )
private async Task SynchronizeServer ( List < PlexMediaSource > allExisting , PlexMediaSource server )
{
Option < PlexMediaSource > maybeExisting =
allExisting . Find ( s = > s . ClientIdentifier = = server . ClientIdentifier ) ;
return maybeExisting . Match (
existing = >
{
existing . Platform = server . Platform ;
existing . PlatformVersion = server . PlatformVersion ;
existing . ProductVersion = server . ProductVersion ;
existing . ServerName = server . ServerName ;
var toAdd = server . Connections
. Filter ( connection = > existing . Connections . All ( c = > c . Uri ! = connection . Uri ) ) . ToList ( ) ;
var toRemove = existing . Connections
. Filter ( connection = > server . Connections . All ( c = > c . Uri ! = connection . Uri ) ) . ToList ( ) ;
return _ mediaSourceRepository . Update ( existing , server . Connections , toAdd , toRemove ) ;
} ,
async ( ) = >
foreach ( PlexMediaSource existing in maybeExisting )
{
existing . Platform = server . Platform ;
existing . PlatformVersion = server . PlatformVersion ;
existing . ProductVersion = server . ProductVersion ;
existing . ServerName = server . ServerName ;
var toAdd = server . Connections
. Filter ( connection = > existing . Connections . All ( c = > c . Uri ! = connection . Uri ) ) . ToList ( ) ;
var toRemove = existing . Connections
. Filter ( connection = > server . Connections . All ( c = > c . Uri ! = connection . Uri ) ) . ToList ( ) ;
await _ mediaSourceRepository . Update ( existing , toAdd , toRemove ) ;
await FindConnectionToActivate ( existing ) ;
}
if ( maybeExisting . IsNone )
{
await _ mediaSourceRepository . Add ( server ) ;
await FindConnectionToActivate ( server ) ;
}
}
private async Task FindConnectionToActivate ( PlexMediaSource server )
{
var prioritized = server . Connections . OrderBy ( pc = > pc . IsActive ? 0 : 1 ) . ToList ( ) ;
foreach ( PlexConnection connection in server . Connections )
{
connection . IsActive = false ;
}
Option < PlexServerAuthToken > maybeToken = await _ plexSecretStore . GetServerAuthToken ( server . ClientIdentifier ) ;
foreach ( PlexServerAuthToken token in maybeToken )
{
foreach ( PlexConnection connection in prioritized )
{
if ( server . Connections . Any ( ) )
try
{
_l ogger . LogDebug ( "Attempting to locate to Plex at {Uri}" , connection . Uri ) ;
if ( await _ plexServerApiClient . Ping ( connection , token ) )
{
_l ogger . LogInformation ( "Located Plex at {Uri}" , connection . Uri ) ;
connection . IsActive = true ;
break ;
}
}
catch
{
server . Connections . Head ( ) . IsActive = true ;
// do nothing
}
}
}
if ( maybeToken . IsNone )
{
_l ogger . LogError (
"Unable to activate Plex connection for server {Server} without auth token" ,
server . ServerName ) ;
}
if ( server . Connections . All ( c = > ! c . IsActive ) )
{
_l ogger . LogError ( "Unable to locate Plex" ) ;
server . Connections . Head ( ) . IsActive = true ;
}
await _ mediaSourceRepository . Add ( server ) ;
} ) ;
await _ mediaSourceRepository . Update ( server , new List < PlexConnection > ( ) , new List < PlexConnection > ( ) ) ;
}
}
}