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/). @@ -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
- 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
- Support many more season folder names with local television libraries
## [0.7.4-beta] - 2023-02-12
### Added

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

@ -150,4 +150,26 @@ public class FallbackMetadataProviderTests @@ -150,4 +150,26 @@ public class FallbackMetadataProviderTests
metadata.Should().NotBeNull();
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; @@ -4,6 +4,7 @@ namespace ErsatzTV.Core.Interfaces.Metadata;
public interface IFallbackMetadataProvider
{
Option<int> GetSeasonNumberForFolder(string folder);
ShowMetadata GetFallbackMetadataForShow(string showFolder);
ArtistMetadata GetFallbackMetadataForArtist(string artistFolder);
List<EpisodeMetadata> GetFallbackMetadata(Episode episode);

28
ErsatzTV.Core/Metadata/FallbackMetadataProvider.cs

@ -5,12 +5,38 @@ using ErsatzTV.Core.Interfaces.Metadata; @@ -5,12 +5,38 @@ using ErsatzTV.Core.Interfaces.Metadata;
namespace ErsatzTV.Core.Metadata;
public class FallbackMetadataProvider : IFallbackMetadataProvider
public partial class FallbackMetadataProvider : IFallbackMetadataProvider
{
private static readonly Regex SeasonPattern = SeasonNumber();
private readonly IClient _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)
{
string fileName = Path.GetFileName(showFolder);

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

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