fix plex server and connection sync (#153)
This commit is contained in:
@@ -10,6 +10,7 @@ using ErsatzTV.Core.Interfaces.Plex;
|
||||
using ErsatzTV.Core.Interfaces.Repositories;
|
||||
using LanguageExt;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace ErsatzTV.Application.Plex.Commands
|
||||
{
|
||||
@@ -19,6 +20,7 @@ namespace ErsatzTV.Application.Plex.Commands
|
||||
{
|
||||
private readonly ChannelWriter<IPlexBackgroundServiceRequest> _channel;
|
||||
private readonly IEntityLocker _entityLocker;
|
||||
private readonly ILogger<SynchronizePlexMediaSourcesHandler> _logger;
|
||||
private readonly IMediaSourceRepository _mediaSourceRepository;
|
||||
private readonly IPlexTvApiClient _plexTvApiClient;
|
||||
|
||||
@@ -26,12 +28,14 @@ namespace ErsatzTV.Application.Plex.Commands
|
||||
IMediaSourceRepository mediaSourceRepository,
|
||||
IPlexTvApiClient plexTvApiClient,
|
||||
ChannelWriter<IPlexBackgroundServiceRequest> channel,
|
||||
IEntityLocker entityLocker)
|
||||
IEntityLocker entityLocker,
|
||||
ILogger<SynchronizePlexMediaSourcesHandler> logger)
|
||||
{
|
||||
_mediaSourceRepository = mediaSourceRepository;
|
||||
_plexTvApiClient = plexTvApiClient;
|
||||
_channel = channel;
|
||||
_entityLocker = entityLocker;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public Task<Either<BaseError, List<PlexMediaSource>>> Handle(
|
||||
@@ -47,6 +51,14 @@ namespace ErsatzTV.Application.Plex.Commands
|
||||
await SynchronizeServer(allExisting, server);
|
||||
}
|
||||
|
||||
// delete removed servers
|
||||
foreach (PlexMediaSource removed in allExisting.Filter(
|
||||
s => servers.All(pms => pms.ClientIdentifier != s.ClientIdentifier)))
|
||||
{
|
||||
_logger.LogWarning("Deleting removed Plex server {ServerName}!", removed.Id.ToString());
|
||||
await _mediaSourceRepository.DeletePlex(removed);
|
||||
}
|
||||
|
||||
foreach (PlexMediaSource mediaSource in await _mediaSourceRepository.GetAllPlex())
|
||||
{
|
||||
await _channel.WriteAsync(new SynchronizePlexLibraries(mediaSource.Id));
|
||||
@@ -72,7 +84,7 @@ namespace ErsatzTV.Application.Plex.Commands
|
||||
.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, toAdd, toRemove);
|
||||
return _mediaSourceRepository.Update(existing, server.Connections, toAdd, toRemove);
|
||||
},
|
||||
async () =>
|
||||
{
|
||||
|
||||
@@ -20,7 +20,12 @@ namespace ErsatzTV.Core.Interfaces.Repositories
|
||||
Task<List<PlexPathReplacement>> GetPlexPathReplacementsByLibraryId(int plexLibraryPathId);
|
||||
Task<int> CountMediaItems(int id);
|
||||
Task Update(LocalMediaSource localMediaSource);
|
||||
Task Update(PlexMediaSource plexMediaSource, List<PlexConnection> toAdd, List<PlexConnection> toDelete);
|
||||
|
||||
Task Update(
|
||||
PlexMediaSource plexMediaSource,
|
||||
List<PlexConnection> prioritizedConnections,
|
||||
List<PlexConnection> toAdd,
|
||||
List<PlexConnection> toDelete);
|
||||
|
||||
Task<Unit> UpdateLibraries(
|
||||
int plexMediaSourceId,
|
||||
@@ -36,6 +41,7 @@ namespace ErsatzTV.Core.Interfaces.Repositories
|
||||
Task Update(PlexLibrary plexMediaSourceLibrary);
|
||||
Task Delete(int mediaSourceId);
|
||||
Task<List<int>> DeleteAllPlex();
|
||||
Task<List<int>> DeletePlex(PlexMediaSource plexMediaSource);
|
||||
Task<List<int>> DisablePlexLibrarySync(List<int> libraryIds);
|
||||
Task EnablePlexLibrarySync(IEnumerable<int> libraryIds);
|
||||
}
|
||||
|
||||
@@ -155,6 +155,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
|
||||
|
||||
public async Task Update(
|
||||
PlexMediaSource plexMediaSource,
|
||||
List<PlexConnection> sortedConnections,
|
||||
List<PlexConnection> toAdd,
|
||||
List<PlexConnection> toDelete)
|
||||
{
|
||||
@@ -174,27 +175,34 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
|
||||
plexMediaSource.Id
|
||||
});
|
||||
|
||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext();
|
||||
|
||||
foreach (PlexConnection add in toAdd)
|
||||
{
|
||||
add.PlexMediaSourceId = plexMediaSource.Id;
|
||||
dbContext.Entry(add).State = EntityState.Added;
|
||||
await _dbConnection.ExecuteAsync(
|
||||
@"INSERT INTO PlexConnection (IsActive, Uri, PlexMediaSourceId)
|
||||
VALUES (0, @Uri, @PlexMediaSourceId)",
|
||||
new { add.Uri, PlexMediaSourceId = plexMediaSource.Id });
|
||||
}
|
||||
|
||||
foreach (PlexConnection delete in toDelete)
|
||||
{
|
||||
dbContext.Entry(delete).State = EntityState.Deleted;
|
||||
await _dbConnection.ExecuteAsync(
|
||||
@"DELETE FROM PlexConnection WHERE Id = @Id",
|
||||
new { delete.Id });
|
||||
}
|
||||
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
PlexMediaSource pms = await dbContext.PlexMediaSources.FindAsync(plexMediaSource.Id);
|
||||
await dbContext.Entry(pms).Collection(x => x.Connections).LoadAsync();
|
||||
if (plexMediaSource.Connections.Any() && plexMediaSource.Connections.All(c => !c.IsActive))
|
||||
int activeCount = await _dbConnection.QuerySingleAsync<int>(
|
||||
@"SELECT COUNT(*) FROM PlexConnection WHERE IsActive = 1 AND PlexMediaSourceId = @PlexMediaSourceId",
|
||||
new { PlexMediaSourceId = plexMediaSource.Id });
|
||||
if (activeCount == 0)
|
||||
{
|
||||
plexMediaSource.Connections.Head().IsActive = true;
|
||||
await dbContext.SaveChangesAsync();
|
||||
Option<PlexConnection> toActivate =
|
||||
sortedConnections.FirstOrDefault(c => toDelete.All(d => d.Id != c.Id));
|
||||
|
||||
// update on uri because connections from Plex API don't have our local ids
|
||||
await toActivate.IfSomeAsync(
|
||||
async c => await _dbConnection.ExecuteAsync(
|
||||
@"UPDATE PlexConnection SET IsActive = 1 WHERE Uri = @Uri",
|
||||
new { c.Uri }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,6 +300,23 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
|
||||
return movieIds.Append(showIds).ToList();
|
||||
}
|
||||
|
||||
public async Task<List<int>> DeletePlex(PlexMediaSource plexMediaSource)
|
||||
{
|
||||
List<int> mediaItemIds = await _dbConnection.QueryAsync<int>(
|
||||
@"SELECT MediaItem.Id FROM MediaItem
|
||||
INNER JOIN LibraryPath LP on MediaItem.LibraryPathId = LP.Id
|
||||
INNER JOIN Library L on LP.LibraryId = L.Id
|
||||
WHERE L.MediaSourceId = @PlexMediaSourceId",
|
||||
new { PlexMediaSourceId = plexMediaSource.Id })
|
||||
.Map(result => result.ToList());
|
||||
|
||||
await _dbConnection.ExecuteAsync(
|
||||
@"DELETE FROM MediaSource WHERE Id = @PlexMediaSourceId",
|
||||
new { PlexMediaSourceId = plexMediaSource.Id });
|
||||
|
||||
return mediaItemIds;
|
||||
}
|
||||
|
||||
public async Task<List<int>> DisablePlexLibrarySync(List<int> libraryIds)
|
||||
{
|
||||
await _dbConnection.ExecuteAsync(
|
||||
|
||||
Reference in New Issue
Block a user