@ -10,15 +10,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
@@ -10,15 +10,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Fix ability of health check crash to crash home page
- Remove and ignore Season 0/Specials from Plex shows that have no specials
- Automatically delete and rebuild the search index on startup if it has become corrupt
- Automatically scan Jellyfin and Emby libraries on startup and periodically
- Properly remove un-synchronized Plex, Jellyfin and Emby items from the database and search index
- Fix synchronizing movies within a collection from Jellyfin
### Changed
- Update Plex, Jellyfin and Emby movie and show library scanners to share a significant amount of code
- This should help maintain feature parity going forward
- Jellyfin and Emby movie and show library scanners now support the `unavailable` media state
- Optimize search-index rebuilding to complete 100x faster
- **No longer use network paths to source content from Jellyfin and Emby**
- **If you previously used path replacements to convert network paths to local paths, you should remove them**
### Added
- Add `unavailable` state for Emby movie libraries
- Add `unavailable` state for Jellyfin and Emby movie and show libraries
- Add `height` and `width` to search index for all videos
- Add `season_number` and `episode_number` to search index for all episodes
@ -32,7 +32,7 @@ public class CreateLocalLibraryHandler : LocalLibraryHandlerBase,
@@ -32,7 +32,7 @@ public class CreateLocalLibraryHandler : LocalLibraryHandlerBase,
@ -60,6 +60,22 @@ public class FakeTelevisionRepository : ITelevisionRepository
@@ -60,6 +60,22 @@ public class FakeTelevisionRepository : ITelevisionRepository
@ -73,14 +89,6 @@ public class FakeTelevisionRepository : ITelevisionRepository
@@ -73,14 +89,6 @@ public class FakeTelevisionRepository : ITelevisionRepository
@ -90,13 +98,6 @@ public class FakeTelevisionRepository : ITelevisionRepository
@@ -90,13 +98,6 @@ public class FakeTelevisionRepository : ITelevisionRepository
@ -31,7 +31,39 @@ public class EmbyPathReplacementService : IEmbyPathReplacementService
@@ -31,7 +31,39 @@ public class EmbyPathReplacementService : IEmbyPathReplacementService
@ -50,11 +82,11 @@ public class EmbyPathReplacementService : IEmbyPathReplacementService
@@ -50,11 +82,11 @@ public class EmbyPathReplacementService : IEmbyPathReplacementService
@ -73,10 +105,4 @@ public class EmbyPathReplacementService : IEmbyPathReplacementService
@@ -73,10 +105,4 @@ public class EmbyPathReplacementService : IEmbyPathReplacementService
@ -108,6 +108,7 @@ public class EmbyTelevisionLibraryScanner : MediaServerTelevisionLibraryScanner<
@@ -108,6 +108,7 @@ public class EmbyTelevisionLibraryScanner : MediaServerTelevisionLibraryScanner<
@ -34,7 +34,36 @@ public class JellyfinPathReplacementService : IJellyfinPathReplacementService
@@ -34,7 +34,36 @@ public class JellyfinPathReplacementService : IJellyfinPathReplacementService
@ -55,13 +84,11 @@ public class JellyfinPathReplacementService : IJellyfinPathReplacementService
@@ -55,13 +84,11 @@ public class JellyfinPathReplacementService : IJellyfinPathReplacementService
@ -80,10 +107,4 @@ public class JellyfinPathReplacementService : IJellyfinPathReplacementService
@@ -80,10 +107,4 @@ public class JellyfinPathReplacementService : IJellyfinPathReplacementService
@ -111,7 +111,7 @@ public class JellyfinTelevisionLibraryScanner : MediaServerTelevisionLibraryScan
@@ -111,7 +111,7 @@ public class JellyfinTelevisionLibraryScanner : MediaServerTelevisionLibraryScan
@ -209,18 +209,18 @@ public abstract class MediaServerMovieLibraryScanner<TConnectionParameters, TLib
@@ -209,18 +209,18 @@ public abstract class MediaServerMovieLibraryScanner<TConnectionParameters, TLib
@ -277,7 +277,7 @@ public abstract class MediaServerMovieLibraryScanner<TConnectionParameters, TLib
@@ -277,7 +277,7 @@ public abstract class MediaServerMovieLibraryScanner<TConnectionParameters, TLib
@ -439,18 +439,18 @@ public abstract class MediaServerTelevisionLibraryScanner<TConnectionParameters,
@@ -439,18 +439,18 @@ public abstract class MediaServerTelevisionLibraryScanner<TConnectionParameters,
@ -559,7 +559,7 @@ public abstract class MediaServerTelevisionLibraryScanner<TConnectionParameters,
@@ -559,7 +559,7 @@ public abstract class MediaServerTelevisionLibraryScanner<TConnectionParameters,
@ -657,6 +657,7 @@ public class EmbyTelevisionRepository : IEmbyTelevisionRepository
@@ -657,6 +657,7 @@ public class EmbyTelevisionRepository : IEmbyTelevisionRepository
try
{
// blank out etag for initial save in case other updates fail
stringetag=show.Etag;
show.Etag=string.Empty;
show.LibraryPathId=library.Paths.Head().Id;
@ -664,6 +665,9 @@ public class EmbyTelevisionRepository : IEmbyTelevisionRepository
@@ -664,6 +665,9 @@ public class EmbyTelevisionRepository : IEmbyTelevisionRepository
@ -682,6 +686,7 @@ public class EmbyTelevisionRepository : IEmbyTelevisionRepository
@@ -682,6 +686,7 @@ public class EmbyTelevisionRepository : IEmbyTelevisionRepository
try
{
// blank out etag for initial save in case other updates fail
stringetag=season.Etag;
season.Etag=string.Empty;
season.LibraryPathId=library.Paths.Head().Id;
@ -689,6 +694,9 @@ public class EmbyTelevisionRepository : IEmbyTelevisionRepository
@@ -689,6 +694,9 @@ public class EmbyTelevisionRepository : IEmbyTelevisionRepository
@ -707,6 +715,7 @@ public class EmbyTelevisionRepository : IEmbyTelevisionRepository
@@ -707,6 +715,7 @@ public class EmbyTelevisionRepository : IEmbyTelevisionRepository
try
{
// blank out etag for initial save in case other updates fail
stringetag=episode.Etag;
episode.Etag=string.Empty;
episode.LibraryPathId=library.Paths.Head().Id;
@ -714,6 +723,9 @@ public class EmbyTelevisionRepository : IEmbyTelevisionRepository
@@ -714,6 +723,9 @@ public class EmbyTelevisionRepository : IEmbyTelevisionRepository
@ -334,6 +334,7 @@ public class JellyfinMovieRepository : IJellyfinMovieRepository
@@ -334,6 +334,7 @@ public class JellyfinMovieRepository : IJellyfinMovieRepository
try
{
// blank out etag for initial save in case other updates fail
stringetag=movie.Etag;
movie.Etag=string.Empty;
movie.LibraryPathId=library.Paths.Head().Id;
@ -341,6 +342,9 @@ public class JellyfinMovieRepository : IJellyfinMovieRepository
@@ -341,6 +342,9 @@ public class JellyfinMovieRepository : IJellyfinMovieRepository
@ -661,6 +661,7 @@ public class JellyfinTelevisionRepository : IJellyfinTelevisionRepository
@@ -661,6 +661,7 @@ public class JellyfinTelevisionRepository : IJellyfinTelevisionRepository
try
{
// blank out etag for initial save in case other updates fail
stringetag=show.Etag;
show.Etag=string.Empty;
show.LibraryPathId=library.Paths.Head().Id;
@ -668,6 +669,9 @@ public class JellyfinTelevisionRepository : IJellyfinTelevisionRepository
@@ -668,6 +669,9 @@ public class JellyfinTelevisionRepository : IJellyfinTelevisionRepository
@ -686,6 +690,7 @@ public class JellyfinTelevisionRepository : IJellyfinTelevisionRepository
@@ -686,6 +690,7 @@ public class JellyfinTelevisionRepository : IJellyfinTelevisionRepository
try
{
// blank out etag for initial save in case other updates fail
stringetag=season.Etag;
season.Etag=string.Empty;
season.LibraryPathId=library.Paths.Head().Id;
@ -693,6 +698,9 @@ public class JellyfinTelevisionRepository : IJellyfinTelevisionRepository
@@ -693,6 +698,9 @@ public class JellyfinTelevisionRepository : IJellyfinTelevisionRepository
@ -711,6 +719,7 @@ public class JellyfinTelevisionRepository : IJellyfinTelevisionRepository
@@ -711,6 +719,7 @@ public class JellyfinTelevisionRepository : IJellyfinTelevisionRepository
try
{
// blank out etag for initial save in case other updates fail
stringetag=episode.Etag;
episode.Etag=string.Empty;
episode.LibraryPathId=library.Paths.Head().Id;
@ -718,6 +727,9 @@ public class JellyfinTelevisionRepository : IJellyfinTelevisionRepository
@@ -718,6 +727,9 @@ public class JellyfinTelevisionRepository : IJellyfinTelevisionRepository
@ -159,27 +163,51 @@ public class MediaSourceRepository : IMediaSourceRepository
@@ -159,27 +163,51 @@ public class MediaSourceRepository : IMediaSourceRepository
@ -188,27 +216,51 @@ public class MediaSourceRepository : IMediaSourceRepository
@@ -188,27 +216,51 @@ public class MediaSourceRepository : IMediaSourceRepository
@ -259,14 +311,16 @@ public class MediaSourceRepository : IMediaSourceRepository
@@ -259,14 +311,16 @@ public class MediaSourceRepository : IMediaSourceRepository
@ -292,83 +346,30 @@ public class MediaSourceRepository : IMediaSourceRepository
@@ -292,83 +346,30 @@ public class MediaSourceRepository : IMediaSourceRepository
@ -447,6 +448,7 @@ public class MediaSourceRepository : IMediaSourceRepository
@@ -447,6 +448,7 @@ public class MediaSourceRepository : IMediaSourceRepository
@ -473,83 +475,31 @@ public class MediaSourceRepository : IMediaSourceRepository
@@ -473,83 +475,31 @@ public class MediaSourceRepository : IMediaSourceRepository
@ -557,6 +507,8 @@ public class MediaSourceRepository : IMediaSourceRepository
@@ -557,6 +507,8 @@ public class MediaSourceRepository : IMediaSourceRepository
@ -654,24 +606,14 @@ public class MediaSourceRepository : IMediaSourceRepository
@@ -654,24 +606,14 @@ public class MediaSourceRepository : IMediaSourceRepository
@ -742,10 +684,9 @@ public class MediaSourceRepository : IMediaSourceRepository
@@ -742,10 +684,9 @@ public class MediaSourceRepository : IMediaSourceRepository
@ -771,9 +712,9 @@ public class MediaSourceRepository : IMediaSourceRepository
@@ -771,9 +712,9 @@ public class MediaSourceRepository : IMediaSourceRepository
@ -858,24 +799,14 @@ public class MediaSourceRepository : IMediaSourceRepository
@@ -858,24 +799,14 @@ public class MediaSourceRepository : IMediaSourceRepository
@ -890,122 +821,30 @@ public class MediaSourceRepository : IMediaSourceRepository
@@ -890,122 +821,30 @@ public class MediaSourceRepository : IMediaSourceRepository
@ -301,6 +301,7 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository
@@ -301,6 +301,7 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository
try
{
// blank out etag for initial save in case stats/metadata/etc updates fail
stringetag=item.Etag;
item.Etag=string.Empty;
item.LibraryPathId=library.Paths.Head().Id;
@ -308,6 +309,9 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository
@@ -308,6 +309,9 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository
@ -326,6 +330,7 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository
@@ -326,6 +330,7 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository
try
{
// blank out etag for initial save in case stats/metadata/etc updates fail
stringetag=item.Etag;
item.Etag=string.Empty;
item.LibraryPathId=library.Paths.Head().Id;
@ -333,6 +338,9 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository
@@ -333,6 +338,9 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository
@ -356,6 +364,7 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository
@@ -356,6 +364,7 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository
}
// blank out etag for initial save in case stats/metadata/etc updates fail
stringetag=item.Etag;
item.Etag=string.Empty;
item.LibraryPathId=library.Paths.Head().Id;
@ -372,6 +381,9 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository
@@ -372,6 +381,9 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository