add plex network metadata (#2085)
* initial plumbing * scan for plex networks * save network contents to db as tags * eliminate network tag id churn * add network and show_network to search index * update last networks scan * show networks on tv show page * update changelog
This commit is contained in:
@@ -180,6 +180,7 @@
|
||||
case PlexLibraryViewModel:
|
||||
await ScannerWorkerChannel.WriteAsync(new SynchronizePlexLibraries(library.MediaSourceId), _cts.Token);
|
||||
await ScannerWorkerChannel.WriteAsync(new ForceSynchronizePlexLibraryById(library.Id, deepScan), _cts.Token);
|
||||
await ScannerWorkerChannel.WriteAsync(new SynchronizePlexNetworks(library.Id, true), _cts.Token);
|
||||
break;
|
||||
case JellyfinLibraryViewModel:
|
||||
await ScannerWorkerChannel.WriteAsync(new SynchronizeJellyfinLibraries(library.MediaSourceId), _cts.Token);
|
||||
|
||||
@@ -116,6 +116,18 @@
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@if (_sortedNetworks.Any())
|
||||
{
|
||||
<div style="display: flex; flex-direction: row; flex-wrap: wrap">
|
||||
<MudText GutterBottom="true">Networks: </MudText>
|
||||
<MudLink Href="@(@$"network:""{_sortedNetworks.Head().ToLowerInvariant()}""".GetRelativeSearchQuery())">@_sortedNetworks.Head()</MudLink>
|
||||
@foreach (string network in _sortedNetworks.Skip(1))
|
||||
{
|
||||
<MudText>, </MudText>
|
||||
<MudLink Href="@(@$"network:""{network.ToLowerInvariant()}""".GetRelativeSearchQuery())">@network</MudLink>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@if (_sortedGenres.Any())
|
||||
{
|
||||
<div style="display: flex; flex-direction: row; flex-wrap: wrap">
|
||||
@@ -176,11 +188,12 @@
|
||||
public int ShowId { get; set; }
|
||||
|
||||
private TelevisionShowViewModel _show;
|
||||
private List<string> _sortedContentRatings = new();
|
||||
private List<CultureInfo> _sortedLanguages = new();
|
||||
private List<string> _sortedStudios = new();
|
||||
private List<string> _sortedGenres = new();
|
||||
private List<string> _sortedTags = new();
|
||||
private List<string> _sortedContentRatings = [];
|
||||
private List<CultureInfo> _sortedLanguages = [];
|
||||
private List<string> _sortedStudios = [];
|
||||
private List<string> _sortedNetworks = [];
|
||||
private List<string> _sortedGenres = [];
|
||||
private List<string> _sortedTags = [];
|
||||
|
||||
private int _pageSize => 100;
|
||||
private readonly int _pageNumber = 1;
|
||||
@@ -197,17 +210,17 @@
|
||||
|
||||
private async Task RefreshData()
|
||||
{
|
||||
await Mediator.Send(new GetTelevisionShowById(ShowId), _cts.Token)
|
||||
.IfSomeAsync(
|
||||
vm =>
|
||||
{
|
||||
_show = vm;
|
||||
_sortedContentRatings = _show.ContentRatings.OrderBy(cr => cr).ToList();
|
||||
_sortedLanguages = _show.Languages.OrderBy(ci => ci.EnglishName).ToList();
|
||||
_sortedStudios = _show.Studios.OrderBy(s => s).ToList();
|
||||
_sortedGenres = _show.Genres.OrderBy(g => g).ToList();
|
||||
_sortedTags = _show.Tags.OrderBy(t => t).ToList();
|
||||
});
|
||||
Option<TelevisionShowViewModel> maybeShow = await Mediator.Send(new GetTelevisionShowById(ShowId), _cts.Token);
|
||||
foreach (TelevisionShowViewModel show in maybeShow)
|
||||
{
|
||||
_show = show;
|
||||
_sortedContentRatings = _show.ContentRatings.OrderBy(cr => cr).ToList();
|
||||
_sortedLanguages = _show.Languages.OrderBy(ci => ci.EnglishName).ToList();
|
||||
_sortedStudios = _show.Studios.OrderBy(s => s).ToList();
|
||||
_sortedGenres = _show.Genres.OrderBy(g => g).ToList();
|
||||
_sortedTags = _show.Tags.OrderBy(t => t).ToList();
|
||||
_sortedNetworks = _show.Networks.OrderBy(n => n).ToList();
|
||||
}
|
||||
|
||||
_data = await Mediator.Send(new GetTelevisionSeasonCards(ShowId, _pageNumber, _pageSize), _cts.Token);
|
||||
}
|
||||
|
||||
@@ -57,6 +57,9 @@ public class ScannerService : BackgroundService
|
||||
case SynchronizePlexCollections synchronizePlexCollections:
|
||||
requestTask = SynchronizePlexCollections(synchronizePlexCollections, stoppingToken);
|
||||
break;
|
||||
case SynchronizePlexNetworks synchronizePlexNetworks:
|
||||
requestTask = SynchronizePlexNetworks(synchronizePlexNetworks, stoppingToken);
|
||||
break;
|
||||
case SynchronizeJellyfinLibraries synchronizeJellyfinLibraries:
|
||||
requestTask = SynchronizeLibraries(synchronizeJellyfinLibraries, stoppingToken);
|
||||
break;
|
||||
@@ -220,6 +223,40 @@ public class ScannerService : BackgroundService
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SynchronizePlexNetworks(
|
||||
SynchronizePlexNetworks request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
using IServiceScope scope = _serviceScopeFactory.CreateScope();
|
||||
IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
|
||||
IEntityLocker entityLocker = scope.ServiceProvider.GetRequiredService<IEntityLocker>();
|
||||
|
||||
Either<BaseError, Unit> result = await mediator.Send(request, cancellationToken);
|
||||
result.BiIter(
|
||||
_ => _logger.LogDebug("Done synchronizing plex networks for library {LibraryId}", request.PlexLibraryId),
|
||||
error =>
|
||||
{
|
||||
if (error is ScanIsNotRequired)
|
||||
{
|
||||
_logger.LogDebug(
|
||||
"Scan is not required for plex networks in library {LibraryId} at this time",
|
||||
request.PlexLibraryId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning(
|
||||
"Unable to synchronize plex networks for library {LibraryId}: {Error}",
|
||||
request.PlexLibraryId,
|
||||
error.Value);
|
||||
}
|
||||
});
|
||||
|
||||
if (entityLocker.IsLibraryLocked(request.PlexLibraryId))
|
||||
{
|
||||
entityLocker.UnlockLibrary(request.PlexLibraryId);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SynchronizeLibraries(SynchronizeJellyfinLibraries request, CancellationToken cancellationToken)
|
||||
{
|
||||
using IServiceScope scope = _serviceScopeFactory.CreateScope();
|
||||
|
||||
@@ -247,6 +247,13 @@ public class SchedulerService : BackgroundService
|
||||
await _scannerWorkerChannel.WriteAsync(
|
||||
new SynchronizePlexLibraryByIdIfNeeded(library.Id),
|
||||
cancellationToken);
|
||||
|
||||
if (library.MediaKind is LibraryMediaKind.Shows)
|
||||
{
|
||||
await _scannerWorkerChannel.WriteAsync(
|
||||
new SynchronizePlexNetworks(library.Id, false),
|
||||
cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -480,7 +480,7 @@ public class Startup
|
||||
app.UseCors("AllowAll");
|
||||
app.UseForwardedHeaders();
|
||||
|
||||
// app.UseHttpLogging();
|
||||
//app.UseHttpLogging();
|
||||
app.UseSerilogRequestLogging(
|
||||
options =>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user