Browse Source

fix parsing show title from nfo (#1426)

pull/1428/head
Jason Dove 2 years ago committed by GitHub
parent
commit
b00a25bbee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 2
      ErsatzTV.Core.Tests/Fakes/FakeTelevisionRepository.cs
  3. 2
      ErsatzTV.Core/Interfaces/Repositories/ITelevisionRepository.cs
  4. 21
      ErsatzTV.Infrastructure/Data/Repositories/TelevisionRepository.cs
  5. 19
      ErsatzTV.Scanner.Tests/Core/Metadata/Nfo/ShowNfoReaderTests.cs
  6. 8
      ErsatzTV.Scanner/Core/Metadata/Nfo/ShowNfoReader.cs
  7. 2
      ErsatzTV.Scanner/Core/Metadata/TelevisionFolderScanner.cs

1
CHANGELOG.md

@ -26,6 +26,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Clean channel guide cache on startup (delete channels that no longer exist) - Clean channel guide cache on startup (delete channels that no longer exist)
- Fix Emby movie libraries so local file access is not required - Fix Emby movie libraries so local file access is not required
- Fix adding alternate schedule - Fix adding alternate schedule
- Fix parsing show title from NFO file that also contains season information
### Changed ### Changed
- Optimize transcoding session to only work ahead (at max speed) for 3 minutes before throttling to realtime - Optimize transcoding session to only work ahead (at max speed) for 3 minutes before throttling to realtime

2
ErsatzTV.Core.Tests/Fakes/FakeTelevisionRepository.cs

@ -38,7 +38,7 @@ public class FakeTelevisionRepository : ITelevisionRepository
public Task<List<EpisodeMetadata>> GetPagedEpisodes(int seasonId, int pageNumber, int pageSize) => public Task<List<EpisodeMetadata>> GetPagedEpisodes(int seasonId, int pageNumber, int pageSize) =>
throw new NotSupportedException(); throw new NotSupportedException();
public Task<Option<Show>> GetShowByMetadata(int libraryPathId, ShowMetadata metadata) => public Task<Option<Show>> GetShowByMetadata(int libraryPathId, ShowMetadata metadata, string showName) =>
throw new NotSupportedException(); throw new NotSupportedException();
public Task<Either<BaseError, MediaItemScanResult<Show>>> AddShow(int libraryPathId, ShowMetadata metadata) => public Task<Either<BaseError, MediaItemScanResult<Show>>> AddShow(int libraryPathId, ShowMetadata metadata) =>

2
ErsatzTV.Core/Interfaces/Repositories/ITelevisionRepository.cs

@ -21,7 +21,7 @@ public interface ITelevisionRepository
Task<List<Episode>> GetSeasonItems(int seasonId); Task<List<Episode>> GetSeasonItems(int seasonId);
Task<int> GetEpisodeCount(int seasonId); Task<int> GetEpisodeCount(int seasonId);
Task<List<EpisodeMetadata>> GetPagedEpisodes(int seasonId, int pageNumber, int pageSize); Task<List<EpisodeMetadata>> GetPagedEpisodes(int seasonId, int pageNumber, int pageSize);
Task<Option<Show>> GetShowByMetadata(int libraryPathId, ShowMetadata metadata); Task<Option<Show>> GetShowByMetadata(int libraryPathId, ShowMetadata metadata, string showFolder);
Task<Either<BaseError, MediaItemScanResult<Show>>> AddShow(int libraryPathId, ShowMetadata metadata); Task<Either<BaseError, MediaItemScanResult<Show>>> AddShow(int libraryPathId, ShowMetadata metadata);
Task<Either<BaseError, Season>> GetOrAddSeason(Show show, int libraryPathId, int seasonNumber); Task<Either<BaseError, Season>> GetOrAddSeason(Show show, int libraryPathId, int seasonNumber);
Task<Either<BaseError, Episode>> GetOrAddEpisode(Season season, LibraryPath libraryPath, string path); Task<Either<BaseError, Episode>> GetOrAddEpisode(Season season, LibraryPath libraryPath, string path);

21
ErsatzTV.Infrastructure/Data/Repositories/TelevisionRepository.cs

@ -228,7 +228,7 @@ public class TelevisionRepository : ITelevisionRepository
.ToListAsync(); .ToListAsync();
} }
public async Task<Option<Show>> GetShowByMetadata(int libraryPathId, ShowMetadata metadata) public async Task<Option<Show>> GetShowByMetadata(int libraryPathId, ShowMetadata metadata, string showFolder)
{ {
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(); await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
Option<int> maybeId = await dbContext.ShowMetadata Option<int> maybeId = await dbContext.ShowMetadata
@ -238,6 +238,25 @@ public class TelevisionRepository : ITelevisionRepository
.Map(Optional) .Map(Optional)
.MapT(sm => sm.ShowId); .MapT(sm => sm.ShowId);
if (maybeId.IsNone)
{
List<int> maybeShowIds = await dbContext.Episodes
.Where(
e => e.MediaVersions.Any(
mv => mv.MediaFiles.Any(
mf => EF.Functions.Like(
EF.Functions.Collate(mf.Path, TvContext.CaseInsensitiveCollation),
$"{showFolder}%"))))
.Map(e => e.Season.ShowId)
.Distinct()
.ToListAsync();
if (maybeShowIds.Count == 1)
{
maybeId = maybeShowIds.HeadOrNone();
}
}
return await maybeId.Match( return await maybeId.Match(
id => id =>
{ {

19
ErsatzTV.Scanner.Tests/Core/Metadata/Nfo/ShowNfoReaderTests.cs

@ -58,6 +58,7 @@ https://www.themoviedb.org/movie/11-star-wars"));
[Test] [Test]
public async Task FullSample_Should_Return_Nfo() public async Task FullSample_Should_Return_Nfo()
{ {
// nested "title" in "seasondetails" may cause the last encountered title to be used for the show
await using var stream = new MemoryStream( await using var stream = new MemoryStream(
Encoding.UTF8.GetBytes( Encoding.UTF8.GetBytes(
@"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes"" ?> @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes"" ?>
@ -132,6 +133,24 @@ https://www.themoviedb.org/movie/11-star-wars"));
<total>0.000000</total> <total>0.000000</total>
</resume> </resume>
<dateadded>2021-03-12 06:15:51</dateadded> <dateadded>2021-03-12 06:15:51</dateadded>
<seasons>
<seasondetails>
<season>-1</season>
<title>* All Seasons</title>
<locked>false</locked>
</seasondetails>
<seasondetails>
<season>1</season>
<tvdb>1824025</tvdb>
<locked>false</locked>
</seasondetails>
<seasondetails>
<season>2</season>
<title>Season 02</title>
<tvdb>1993428</tvdb>
<locked>false</locked>
</seasondetails>
</seasons>
</tvshow>")); </tvshow>"));
Either<BaseError, ShowNfo> result = await _showNfoReader.Read(stream); Either<BaseError, ShowNfo> result = await _showNfoReader.Read(stream);

8
ErsatzTV.Scanner/Core/Metadata/Nfo/ShowNfoReader.cs

@ -41,6 +41,7 @@ public class ShowNfoReader : NfoReader<ShowNfo>, IShowNfoReader
var settings = new XmlReaderSettings { Async = true, ConformanceLevel = ConformanceLevel.Fragment }; var settings = new XmlReaderSettings { Async = true, ConformanceLevel = ConformanceLevel.Fragment };
using var reader = XmlReader.Create(input, settings); using var reader = XmlReader.Create(input, settings);
var done = false; var done = false;
int showDepth = 0;
while (!done && await reader.ReadAsync()) while (!done && await reader.ReadAsync())
{ {
@ -51,9 +52,14 @@ public class ShowNfoReader : NfoReader<ShowNfo>, IShowNfoReader
{ {
case "tvshow": case "tvshow":
nfo = new ShowNfo(); nfo = new ShowNfo();
showDepth = reader.Depth;
break; break;
case "title": case "title":
await ReadStringContent(reader, nfo, (show, title) => show.Title = title); if (reader.Depth == showDepth + 1)
{
await ReadStringContent(reader, nfo, (show, title) => show.Title = title);
}
break; break;
case "year": case "year":
await ReadIntContent(reader, nfo, (show, year) => show.Year = year); await ReadIntContent(reader, nfo, (show, year) => show.Year = year);

2
ErsatzTV.Scanner/Core/Metadata/TelevisionFolderScanner.cs

@ -194,7 +194,7 @@ public class TelevisionFolderScanner : LocalFolderScanner, ITelevisionFolderScan
string showFolder) string showFolder)
{ {
ShowMetadata metadata = await _localMetadataProvider.GetMetadataForShow(showFolder); ShowMetadata metadata = await _localMetadataProvider.GetMetadataForShow(showFolder);
Option<Show> maybeShow = await _televisionRepository.GetShowByMetadata(libraryPathId, metadata); Option<Show> maybeShow = await _televisionRepository.GetShowByMetadata(libraryPathId, metadata, showFolder);
foreach (Show show in maybeShow) foreach (Show show in maybeShow)
{ {

Loading…
Cancel
Save