From e2f3e86fd624455f5f25a5664d72f1d8de1955b7 Mon Sep 17 00:00:00 2001 From: Jason Dove Date: Tue, 22 Jun 2021 18:55:44 -0500 Subject: [PATCH] fix adding jellyfin emby seasons episodes (#281) * fix adding new seasons and episodes with emby and jellyfin * update changelog * update dependencies --- CHANGELOG.md | 2 + .../Emby/EmbyTelevisionLibraryScanner.cs | 6 +- .../Repositories/IEmbyTelevisionRepository.cs | 4 +- .../IJellyfinTelevisionRepository.cs | 4 +- .../JellyfinTelevisionLibraryScanner.cs | 6 +- .../Repositories/EmbyTelevisionRepository.cs | 56 +++++++++++++------ .../JellyfinTelevisionRepository.cs | 56 +++++++++++++------ .../ErsatzTV.Infrastructure.csproj | 6 +- ErsatzTV/ErsatzTV.csproj | 6 +- 9 files changed, 94 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d0b5197e..12323deea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Fixed - Fix playback of transcoded 10-bit media items (pixel format `yuv420p10le`) on Nvidia hardware - Emby and Jellyfin scanners now respect library refresh interval setting +- Fix adding new seasons to existing Emby and Jellyfin shows +- Fix adding new episodes to existing Emby and Jellyfin seasons ## [0.0.47-prealpha] - 2021-06-15 ### Added diff --git a/ErsatzTV.Core/Emby/EmbyTelevisionLibraryScanner.cs b/ErsatzTV.Core/Emby/EmbyTelevisionLibraryScanner.cs index 5bfd0ce64..df39ac5f7 100644 --- a/ErsatzTV.Core/Emby/EmbyTelevisionLibraryScanner.cs +++ b/ErsatzTV.Core/Emby/EmbyTelevisionLibraryScanner.cs @@ -231,7 +231,6 @@ namespace ErsatzTV.Core.Emby }, async () => { - incoming.ShowId = show.Id; incoming.LibraryPathId = library.Paths.Head().Id; _logger.LogDebug( @@ -239,7 +238,7 @@ namespace ErsatzTV.Core.Emby show.ShowMetadata.Head().Title, incoming.SeasonMetadata.Head().Title); - await _televisionRepository.AddSeason(incoming); + await _televisionRepository.AddSeason(show, incoming); }); List existingEpisodes = @@ -364,7 +363,6 @@ namespace ErsatzTV.Core.Emby try { updateStatistics = true; - incoming.SeasonId = season.Id; incoming.LibraryPathId = library.Paths.Head().Id; _logger.LogDebug( @@ -373,7 +371,7 @@ namespace ErsatzTV.Core.Emby seasonName, incoming.EpisodeMetadata.HeadOrNone().Map(em => em.EpisodeNumber)); - if (await _televisionRepository.AddEpisode(incoming)) + if (await _televisionRepository.AddEpisode(season, incoming)) { await _searchIndex.AddItems(_searchRepository, new List { incoming }); } diff --git a/ErsatzTV.Core/Interfaces/Repositories/IEmbyTelevisionRepository.cs b/ErsatzTV.Core/Interfaces/Repositories/IEmbyTelevisionRepository.cs index 8f427f5d8..e2485ba87 100644 --- a/ErsatzTV.Core/Interfaces/Repositories/IEmbyTelevisionRepository.cs +++ b/ErsatzTV.Core/Interfaces/Repositories/IEmbyTelevisionRepository.cs @@ -13,9 +13,9 @@ namespace ErsatzTV.Core.Interfaces.Repositories Task> GetExistingEpisodes(EmbyLibrary library, string seasonItemId); Task AddShow(EmbyShow show); Task> Update(EmbyShow show); - Task AddSeason(EmbySeason season); + Task AddSeason(EmbyShow show, EmbySeason season); Task Update(EmbySeason season); - Task AddEpisode(EmbyEpisode episode); + Task AddEpisode(EmbySeason season, EmbyEpisode episode); Task> Update(EmbyEpisode episode); Task> RemoveMissingShows(EmbyLibrary library, List showIds); Task RemoveMissingSeasons(EmbyLibrary library, List seasonIds); diff --git a/ErsatzTV.Core/Interfaces/Repositories/IJellyfinTelevisionRepository.cs b/ErsatzTV.Core/Interfaces/Repositories/IJellyfinTelevisionRepository.cs index 7e7accdf8..8719a84ca 100644 --- a/ErsatzTV.Core/Interfaces/Repositories/IJellyfinTelevisionRepository.cs +++ b/ErsatzTV.Core/Interfaces/Repositories/IJellyfinTelevisionRepository.cs @@ -13,9 +13,9 @@ namespace ErsatzTV.Core.Interfaces.Repositories Task> GetExistingEpisodes(JellyfinLibrary library, string seasonItemId); Task AddShow(JellyfinShow show); Task> Update(JellyfinShow show); - Task AddSeason(JellyfinSeason season); + Task AddSeason(JellyfinShow show, JellyfinSeason season); Task Update(JellyfinSeason season); - Task AddEpisode(JellyfinEpisode episode); + Task AddEpisode(JellyfinSeason season, JellyfinEpisode episode); Task> Update(JellyfinEpisode episode); Task> RemoveMissingShows(JellyfinLibrary library, List showIds); Task RemoveMissingSeasons(JellyfinLibrary library, List seasonIds); diff --git a/ErsatzTV.Core/Jellyfin/JellyfinTelevisionLibraryScanner.cs b/ErsatzTV.Core/Jellyfin/JellyfinTelevisionLibraryScanner.cs index c1c26a431..7f7ca2a4f 100644 --- a/ErsatzTV.Core/Jellyfin/JellyfinTelevisionLibraryScanner.cs +++ b/ErsatzTV.Core/Jellyfin/JellyfinTelevisionLibraryScanner.cs @@ -231,7 +231,6 @@ namespace ErsatzTV.Core.Jellyfin }, async () => { - incoming.ShowId = show.Id; incoming.LibraryPathId = library.Paths.Head().Id; _logger.LogDebug( @@ -239,7 +238,7 @@ namespace ErsatzTV.Core.Jellyfin show.ShowMetadata.Head().Title, incoming.SeasonMetadata.Head().Title); - await _televisionRepository.AddSeason(incoming); + await _televisionRepository.AddSeason(show, incoming); }); List existingEpisodes = @@ -365,7 +364,6 @@ namespace ErsatzTV.Core.Jellyfin try { updateStatistics = true; - incoming.SeasonId = season.Id; incoming.LibraryPathId = library.Paths.Head().Id; _logger.LogDebug( @@ -374,7 +372,7 @@ namespace ErsatzTV.Core.Jellyfin seasonName, incoming.EpisodeMetadata.HeadOrNone().Map(em => em.EpisodeNumber)); - if (await _televisionRepository.AddEpisode(incoming)) + if (await _televisionRepository.AddEpisode(season, incoming)) { await _searchIndex.AddItems(_searchRepository, new List { incoming }); } diff --git a/ErsatzTV.Infrastructure/Data/Repositories/EmbyTelevisionRepository.cs b/ErsatzTV.Infrastructure/Data/Repositories/EmbyTelevisionRepository.cs index 69c6f479f..302fd9075 100644 --- a/ErsatzTV.Infrastructure/Data/Repositories/EmbyTelevisionRepository.cs +++ b/ErsatzTV.Infrastructure/Data/Repositories/EmbyTelevisionRepository.cs @@ -242,18 +242,29 @@ namespace ErsatzTV.Infrastructure.Data.Repositories return maybeExisting; } - public async Task AddSeason(EmbySeason season) + public async Task AddSeason(EmbyShow show, EmbySeason season) { - await using TvContext dbContext = _dbContextFactory.CreateDbContext(); - await dbContext.AddAsync(season); - if (await dbContext.SaveChangesAsync() <= 0) + try + { + season.ShowId = await _dbConnection.ExecuteScalarAsync( + @"SELECT Id FROM EmbyShow WHERE ItemId = @ItemId", + new { show.ItemId }); + + await using TvContext dbContext = _dbContextFactory.CreateDbContext(); + await dbContext.AddAsync(season); + if (await dbContext.SaveChangesAsync() <= 0) + { + return false; + } + + await dbContext.Entry(season).Reference(m => m.LibraryPath).LoadAsync(); + await dbContext.Entry(season.LibraryPath).Reference(lp => lp.Library).LoadAsync(); + return true; + } + catch (Exception) { return false; } - - await dbContext.Entry(season).Reference(m => m.LibraryPath).LoadAsync(); - await dbContext.Entry(season.LibraryPath).Reference(lp => lp.Library).LoadAsync(); - return true; } public async Task Update(EmbySeason season) @@ -368,19 +379,30 @@ namespace ErsatzTV.Infrastructure.Data.Repositories return Unit.Default; } - public async Task AddEpisode(EmbyEpisode episode) + public async Task AddEpisode(EmbySeason season, EmbyEpisode episode) { - await using TvContext dbContext = _dbContextFactory.CreateDbContext(); - await dbContext.AddAsync(episode); - if (await dbContext.SaveChangesAsync() <= 0) + try + { + episode.SeasonId = await _dbConnection.ExecuteScalarAsync( + @"SELECT Id FROM EmbySeason WHERE ItemId = @ItemId", + new { season.ItemId }); + + await using TvContext dbContext = _dbContextFactory.CreateDbContext(); + await dbContext.AddAsync(episode); + if (await dbContext.SaveChangesAsync() <= 0) + { + return false; + } + + await dbContext.Entry(episode).Reference(m => m.LibraryPath).LoadAsync(); + await dbContext.Entry(episode.LibraryPath).Reference(lp => lp.Library).LoadAsync(); + await dbContext.Entry(episode).Reference(e => e.Season).LoadAsync(); + return true; + } + catch (Exception) { return false; } - - await dbContext.Entry(episode).Reference(m => m.LibraryPath).LoadAsync(); - await dbContext.Entry(episode.LibraryPath).Reference(lp => lp.Library).LoadAsync(); - await dbContext.Entry(episode).Reference(e => e.Season).LoadAsync(); - return true; } public async Task> Update(EmbyEpisode episode) diff --git a/ErsatzTV.Infrastructure/Data/Repositories/JellyfinTelevisionRepository.cs b/ErsatzTV.Infrastructure/Data/Repositories/JellyfinTelevisionRepository.cs index 77797ee1f..6d14ba09a 100644 --- a/ErsatzTV.Infrastructure/Data/Repositories/JellyfinTelevisionRepository.cs +++ b/ErsatzTV.Infrastructure/Data/Repositories/JellyfinTelevisionRepository.cs @@ -259,18 +259,29 @@ namespace ErsatzTV.Infrastructure.Data.Repositories return maybeExisting; } - public async Task AddSeason(JellyfinSeason season) + public async Task AddSeason(JellyfinShow show, JellyfinSeason season) { - await using TvContext dbContext = _dbContextFactory.CreateDbContext(); - await dbContext.AddAsync(season); - if (await dbContext.SaveChangesAsync() <= 0) + try + { + season.ShowId = await _dbConnection.ExecuteScalarAsync( + @"SELECT Id FROM JellyfinShow WHERE ItemId = @ItemId", + new { show.ItemId }); + + await using TvContext dbContext = _dbContextFactory.CreateDbContext(); + await dbContext.AddAsync(season); + if (await dbContext.SaveChangesAsync() <= 0) + { + return false; + } + + await dbContext.Entry(season).Reference(m => m.LibraryPath).LoadAsync(); + await dbContext.Entry(season.LibraryPath).Reference(lp => lp.Library).LoadAsync(); + return true; + } + catch (Exception) { return false; } - - await dbContext.Entry(season).Reference(m => m.LibraryPath).LoadAsync(); - await dbContext.Entry(season.LibraryPath).Reference(lp => lp.Library).LoadAsync(); - return true; } public async Task Update(JellyfinSeason season) @@ -368,19 +379,30 @@ namespace ErsatzTV.Infrastructure.Data.Repositories return Unit.Default; } - public async Task AddEpisode(JellyfinEpisode episode) + public async Task AddEpisode(JellyfinSeason season, JellyfinEpisode episode) { - await using TvContext dbContext = _dbContextFactory.CreateDbContext(); - await dbContext.AddAsync(episode); - if (await dbContext.SaveChangesAsync() <= 0) + try + { + episode.SeasonId = await _dbConnection.ExecuteScalarAsync( + @"SELECT Id FROM JellyfinSeason WHERE ItemId = @ItemId", + new { season.ItemId }); + + await using TvContext dbContext = _dbContextFactory.CreateDbContext(); + await dbContext.AddAsync(episode); + if (await dbContext.SaveChangesAsync() <= 0) + { + return false; + } + + await dbContext.Entry(episode).Reference(m => m.LibraryPath).LoadAsync(); + await dbContext.Entry(episode.LibraryPath).Reference(lp => lp.Library).LoadAsync(); + await dbContext.Entry(episode).Reference(e => e.Season).LoadAsync(); + return true; + } + catch (Exception) { return false; } - - await dbContext.Entry(episode).Reference(m => m.LibraryPath).LoadAsync(); - await dbContext.Entry(episode.LibraryPath).Reference(lp => lp.Library).LoadAsync(); - await dbContext.Entry(episode).Reference(e => e.Season).LoadAsync(); - return true; } public async Task> Update(JellyfinEpisode episode) diff --git a/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj b/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj index 049ae0e24..0f458275c 100644 --- a/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj +++ b/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj @@ -16,12 +16,12 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/ErsatzTV/ErsatzTV.csproj b/ErsatzTV/ErsatzTV.csproj index add0644af..fa1d9c13a 100644 --- a/ErsatzTV/ErsatzTV.csproj +++ b/ErsatzTV/ErsatzTV.csproj @@ -19,14 +19,14 @@ - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive