show plex server names in libraries page (#1402)
* cleanup plex libraries query * show plex server names in libraries page
This commit is contained in:
@@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||||||
- `MYSQL__CONNECTIONSTRING` - (e.g. `Server=localhost;Database=ErsatzTV;Uid=root;Pwd=ersatztv;`)
|
- `MYSQL__CONNECTIONSTRING` - (e.g. `Server=localhost;Database=ErsatzTV;Uid=root;Pwd=ersatztv;`)
|
||||||
- Add option to use shared Plex servers, not just owned servers
|
- Add option to use shared Plex servers, not just owned servers
|
||||||
- This can be enabled by setting the env var `ETV_ALLOW_SHARED_PLEX_SERVERS` to any non-empty value
|
- This can be enabled by setting the env var `ETV_ALLOW_SHARED_PLEX_SERVERS` to any non-empty value
|
||||||
|
- Show Plex server names in Libraries page
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Fix subtitle scaling when using QSV hardware acceleration
|
- Fix subtitle scaling when using QSV hardware acceleration
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ public record EmbyLibraryViewModel(
|
|||||||
LibraryMediaKind MediaKind,
|
LibraryMediaKind MediaKind,
|
||||||
bool ShouldSyncItems,
|
bool ShouldSyncItems,
|
||||||
int MediaSourceId)
|
int MediaSourceId)
|
||||||
: LibraryViewModel("Emby", Id, Name, MediaKind, MediaSourceId);
|
: LibraryViewModel("Emby", Id, Name, MediaKind, MediaSourceId, string.Empty);
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ public record JellyfinLibraryViewModel(
|
|||||||
LibraryMediaKind MediaKind,
|
LibraryMediaKind MediaKind,
|
||||||
bool ShouldSyncItems,
|
bool ShouldSyncItems,
|
||||||
int MediaSourceId)
|
int MediaSourceId)
|
||||||
: LibraryViewModel("Jellyfin", Id, Name, MediaKind, MediaSourceId);
|
: LibraryViewModel("Jellyfin", Id, Name, MediaKind, MediaSourceId, string.Empty);
|
||||||
|
|||||||
@@ -2,4 +2,10 @@
|
|||||||
|
|
||||||
namespace ErsatzTV.Application.Libraries;
|
namespace ErsatzTV.Application.Libraries;
|
||||||
|
|
||||||
public record LibraryViewModel(string LibraryKind, int Id, string Name, LibraryMediaKind MediaKind, int MediaSourceId);
|
public record LibraryViewModel(
|
||||||
|
string LibraryKind,
|
||||||
|
int Id,
|
||||||
|
string Name,
|
||||||
|
LibraryMediaKind MediaKind,
|
||||||
|
int MediaSourceId,
|
||||||
|
string MediaSourceName);
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
namespace ErsatzTV.Application.Libraries;
|
namespace ErsatzTV.Application.Libraries;
|
||||||
|
|
||||||
public record LocalLibraryViewModel(int Id, string Name, LibraryMediaKind MediaKind, int MediaSourceId)
|
public record LocalLibraryViewModel(int Id, string Name, LibraryMediaKind MediaKind, int MediaSourceId)
|
||||||
: LibraryViewModel("Local", Id, Name, MediaKind, MediaSourceId);
|
: LibraryViewModel("Local", Id, Name, MediaKind, MediaSourceId, string.Empty);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ internal static class Mapper
|
|||||||
library switch
|
library switch
|
||||||
{
|
{
|
||||||
LocalLibrary l => ProjectToViewModel(l),
|
LocalLibrary l => ProjectToViewModel(l),
|
||||||
PlexLibrary p => new PlexLibraryViewModel(p.Id, p.Name, p.MediaKind, p.MediaSourceId),
|
PlexLibrary p => new PlexLibraryViewModel(p.Id, p.Name, p.MediaKind, p.MediaSourceId, GetServerName(p.MediaSource)),
|
||||||
JellyfinLibrary j => new JellyfinLibraryViewModel(
|
JellyfinLibrary j => new JellyfinLibraryViewModel(
|
||||||
j.Id,
|
j.Id,
|
||||||
j.Name,
|
j.Name,
|
||||||
@@ -26,4 +26,11 @@ internal static class Mapper
|
|||||||
|
|
||||||
public static LocalLibraryPathViewModel ProjectToViewModel(LibraryPath libraryPath) =>
|
public static LocalLibraryPathViewModel ProjectToViewModel(LibraryPath libraryPath) =>
|
||||||
new(libraryPath.Id, libraryPath.LibraryId, libraryPath.Path);
|
new(libraryPath.Id, libraryPath.LibraryId, libraryPath.Path);
|
||||||
|
|
||||||
|
private static string GetServerName(MediaSource ms) =>
|
||||||
|
ms switch
|
||||||
|
{
|
||||||
|
PlexMediaSource pms => pms.ServerName,
|
||||||
|
_ => string.Empty
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,5 +2,10 @@
|
|||||||
|
|
||||||
namespace ErsatzTV.Application.Libraries;
|
namespace ErsatzTV.Application.Libraries;
|
||||||
|
|
||||||
public record PlexLibraryViewModel(int Id, string Name, LibraryMediaKind MediaKind, int MediaSourceId)
|
public record PlexLibraryViewModel(
|
||||||
: LibraryViewModel("Plex", Id, Name, MediaKind, MediaSourceId);
|
int Id,
|
||||||
|
string Name,
|
||||||
|
LibraryMediaKind MediaKind,
|
||||||
|
int MediaSourceId,
|
||||||
|
string MediaSourceName)
|
||||||
|
: LibraryViewModel("Plex", Id, Name, MediaKind, MediaSourceId, MediaSourceName);
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ public class GetExternalCollectionsHandler : IRequestHandler<GetExternalCollecti
|
|||||||
0,
|
0,
|
||||||
"Collections",
|
"Collections",
|
||||||
0,
|
0,
|
||||||
id))
|
id,
|
||||||
|
string.Empty))
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,28 @@
|
|||||||
using ErsatzTV.Core.Interfaces.Repositories;
|
using ErsatzTV.Infrastructure.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using static ErsatzTV.Application.Plex.Mapper;
|
using static ErsatzTV.Application.Plex.Mapper;
|
||||||
|
|
||||||
namespace ErsatzTV.Application.Plex;
|
namespace ErsatzTV.Application.Plex;
|
||||||
|
|
||||||
public class
|
public class GetPlexLibrariesBySourceIdHandler : IRequestHandler<GetPlexLibrariesBySourceId, List<PlexLibraryViewModel>>
|
||||||
GetPlexLibrariesBySourceIdHandler : IRequestHandler<GetPlexLibrariesBySourceId,
|
|
||||||
List<PlexLibraryViewModel>>
|
|
||||||
{
|
{
|
||||||
private readonly IMediaSourceRepository _mediaSourceRepository;
|
private readonly IDbContextFactory<TvContext> _dbContextFactory;
|
||||||
|
|
||||||
public GetPlexLibrariesBySourceIdHandler(IMediaSourceRepository mediaSourceRepository) =>
|
public GetPlexLibrariesBySourceIdHandler(IDbContextFactory<TvContext> dbContextFactory)
|
||||||
_mediaSourceRepository = mediaSourceRepository;
|
{
|
||||||
|
_dbContextFactory = dbContextFactory;
|
||||||
|
}
|
||||||
|
|
||||||
public Task<List<PlexLibraryViewModel>> Handle(
|
public async Task<List<PlexLibraryViewModel>> Handle(
|
||||||
GetPlexLibrariesBySourceId request,
|
GetPlexLibrariesBySourceId request,
|
||||||
CancellationToken cancellationToken) =>
|
CancellationToken cancellationToken)
|
||||||
_mediaSourceRepository.GetPlexLibraries(request.PlexMediaSourceId)
|
{
|
||||||
.Map(list => list.Map(ProjectToViewModel).ToList());
|
await using TvContext context = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||||
|
|
||||||
|
return await context.PlexLibraries
|
||||||
|
.AsNoTracking()
|
||||||
|
.Where(l => l.MediaSourceId == request.PlexMediaSourceId)
|
||||||
|
.Map(pl => ProjectToViewModel(pl))
|
||||||
|
.ToListAsync(cancellationToken);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ public interface IMediaSourceRepository
|
|||||||
{
|
{
|
||||||
Task<PlexMediaSource> Add(PlexMediaSource plexMediaSource);
|
Task<PlexMediaSource> Add(PlexMediaSource plexMediaSource);
|
||||||
Task<List<PlexMediaSource>> GetAllPlex();
|
Task<List<PlexMediaSource>> GetAllPlex();
|
||||||
Task<List<PlexLibrary>> GetPlexLibraries(int plexMediaSourceId);
|
|
||||||
Task<List<PlexPathReplacement>> GetPlexPathReplacements(int plexMediaSourceId);
|
Task<List<PlexPathReplacement>> GetPlexPathReplacements(int plexMediaSourceId);
|
||||||
Task<Option<PlexLibrary>> GetPlexLibrary(int plexLibraryId);
|
Task<Option<PlexLibrary>> GetPlexLibrary(int plexLibraryId);
|
||||||
Task<Option<PlexMediaSource>> GetPlex(int id);
|
Task<Option<PlexMediaSource>> GetPlex(int id);
|
||||||
|
|||||||
@@ -31,14 +31,6 @@ public class MediaSourceRepository : IMediaSourceRepository
|
|||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<PlexLibrary>> GetPlexLibraries(int plexMediaSourceId)
|
|
||||||
{
|
|
||||||
await using TvContext context = await _dbContextFactory.CreateDbContextAsync();
|
|
||||||
return await context.PlexLibraries
|
|
||||||
.Filter(l => l.MediaSourceId == plexMediaSourceId)
|
|
||||||
.ToListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<PlexPathReplacement>> GetPlexPathReplacements(int plexMediaSourceId)
|
public async Task<List<PlexPathReplacement>> GetPlexPathReplacements(int plexMediaSourceId)
|
||||||
{
|
{
|
||||||
await using TvContext context = await _dbContextFactory.CreateDbContextAsync();
|
await using TvContext context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|||||||
@@ -20,19 +20,31 @@
|
|||||||
</ToolBarContent>
|
</ToolBarContent>
|
||||||
<ColGroup>
|
<ColGroup>
|
||||||
<col/>
|
<col/>
|
||||||
|
@if (_showServerNames)
|
||||||
|
{
|
||||||
|
<col/>
|
||||||
|
}
|
||||||
<col/>
|
<col/>
|
||||||
<col/>
|
<col/>
|
||||||
<col style="width: 180px;"/>
|
<col style="width: 180px;"/>
|
||||||
</ColGroup>
|
</ColGroup>
|
||||||
<HeaderContent>
|
<HeaderContent>
|
||||||
<MudTh>Library Kind</MudTh>
|
<MudTh>Library Kind</MudTh>
|
||||||
<MudTh>Name</MudTh>
|
@if (_showServerNames)
|
||||||
|
{
|
||||||
|
<MudTh>Server Name</MudTh>
|
||||||
|
}
|
||||||
|
<MudTh>Library Name</MudTh>
|
||||||
<MudTh>Media Kind</MudTh>
|
<MudTh>Media Kind</MudTh>
|
||||||
<MudTh/>
|
<MudTh/>
|
||||||
</HeaderContent>
|
</HeaderContent>
|
||||||
<RowTemplate>
|
<RowTemplate>
|
||||||
<MudTd DataLabel="Library Kind">@context.LibraryKind</MudTd>
|
<MudTd DataLabel="Library Kind">@context.LibraryKind</MudTd>
|
||||||
<MudTd DataLabel="Name">@context.Name</MudTd>
|
@if (_showServerNames)
|
||||||
|
{
|
||||||
|
<MudTd DataLabel="Server Name">@context.MediaSourceName</MudTd>
|
||||||
|
}
|
||||||
|
<MudTd DataLabel="Library Name">@context.Name</MudTd>
|
||||||
<MudTd DataLabel="Media Kind">@context.MediaKind</MudTd>
|
<MudTd DataLabel="Media Kind">@context.MediaKind</MudTd>
|
||||||
<MudTd>
|
<MudTd>
|
||||||
<div style="align-items: center; display: flex;">
|
<div style="align-items: center; display: flex;">
|
||||||
@@ -133,6 +145,7 @@
|
|||||||
private IList<LibraryViewModel> _libraries = new List<LibraryViewModel>();
|
private IList<LibraryViewModel> _libraries = new List<LibraryViewModel>();
|
||||||
private IList<LibraryViewModel> _externalCollections = new List<LibraryViewModel>();
|
private IList<LibraryViewModel> _externalCollections = new List<LibraryViewModel>();
|
||||||
private Dictionary<int, int> _progressByLibrary = new();
|
private Dictionary<int, int> _progressByLibrary = new();
|
||||||
|
private bool _showServerNames = false;
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
@@ -146,6 +159,8 @@
|
|||||||
private async Task LoadLibraries(CancellationToken cancellationToken)
|
private async Task LoadLibraries(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_libraries = await _mediator.Send(new GetConfiguredLibraries(), cancellationToken);
|
_libraries = await _mediator.Send(new GetConfiguredLibraries(), cancellationToken);
|
||||||
|
_showServerNames = _libraries.Any(l => l is PlexLibraryViewModel);
|
||||||
|
|
||||||
_externalCollections = await _mediator.Send(new GetExternalCollections(), cancellationToken);
|
_externalCollections = await _mediator.Send(new GetExternalCollections(), cancellationToken);
|
||||||
_progressByLibrary = _libraries.ToDictionary(vm => vm.Id, _ => 0);
|
_progressByLibrary = _libraries.ToDictionary(vm => vm.Id, _ => 0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user