Browse Source

support more local season folder names (#1191)

pull/1192/head
Jason Dove 3 years ago committed by GitHub
parent
commit
b032e70d7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 22
      ErsatzTV.Core.Tests/Metadata/FallbackMetadataProviderTests.cs
  3. 1
      ErsatzTV.Core/Interfaces/Metadata/IFallbackMetadataProvider.cs
  4. 28
      ErsatzTV.Core/Metadata/FallbackMetadataProvider.cs
  5. 20
      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/).
- Search queries no longer remove duplicate results as this was causing incorrect behavior - Search queries no longer remove duplicate results as this was causing incorrect behavior
- Prioritize audio streams that are flagged as "default" over number of audio channels - Prioritize audio streams that are flagged as "default" over number of audio channels
- For example, a video with a stereo commentary track and a mono "default" track will now prefer the "default" track - For example, a video with a stereo commentary track and a mono "default" track will now prefer the "default" track
- Support many more season folder names with local television libraries
## [0.7.4-beta] - 2023-02-12 ## [0.7.4-beta] - 2023-02-12
### Added ### Added

22
ErsatzTV.Core.Tests/Metadata/FallbackMetadataProviderTests.cs

@ -150,4 +150,26 @@ public class FallbackMetadataProviderTests
metadata.Should().NotBeNull(); metadata.Should().NotBeNull();
metadata.Title.Should().Be(expectedTitle); metadata.Title.Should().Be(expectedTitle);
} }
[Test]
[TestCase(@"/Whatever/American Dad! S01", 1)]
[TestCase(@"/Whatever/Season 2", 2)]
[TestCase(@"/Whatever/Season 02", 2)]
[TestCase(@"/Whatever/Seinfeld/S02", 2)]
[TestCase(@"/Whatever/Seinfeld/2", 2)]
[TestCase(@"/Whatever/Season 2009", 2009)]
[TestCase(@"/Whatever/Season1", 1)]
[TestCase(@"/Bojack Horseman/Bojack.Horseman.S04.1080p.WEB.x264-ABBA", 4)]
[TestCase(@"/Whatever/Season 7 (2016)", 7)]
[TestCase(@"/Whatever/Season (8)", null)]
[TestCase(@"/Whatever/s06e05", null)]
[TestCase(@"/Whatever/The.Legend.of.Condor.Heroes.2017.V2.web-dl.1080p.h264.aac-hdctv", null)]
[TestCase(@"/Whatever/extras", null)]
[TestCase(@"/Whatever/specials", 0)]
[TestCase(@"Stargate SG1 S08", 8)]
public void GetSeasonNumberForFolder_ShouldHandleVariousFormats(string folder, int? season)
{
Option<int> actual = _fallbackMetadataProvider.GetSeasonNumberForFolder(folder);
actual.Should<Option<int>>().Be(Optional(season));
}
} }

1
ErsatzTV.Core/Interfaces/Metadata/IFallbackMetadataProvider.cs

