Browse Source

error report bug fixes (#1042)

* fix some potential null reference exceptions

* searching isn't actually async

* add search query breadcrumb
pull/1046/head
Jason Dove 4 years ago committed by GitHub
parent
commit
9a30d7c7da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      ErsatzTV.Application/Maintenance/Commands/EmptyTrashHandler.cs
  2. 38
      ErsatzTV.Application/Search/Queries/QuerySearchIndexAllItemsHandler.cs
  3. 14
      ErsatzTV.Application/Search/Queries/QuerySearchIndexArtistsHandler.cs
  4. 9
      ErsatzTV.Application/Search/Queries/QuerySearchIndexEpisodesHandler.cs
  5. 9
      ErsatzTV.Application/Search/Queries/QuerySearchIndexMoviesHandler.cs
  6. 9
      ErsatzTV.Application/Search/Queries/QuerySearchIndexMusicVideosHandler.cs
  7. 13
      ErsatzTV.Application/Search/Queries/QuerySearchIndexOtherVideosHandler.cs
  8. 9
      ErsatzTV.Application/Search/Queries/QuerySearchIndexSeasonsHandler.cs
  9. 9
      ErsatzTV.Application/Search/Queries/QuerySearchIndexShowsHandler.cs
  10. 14
      ErsatzTV.Application/Search/Queries/QuerySearchIndexSongsHandler.cs
  11. 3
      ErsatzTV.Core.Tests/Scheduling/ScheduleIntegrationTests.cs
  12. 5
      ErsatzTV.Core/Interfaces/Search/ISearchIndex.cs
  13. 8
      ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs
  14. 2
      ErsatzTV.Infrastructure/Plex/PlexServerApiClient.cs
  15. 17
      ErsatzTV.Infrastructure/Search/SearchIndex.cs
  16. 5
      ErsatzTV/Pages/Channels.razor
  17. 15
      ErsatzTV/Pages/Collections.razor
  18. 5
      ErsatzTV/Pages/FillerPresets.razor
  19. 22
      ErsatzTV/Pages/Playouts.razor
  20. 10
      ErsatzTV/Pages/Schedules.razor
  21. 2
      ErsatzTV/Pages/TraktLists.razor

8
ErsatzTV.Application/Maintenance/Commands/EmptyTrashHandler.cs

@ -1,4 +1,5 @@
using ErsatzTV.Core; using Bugsnag;
using ErsatzTV.Core;
using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Core.Interfaces.Search; using ErsatzTV.Core.Interfaces.Search;
using ErsatzTV.Core.Search; using ErsatzTV.Core.Search;
@ -8,13 +9,16 @@ namespace ErsatzTV.Application.Maintenance;
public class EmptyTrashHandler : IRequestHandler<EmptyTrash, Either<BaseError, Unit>> public class EmptyTrashHandler : IRequestHandler<EmptyTrash, Either<BaseError, Unit>>
{ {
private readonly IClient _client;
private readonly IMediaItemRepository _mediaItemRepository; private readonly IMediaItemRepository _mediaItemRepository;
private readonly ISearchIndex _searchIndex; private readonly ISearchIndex _searchIndex;
public EmptyTrashHandler( public EmptyTrashHandler(
IClient client,
IMediaItemRepository mediaItemRepository, IMediaItemRepository mediaItemRepository,
ISearchIndex searchIndex) ISearchIndex searchIndex)
{ {
_client = client;
_mediaItemRepository = mediaItemRepository; _mediaItemRepository = mediaItemRepository;
_searchIndex = searchIndex; _searchIndex = searchIndex;
} }
@ -39,7 +43,7 @@ public class EmptyTrashHandler : IRequestHandler<EmptyTrash, Either<BaseError, U
foreach (string type in types) foreach (string type in types)
{ {
SearchResult result = await _searchIndex.Search($"type:{type} AND (state:FileNotFound)", 0, 0); SearchResult result = _searchIndex.Search(_client, $"type:{type} AND (state:FileNotFound)", 0, 0);
ids.AddRange(result.Items.Map(i => i.Id)); ids.AddRange(result.Items.Map(i => i.Id));
} }

38
ErsatzTV.Application/Search/Queries/QuerySearchIndexAllItemsHandler.cs

@ -1,29 +1,33 @@
using ErsatzTV.Core.Interfaces.Search; using Bugsnag;
using ErsatzTV.Core.Interfaces.Search;
using ErsatzTV.Infrastructure.Search; using ErsatzTV.Infrastructure.Search;
namespace ErsatzTV.Application.Search; namespace ErsatzTV.Application.Search;
public class public class QuerySearchIndexAllItemsHandler : IRequestHandler<QuerySearchIndexAllItems, SearchResultAllItemsViewModel>
QuerySearchIndexAllItemsHandler : IRequestHandler<QuerySearchIndexAllItems, SearchResultAllItemsViewModel>
{ {
private readonly IClient _client;
private readonly ISearchIndex _searchIndex; private readonly ISearchIndex _searchIndex;
public QuerySearchIndexAllItemsHandler(ISearchIndex searchIndex) => _searchIndex = searchIndex; public QuerySearchIndexAllItemsHandler(IClient client, ISearchIndex searchIndex)
{
_client = client;
_searchIndex = searchIndex;
}
public async Task<SearchResultAllItemsViewModel> Handle( public Task<SearchResultAllItemsViewModel> Handle(
QuerySearchIndexAllItems request, QuerySearchIndexAllItems request,
CancellationToken cancellationToken) => CancellationToken cancellationToken) =>
new( new SearchResultAllItemsViewModel(
await GetIds(SearchIndex.MovieType, request.Query), GetIds(SearchIndex.MovieType, request.Query),
await GetIds(SearchIndex.ShowType, request.Query), GetIds(SearchIndex.ShowType, request.Query),
await GetIds(SearchIndex.SeasonType, request.Query), GetIds(SearchIndex.SeasonType, request.Query),
await GetIds(SearchIndex.EpisodeType, request.Query), GetIds(SearchIndex.EpisodeType, request.Query),
await GetIds(SearchIndex.ArtistType, request.Query), GetIds(SearchIndex.ArtistType, request.Query),
await GetIds(SearchIndex.MusicVideoType, request.Query), GetIds(SearchIndex.MusicVideoType, request.Query),
await GetIds(SearchIndex.OtherVideoType, request.Query), GetIds(SearchIndex.OtherVideoType, request.Query),
await GetIds(SearchIndex.SongType, request.Query)); GetIds(SearchIndex.SongType, request.Query)).AsTask();
private Task<List<int>> GetIds(string type, string query) => private List<int> GetIds(string type, string query) =>
_searchIndex.Search($"type:{type} AND ({query})", 0, 0) _searchIndex.Search(_client, $"type:{type} AND ({query})", 0, 0).Items.Map(i => i.Id).ToList();
.Map(result => result.Items.Map(i => i.Id).ToList());
} }

14
ErsatzTV.Application/Search/Queries/QuerySearchIndexArtistsHandler.cs

@ -1,4 +1,5 @@
using ErsatzTV.Application.MediaCards; using Bugsnag;
using ErsatzTV.Application.MediaCards;
using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Core.Interfaces.Search; using ErsatzTV.Core.Interfaces.Search;
using ErsatzTV.Core.Search; using ErsatzTV.Core.Search;
@ -6,15 +7,15 @@ using static ErsatzTV.Application.MediaCards.Mapper;
namespace ErsatzTV.Application.Search; namespace ErsatzTV.Application.Search;
public class public class QuerySearchIndexArtistsHandler : IRequestHandler<QuerySearchIndexArtists, ArtistCardResultsViewModel>
QuerySearchIndexArtistsHandler : IRequestHandler<QuerySearchIndexArtists, ArtistCardResultsViewModel
>
{ {
private readonly IArtistRepository _artistRepository; private readonly IArtistRepository _artistRepository;
private readonly IClient _client;
private readonly ISearchIndex _searchIndex; private readonly ISearchIndex _searchIndex;
public QuerySearchIndexArtistsHandler(ISearchIndex searchIndex, IArtistRepository artistRepository) public QuerySearchIndexArtistsHandler(IClient client, ISearchIndex searchIndex, IArtistRepository artistRepository)
{ {
_client = client;
_searchIndex = searchIndex; _searchIndex = searchIndex;
_artistRepository = artistRepository; _artistRepository = artistRepository;
} }
@ -23,7 +24,8 @@ public class
QuerySearchIndexArtists request, QuerySearchIndexArtists request,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
SearchResult searchResult = await _searchIndex.Search( SearchResult searchResult = _searchIndex.Search(
_client,
request.Query, request.Query,
(request.PageNumber - 1) * request.PageSize, (request.PageNumber - 1) * request.PageSize,
request.PageSize); request.PageSize);

9
ErsatzTV.Application/Search/Queries/QuerySearchIndexEpisodesHandler.cs

@ -1,4 +1,5 @@
using ErsatzTV.Application.MediaCards; using Bugsnag;
using ErsatzTV.Application.MediaCards;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Extensions; using ErsatzTV.Core.Extensions;
using ErsatzTV.Core.Interfaces.Emby; using ErsatzTV.Core.Interfaces.Emby;
@ -24,10 +25,12 @@ public class
private readonly IJellyfinPathReplacementService _jellyfinPathReplacementService; private readonly IJellyfinPathReplacementService _jellyfinPathReplacementService;
private readonly IMediaSourceRepository _mediaSourceRepository; private readonly IMediaSourceRepository _mediaSourceRepository;
private readonly IPlexPathReplacementService _plexPathReplacementService; private readonly IPlexPathReplacementService _plexPathReplacementService;
private readonly IClient _client;
private readonly ISearchIndex _searchIndex; private readonly ISearchIndex _searchIndex;
private readonly ITelevisionRepository _televisionRepository; private readonly ITelevisionRepository _televisionRepository;
public QuerySearchIndexEpisodesHandler( public QuerySearchIndexEpisodesHandler(
IClient client,
ISearchIndex searchIndex, ISearchIndex searchIndex,
ITelevisionRepository televisionRepository, ITelevisionRepository televisionRepository,
IMediaSourceRepository mediaSourceRepository, IMediaSourceRepository mediaSourceRepository,
@ -37,6 +40,7 @@ public class
IFallbackMetadataProvider fallbackMetadataProvider, IFallbackMetadataProvider fallbackMetadataProvider,
IDbContextFactory<TvContext> dbContextFactory) IDbContextFactory<TvContext> dbContextFactory)
{ {
_client = client;
_searchIndex = searchIndex; _searchIndex = searchIndex;
_televisionRepository = televisionRepository; _televisionRepository = televisionRepository;
_mediaSourceRepository = mediaSourceRepository; _mediaSourceRepository = mediaSourceRepository;
@ -51,7 +55,8 @@ public class
QuerySearchIndexEpisodes request, QuerySearchIndexEpisodes request,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
SearchResult searchResult = await _searchIndex.Search( SearchResult searchResult = _searchIndex.Search(
_client,
request.Query, request.Query,
(request.PageNumber - 1) * request.PageSize, (request.PageNumber - 1) * request.PageSize,
request.PageSize); request.PageSize);

9
ErsatzTV.Application/Search/Queries/QuerySearchIndexMoviesHandler.cs

@ -1,4 +1,5 @@
using ErsatzTV.Application.MediaCards; using Bugsnag;
using ErsatzTV.Application.MediaCards;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Core.Interfaces.Search; using ErsatzTV.Core.Interfaces.Search;
@ -11,13 +12,16 @@ public class QuerySearchIndexMoviesHandler : IRequestHandler<QuerySearchIndexMov
{ {
private readonly IMediaSourceRepository _mediaSourceRepository; private readonly IMediaSourceRepository _mediaSourceRepository;
private readonly IMovieRepository _movieRepository; private readonly IMovieRepository _movieRepository;
private readonly IClient _client;
private readonly ISearchIndex _searchIndex; private readonly ISearchIndex _searchIndex;
public QuerySearchIndexMoviesHandler( public QuerySearchIndexMoviesHandler(
IClient client,
ISearchIndex searchIndex, ISearchIndex searchIndex,
IMovieRepository movieRepository, IMovieRepository movieRepository,
IMediaSourceRepository mediaSourceRepository) IMediaSourceRepository mediaSourceRepository)
{ {
_client = client;
_searchIndex = searchIndex; _searchIndex = searchIndex;
_movieRepository = movieRepository; _movieRepository = movieRepository;
_mediaSourceRepository = mediaSourceRepository; _mediaSourceRepository = mediaSourceRepository;
@ -27,7 +31,8 @@ public class QuerySearchIndexMoviesHandler : IRequestHandler<QuerySearchIndexMov
QuerySearchIndexMovies request, QuerySearchIndexMovies request,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
SearchResult searchResult = await _searchIndex.Search( SearchResult searchResult = _searchIndex.Search(
_client,
request.Query, request.Query,
(request.PageNumber - 1) * request.PageSize, (request.PageNumber - 1) * request.PageSize,
request.PageSize); request.PageSize);

9
ErsatzTV.Application/Search/Queries/QuerySearchIndexMusicVideosHandler.cs

@ -1,4 +1,5 @@
using ErsatzTV.Application.MediaCards; using Bugsnag;
using ErsatzTV.Application.MediaCards;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Extensions; using ErsatzTV.Core.Extensions;
using ErsatzTV.Core.Interfaces.Emby; using ErsatzTV.Core.Interfaces.Emby;
@ -18,15 +19,18 @@ public class
private readonly IJellyfinPathReplacementService _jellyfinPathReplacementService; private readonly IJellyfinPathReplacementService _jellyfinPathReplacementService;
private readonly IMusicVideoRepository _musicVideoRepository; private readonly IMusicVideoRepository _musicVideoRepository;
private readonly IPlexPathReplacementService _plexPathReplacementService; private readonly IPlexPathReplacementService _plexPathReplacementService;
private readonly IClient _client;
private readonly ISearchIndex _searchIndex; private readonly ISearchIndex _searchIndex;
public QuerySearchIndexMusicVideosHandler( public QuerySearchIndexMusicVideosHandler(
IClient client,
ISearchIndex searchIndex, ISearchIndex searchIndex,
IMusicVideoRepository musicVideoRepository, IMusicVideoRepository musicVideoRepository,
IPlexPathReplacementService plexPathReplacementService, IPlexPathReplacementService plexPathReplacementService,
IJellyfinPathReplacementService jellyfinPathReplacementService, IJellyfinPathReplacementService jellyfinPathReplacementService,
IEmbyPathReplacementService embyPathReplacementService) IEmbyPathReplacementService embyPathReplacementService)
{ {
_client = client;
_searchIndex = searchIndex; _searchIndex = searchIndex;
_musicVideoRepository = musicVideoRepository; _musicVideoRepository = musicVideoRepository;
_plexPathReplacementService = plexPathReplacementService; _plexPathReplacementService = plexPathReplacementService;
@ -38,7 +42,8 @@ public class
QuerySearchIndexMusicVideos request, QuerySearchIndexMusicVideos request,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
SearchResult searchResult = await _searchIndex.Search( SearchResult searchResult = _searchIndex.Search(
_client,
request.Query, request.Query,
(request.PageNumber - 1) * request.PageSize, (request.PageNumber - 1) * request.PageSize,
request.PageSize); request.PageSize);

13
ErsatzTV.Application/Search/Queries/QuerySearchIndexOtherVideosHandler.cs

@ -1,4 +1,5 @@
using ErsatzTV.Application.MediaCards; using Bugsnag;
using ErsatzTV.Application.MediaCards;
using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Core.Interfaces.Search; using ErsatzTV.Core.Interfaces.Search;
using ErsatzTV.Core.Search; using ErsatzTV.Core.Search;
@ -11,10 +12,15 @@ public class
OtherVideoCardResultsViewModel> OtherVideoCardResultsViewModel>
{ {
private readonly IOtherVideoRepository _otherVideoRepository; private readonly IOtherVideoRepository _otherVideoRepository;
private readonly IClient _client;
private readonly ISearchIndex _searchIndex; private readonly ISearchIndex _searchIndex;
public QuerySearchIndexOtherVideosHandler(ISearchIndex searchIndex, IOtherVideoRepository otherVideoRepository) public QuerySearchIndexOtherVideosHandler(
IClient client,
ISearchIndex searchIndex,
IOtherVideoRepository otherVideoRepository)
{ {
_client = client;
_searchIndex = searchIndex; _searchIndex = searchIndex;
_otherVideoRepository = otherVideoRepository; _otherVideoRepository = otherVideoRepository;
} }
@ -23,7 +29,8 @@ public class
QuerySearchIndexOtherVideos request, QuerySearchIndexOtherVideos request,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
SearchResult searchResult = await _searchIndex.Search( SearchResult searchResult = _searchIndex.Search(
_client,
request.Query, request.Query,
(request.PageNumber - 1) * request.PageSize, (request.PageNumber - 1) * request.PageSize,
request.PageSize); request.PageSize);

9
ErsatzTV.Application/Search/Queries/QuerySearchIndexSeasonsHandler.cs

@ -1,4 +1,5 @@
using ErsatzTV.Application.MediaCards; using Bugsnag;
using ErsatzTV.Application.MediaCards;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Core.Interfaces.Search; using ErsatzTV.Core.Interfaces.Search;
@ -11,14 +12,17 @@ public class
QuerySearchIndexSeasonsHandler : IRequestHandler<QuerySearchIndexSeasons, TelevisionSeasonCardResultsViewModel> QuerySearchIndexSeasonsHandler : IRequestHandler<QuerySearchIndexSeasons, TelevisionSeasonCardResultsViewModel>
{ {
private readonly IMediaSourceRepository _mediaSourceRepository; private readonly IMediaSourceRepository _mediaSourceRepository;
private readonly IClient _client;
private readonly ISearchIndex _searchIndex; private readonly ISearchIndex _searchIndex;
private readonly ITelevisionRepository _televisionRepository; private readonly ITelevisionRepository _televisionRepository;
public QuerySearchIndexSeasonsHandler( public QuerySearchIndexSeasonsHandler(
IClient client,
ISearchIndex searchIndex, ISearchIndex searchIndex,
ITelevisionRepository televisionRepository, ITelevisionRepository televisionRepository,
IMediaSourceRepository mediaSourceRepository) IMediaSourceRepository mediaSourceRepository)
{ {
_client = client;
_searchIndex = searchIndex; _searchIndex = searchIndex;
_televisionRepository = televisionRepository; _televisionRepository = televisionRepository;
_mediaSourceRepository = mediaSourceRepository; _mediaSourceRepository = mediaSourceRepository;
@ -28,7 +32,8 @@ public class
QuerySearchIndexSeasons request, QuerySearchIndexSeasons request,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
SearchResult searchResult = await _searchIndex.Search( SearchResult searchResult = _searchIndex.Search(
_client,
request.Query, request.Query,
(request.PageNumber - 1) * request.PageSize, (request.PageNumber - 1) * request.PageSize,
request.PageSize); request.PageSize);

9
ErsatzTV.Application/Search/Queries/QuerySearchIndexShowsHandler.cs

@ -1,4 +1,5 @@
using ErsatzTV.Application.MediaCards; using Bugsnag;
using ErsatzTV.Application.MediaCards;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Core.Interfaces.Search; using ErsatzTV.Core.Interfaces.Search;
@ -11,14 +12,17 @@ public class
QuerySearchIndexShowsHandler : IRequestHandler<QuerySearchIndexShows, TelevisionShowCardResultsViewModel> QuerySearchIndexShowsHandler : IRequestHandler<QuerySearchIndexShows, TelevisionShowCardResultsViewModel>
{ {
private readonly IMediaSourceRepository _mediaSourceRepository; private readonly IMediaSourceRepository _mediaSourceRepository;
private readonly IClient _client;
private readonly ISearchIndex _searchIndex; private readonly ISearchIndex _searchIndex;
private readonly ITelevisionRepository _televisionRepository; private readonly ITelevisionRepository _televisionRepository;
public QuerySearchIndexShowsHandler( public QuerySearchIndexShowsHandler(
IClient client,
ISearchIndex searchIndex, ISearchIndex searchIndex,
ITelevisionRepository televisionRepository, ITelevisionRepository televisionRepository,
IMediaSourceRepository mediaSourceRepository) IMediaSourceRepository mediaSourceRepository)
{ {
_client = client;
_searchIndex = searchIndex; _searchIndex = searchIndex;
_televisionRepository = televisionRepository; _televisionRepository = televisionRepository;
_mediaSourceRepository = mediaSourceRepository; _mediaSourceRepository = mediaSourceRepository;
@ -28,7 +32,8 @@ public class
QuerySearchIndexShows request, QuerySearchIndexShows request,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
SearchResult searchResult = await _searchIndex.Search( SearchResult searchResult = _searchIndex.Search(
_client,
request.Query, request.Query,
(request.PageNumber - 1) * request.PageSize, (request.PageNumber - 1) * request.PageSize,
request.PageSize); request.PageSize);

14
ErsatzTV.Application/Search/Queries/QuerySearchIndexSongsHandler.cs

@ -1,4 +1,5 @@
using ErsatzTV.Application.MediaCards; using Bugsnag;
using ErsatzTV.Application.MediaCards;
using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Core.Interfaces.Search; using ErsatzTV.Core.Interfaces.Search;
using ErsatzTV.Core.Search; using ErsatzTV.Core.Search;
@ -6,15 +7,15 @@ using static ErsatzTV.Application.MediaCards.Mapper;
namespace ErsatzTV.Application.Search; namespace ErsatzTV.Application.Search;
public class public class QuerySearchIndexSongsHandler : IRequestHandler<QuerySearchIndexSongs, SongCardResultsViewModel>
QuerySearchIndexSongsHandler : IRequestHandler<QuerySearchIndexSongs,
SongCardResultsViewModel>
{ {
private readonly IClient _client;
private readonly ISearchIndex _searchIndex; private readonly ISearchIndex _searchIndex;
private readonly ISongRepository _songRepository; private readonly ISongRepository _songRepository;
public QuerySearchIndexSongsHandler(ISearchIndex searchIndex, ISongRepository songRepository) public QuerySearchIndexSongsHandler(IClient client, ISearchIndex searchIndex, ISongRepository songRepository)
{ {
_client = client;
_searchIndex = searchIndex; _searchIndex = searchIndex;
_songRepository = songRepository; _songRepository = songRepository;
} }
@ -23,7 +24,8 @@ public class
QuerySearchIndexSongs request, QuerySearchIndexSongs request,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
SearchResult searchResult = await _searchIndex.Search( SearchResult searchResult = _searchIndex.Search(
_client,
request.Query, request.Query,
(request.PageNumber - 1) * request.PageSize, (request.PageNumber - 1) * request.PageSize,
request.PageSize); request.PageSize);

3
ErsatzTV.Core.Tests/Scheduling/ScheduleIntegrationTests.cs

@ -1,3 +1,4 @@
using Bugsnag;
using Dapper; using Dapper;
using Destructurama; using Destructurama;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
@ -152,7 +153,7 @@ public class ScheduleIntegrationTests
var builder = new PlayoutBuilder( var builder = new PlayoutBuilder(
new ConfigElementRepository(factory), new ConfigElementRepository(factory),
new MediaCollectionRepository(new Mock<ISearchIndex>().Object, factory), new MediaCollectionRepository(new Mock<IClient>().Object, new Mock<ISearchIndex>().Object, factory),
new TelevisionRepository(factory), new TelevisionRepository(factory),
new ArtistRepository(factory), new ArtistRepository(factory),
new Mock<IMultiEpisodeShuffleCollectionEnumeratorFactory>().Object, new Mock<IMultiEpisodeShuffleCollectionEnumeratorFactory>().Object,

5
ErsatzTV.Core/Interfaces/Search/ISearchIndex.cs

@ -1,4 +1,5 @@
using ErsatzTV.Core.Domain; using Bugsnag;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Metadata;
using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Core.Interfaces.Repositories.Caching; using ErsatzTV.Core.Interfaces.Repositories.Caching;
@ -23,6 +24,6 @@ public interface ISearchIndex : IDisposable
List<MediaItem> items); List<MediaItem> items);
Task<Unit> RemoveItems(List<int> ids); Task<Unit> RemoveItems(List<int> ids);
Task<SearchResult> Search(string query, int skip, int limit, string searchField = ""); SearchResult Search(IClient client, string query, int skip, int limit, string searchField = "");
void Commit(); void Commit();
} }

8
ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs

@ -1,4 +1,5 @@
using Dapper; using Bugsnag;
using Dapper;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Core.Interfaces.Search; using ErsatzTV.Core.Interfaces.Search;
@ -13,12 +14,15 @@ namespace ErsatzTV.Infrastructure.Data.Repositories;
public class MediaCollectionRepository : IMediaCollectionRepository public class MediaCollectionRepository : IMediaCollectionRepository
{ {
private readonly IDbContextFactory<TvContext> _dbContextFactory; private readonly IDbContextFactory<TvContext> _dbContextFactory;
private readonly IClient _client;
private readonly ISearchIndex _searchIndex; private readonly ISearchIndex _searchIndex;
public MediaCollectionRepository( public MediaCollectionRepository(
IClient client,
ISearchIndex searchIndex, ISearchIndex searchIndex,
IDbContextFactory<TvContext> dbContextFactory) IDbContextFactory<TvContext> dbContextFactory)
{ {
_client = client;
_searchIndex = searchIndex; _searchIndex = searchIndex;
_dbContextFactory = dbContextFactory; _dbContextFactory = dbContextFactory;
} }
@ -96,7 +100,7 @@ public class MediaCollectionRepository : IMediaCollectionRepository
foreach (SmartCollection collection in maybeCollection) foreach (SmartCollection collection in maybeCollection)
{ {
SearchResult searchResults = await _searchIndex.Search(collection.Query, 0, 0); SearchResult searchResults = _searchIndex.Search(_client, collection.Query, 0, 0);
var movieIds = searchResults.Items var movieIds = searchResults.Items
.Filter(i => i.Type == SearchIndex.MovieType) .Filter(i => i.Type == SearchIndex.MovieType)

2
ErsatzTV.Infrastructure/Plex/PlexServerApiClient.cs

@ -103,7 +103,7 @@ public class PlexServerApiClient : IPlexServerApiClient
{ {
return jsonService return jsonService
.GetLibrarySectionContents(library.Key, skip, pageSize, token.AuthToken) .GetLibrarySectionContents(library.Key, skip, pageSize, token.AuthToken)
.Map(r => r.MediaContainer.Metadata) .Map(r => r.MediaContainer.Metadata ?? new List<PlexMetadataResponse>())
.Map(list => list.Map(metadata => ProjectToShow(metadata, library.MediaSourceId))); .Map(list => list.Map(metadata => ProjectToShow(metadata, library.MediaSourceId)));
} }

17
ErsatzTV.Infrastructure/Search/SearchIndex.cs

@ -1,4 +1,5 @@
using System.Globalization; using System.Globalization;
using Bugsnag;
using ErsatzTV.Core; using ErsatzTV.Core;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Metadata;
@ -173,11 +174,21 @@ public sealed class SearchIndex : ISearchIndex
return Task.FromResult(Unit.Default); return Task.FromResult(Unit.Default);
} }
public Task<SearchResult> Search(string searchQuery, int skip, int limit, string searchField = "") public SearchResult Search(IClient client, string searchQuery, int skip, int limit, string searchField = "")
{ {
var metadata = new Dictionary<string, string>
{
{ "searchQuery", searchQuery },
{ "skip", skip.ToString() },
{ "limit", limit.ToString() },
{ "searchField", searchField }
};
client.Breadcrumbs.Leave("SearchIndex.Search", BreadcrumbType.State, metadata);
if (string.IsNullOrWhiteSpace(searchQuery.Replace("*", string.Empty).Replace("?", string.Empty))) if (string.IsNullOrWhiteSpace(searchQuery.Replace("*", string.Empty).Replace("?", string.Empty)))
{ {
return new SearchResult(new List<SearchItem>(), 0).AsTask(); return new SearchResult(new List<SearchItem>(), 0);
} }
using DirectoryReader reader = _writer.GetReader(true); using DirectoryReader reader = _writer.GetReader(true);
@ -214,7 +225,7 @@ public sealed class SearchIndex : ISearchIndex
searchResult.PageMap = GetSearchPageMap(searcher, query, filter, sort, limit); searchResult.PageMap = GetSearchPageMap(searcher, query, filter, sort, limit);
} }
return searchResult.AsTask(); return searchResult;
} }
public void Commit() => _writer.Commit(); public void Commit() => _writer.Commit();

5
ErsatzTV/Pages/Channels.razor

@ -109,7 +109,10 @@
if (!result.Cancelled) if (!result.Cancelled)
{ {
await _mediator.Send(new DeleteChannel(channel.Id), _cts.Token); await _mediator.Send(new DeleteChannel(channel.Id), _cts.Token);
await _table.ReloadServerData(); if (_table != null)
{
await _table.ReloadServerData();
}
} }
} }

15
ErsatzTV/Pages/Collections.razor

@ -170,7 +170,10 @@
if (!result.Cancelled) if (!result.Cancelled)
{ {
await _mediator.Send(new DeleteCollection(collection.Id), _cts.Token); await _mediator.Send(new DeleteCollection(collection.Id), _cts.Token);
await _collectionsTable.ReloadServerData(); if (_collectionsTable != null)
{
await _collectionsTable.ReloadServerData();
}
} }
} }
@ -184,7 +187,10 @@
if (!result.Cancelled) if (!result.Cancelled)
{ {
await _mediator.Send(new DeleteMultiCollection(collection.Id), _cts.Token); await _mediator.Send(new DeleteMultiCollection(collection.Id), _cts.Token);
await _multiCollectionsTable.ReloadServerData(); if (_multiCollectionsTable != null)
{
await _multiCollectionsTable.ReloadServerData();
}
} }
} }
@ -198,7 +204,10 @@
if (!result.Cancelled) if (!result.Cancelled)
{ {
await _mediator.Send(new DeleteSmartCollection(collection.Id), _cts.Token); await _mediator.Send(new DeleteSmartCollection(collection.Id), _cts.Token);
await _smartCollectionsTable.ReloadServerData(); if (_smartCollectionsTable != null)
{
await _smartCollectionsTable.ReloadServerData();
}
} }
} }

5
ErsatzTV/Pages/FillerPresets.razor

@ -92,7 +92,10 @@
if (!result.Cancelled) if (!result.Cancelled)
{ {
await _mediator.Send(new DeleteFillerPreset(fillerPreset.Id), _cts.Token); await _mediator.Send(new DeleteFillerPreset(fillerPreset.Id), _cts.Token);
await _fillerPresetsTable.ReloadServerData(); if (_fillerPresetsTable != null)
{
await _fillerPresetsTable.ReloadServerData();
}
} }
} }

22
ErsatzTV/Pages/Playouts.razor

@ -115,7 +115,7 @@
if (_showFiller != value) if (_showFiller != value)
{ {
_showFiller = value; _showFiller = value;
if (_selectedPlayoutId != null) if (_detailTable != null && _selectedPlayoutId != null)
{ {
_detailTable.ReloadServerData(); _detailTable.ReloadServerData();
} }
@ -142,7 +142,10 @@
private async Task PlayoutSelected(PlayoutNameViewModel playout) private async Task PlayoutSelected(PlayoutNameViewModel playout)
{ {
_selectedPlayoutId = playout.PlayoutId; _selectedPlayoutId = playout.PlayoutId;
await _detailTable.ReloadServerData(); if (_detailTable != null)
{
await _detailTable.ReloadServerData();
}
} }
private async Task DeletePlayout(PlayoutNameViewModel playout) private async Task DeletePlayout(PlayoutNameViewModel playout)
@ -155,7 +158,10 @@
if (!result.Cancelled) if (!result.Cancelled)
{ {
await _mediator.Send(new DeletePlayout(playout.PlayoutId), _cts.Token); await _mediator.Send(new DeletePlayout(playout.PlayoutId), _cts.Token);
await _table.ReloadServerData(); if (_table != null)
{
await _table.ReloadServerData();
}
if (_selectedPlayoutId == playout.PlayoutId) if (_selectedPlayoutId == playout.PlayoutId)
{ {
_selectedPlayoutId = null; _selectedPlayoutId = null;
@ -166,7 +172,10 @@
private async Task ResetPlayout(PlayoutNameViewModel playout) private async Task ResetPlayout(PlayoutNameViewModel playout)
{ {
await _mediator.Send(new BuildPlayout(playout.PlayoutId, PlayoutBuildMode.Reset), _cts.Token); await _mediator.Send(new BuildPlayout(playout.PlayoutId, PlayoutBuildMode.Reset), _cts.Token);
await _table.ReloadServerData(); if (_table != null)
{
await _table.ReloadServerData();
}
if (_selectedPlayoutId == playout.PlayoutId) if (_selectedPlayoutId == playout.PlayoutId)
{ {
await PlayoutSelected(playout); await PlayoutSelected(playout);
@ -187,7 +196,10 @@
IDialogReference dialog = await _dialog.ShowAsync<SchedulePlayoutReset>("Schedule Playout Reset", parameters, options); IDialogReference dialog = await _dialog.ShowAsync<SchedulePlayoutReset>("Schedule Playout Reset", parameters, options);
await dialog.Result; await dialog.Result;
await _table.ReloadServerData(); if (_table != null)
{
await _table.ReloadServerData();
}
} }
private async Task<TableData<PlayoutNameViewModel>> ServerReload(TableState state) private async Task<TableData<PlayoutNameViewModel>> ServerReload(TableState state)

10
ErsatzTV/Pages/Schedules.razor

@ -113,7 +113,10 @@
private async Task ScheduleSelected(ProgramScheduleViewModel schedule) private async Task ScheduleSelected(ProgramScheduleViewModel schedule)
{ {
_selectedSchedule = schedule; _selectedSchedule = schedule;
await _detailTable.ReloadServerData(); if (_selectedSchedule != null && _detailTable != null)
{
await _detailTable.ReloadServerData();
}
} }
private async Task DeleteSchedule(ProgramScheduleViewModel programSchedule) private async Task DeleteSchedule(ProgramScheduleViewModel programSchedule)
@ -126,7 +129,10 @@
if (!result.Cancelled) if (!result.Cancelled)
{ {
await _mediator.Send(new DeleteProgramSchedule(programSchedule.Id), _cts.Token); await _mediator.Send(new DeleteProgramSchedule(programSchedule.Id), _cts.Token);
await _table.ReloadServerData(); if (_table != null)
{
await _table.ReloadServerData();
}
if (_selectedSchedule == programSchedule) if (_selectedSchedule == programSchedule)
{ {
_selectedSchedule = null; _selectedSchedule = null;

2
ErsatzTV/Pages/TraktLists.razor

@ -94,7 +94,7 @@
InvokeAsync(async () => InvokeAsync(async () =>
{ {
StateHasChanged(); StateHasChanged();
if (!_locker.IsTraktLocked()) if (_traktListsTable != null && !_locker.IsTraktLocked())
{ {
await _traktListsTable.ReloadServerData(); await _traktListsTable.ReloadServerData();
} }

Loading…
Cancel
Save