@ -4,6 +4,7 @@ namespace ErsatzTV.Core.Interfaces.Metadata;
public interface IFallbackMetadataProvider public interface IFallbackMetadataProvider
{ {
Option<int> GetSeasonNumberForFolder(string folder);
ShowMetadata GetFallbackMetadataForShow(string showFolder); ShowMetadata GetFallbackMetadataForShow(string showFolder);
ArtistMetadata GetFallbackMetadataForArtist(string artistFolder); ArtistMetadata GetFallbackMetadataForArtist(string artistFolder);
List<EpisodeMetadata> GetFallbackMetadata(Episode episode); List<EpisodeMetadata> GetFallbackMetadata(Episode episode);

28
ErsatzTV.Core/Metadata/FallbackMetadataProvider.cs

@ -5,12 +5,38 @@ using ErsatzTV.Core.Interfaces.Metadata;
namespace ErsatzTV.Core.Metadata; namespace ErsatzTV.Core.Metadata;
public class FallbackMetadataProvider : IFallbackMetadataProvider public partial class FallbackMetadataProvider : IFallbackMetadataProvider
{ {
private static readonly Regex SeasonPattern = SeasonNumber();
private readonly IClient _client; private readonly IClient _client;
public FallbackMetadataProvider(IClient client) => _client = client; public FallbackMetadataProvider(IClient client) => _client = client;
public Option<int> GetSeasonNumberForFolder(string folder)
{
string folderName = Path.GetFileName(folder) ?? folder;
if (int.TryParse(folderName, out int seasonNumber))
{
return seasonNumber;
}
Match match = SeasonPattern.Match(folderName);
if (match.Success && int.TryParse(match.Groups[1].Value, out seasonNumber))
{
return seasonNumber;
}
if (folder.EndsWith("specials", StringComparison.OrdinalIgnoreCase))
{
return 0;
}
return None;
}
[GeneratedRegex(@"s(?:eason)?\s?(\d+)(?![e\d])", RegexOptions.IgnoreCase)]
private static partial Regex SeasonNumber();
public ShowMetadata GetFallbackMetadataForShow(string showFolder) public ShowMetadata GetFallbackMetadataForShow(string showFolder)
{ {
string fileName = Path.GetFileName(showFolder); string fileName = Path.GetFileName(showFolder);

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

@ -17,6 +17,7 @@ namespace ErsatzTV.Scanner.Core.Metadata;
public class TelevisionFolderScanner : LocalFolderScanner, ITelevisionFolderScanner public class TelevisionFolderScanner : LocalFolderScanner, ITelevisionFolderScanner
{ {
private readonly IClient _client; private readonly IClient _client;
private readonly IFallbackMetadataProvider _fallbackMetadataProvider;
private readonly ILibraryRepository _libraryRepository; private readonly ILibraryRepository _libraryRepository;
private readonly ILocalFileSystem _localFileSystem; private readonly ILocalFileSystem _localFileSystem;
private readonly ILocalMetadataProvider _localMetadataProvider; private readonly ILocalMetadataProvider _localMetadataProvider;
@ -40,6 +41,7 @@ public class TelevisionFolderScanner : LocalFolderScanner, ITelevisionFolderScan
IFFmpegPngService ffmpegPngService, IFFmpegPngService ffmpegPngService,
ITempFilePool tempFilePool, ITempFilePool tempFilePool,
IClient client, IClient client,
IFallbackMetadataProvider fallbackMetadataProvider,
ILogger<TelevisionFolderScanner> logger) : base( ILogger<TelevisionFolderScanner> logger) : base(
localFileSystem, localFileSystem,
localStatisticsProvider, localStatisticsProvider,
@ -59,6 +61,7 @@ public class TelevisionFolderScanner : LocalFolderScanner, ITelevisionFolderScan
_libraryRepository = libraryRepository; _libraryRepository = libraryRepository;
_mediator = mediator; _mediator = mediator;
_client = client; _client = client;
_fallbackMetadataProvider = fallbackMetadataProvider;
_logger = logger; _logger = logger;
} }
@ -228,7 +231,7 @@ public class TelevisionFolderScanner : LocalFolderScanner, ITelevisionFolderScan
continue; continue;
} }
Option<int> maybeSeasonNumber = SeasonNumberForFolder(seasonFolder); Option<int> maybeSeasonNumber = _fallbackMetadataProvider.GetSeasonNumberForFolder(seasonFolder);
foreach (int seasonNumber in maybeSeasonNumber) foreach (int seasonNumber in maybeSeasonNumber)
{ {
Either<BaseError, Season> maybeSeason = await _televisionRepository Either<BaseError, Season> maybeSeason = await _televisionRepository
@ -579,19 +582,4 @@ public class TelevisionFolderScanner : LocalFolderScanner, ITelevisionFolderScan
.Filter(f => _localFileSystem.FileExists(f)) .Filter(f => _localFileSystem.FileExists(f))
.HeadOrNone(); .HeadOrNone();
} }
private static Option<int> SeasonNumberForFolder(string folder)
{
if (int.TryParse(folder.Split(" ").Last(), out int seasonNumber))
{
return seasonNumber;
}
if (folder.EndsWith("specials", StringComparison.OrdinalIgnoreCase))
{
return 0;
}
return None;
}
} }

Loading…
Cancel
Save