Browse Source

add tv show metadata and posters

pull/25/head
Jason Dove 6 years ago
parent
commit
7a37fc8d7a
  1. 223
      ErsatzTV.Core.Tests/Metadata/TestMediaScannerTests.cs
  2. 15
      ErsatzTV.Core/Metadata/TestMediaScanner.cs

223
ErsatzTV.Core.Tests/Metadata/TestMediaScannerTests.cs

@ -9,13 +9,15 @@ namespace ErsatzTV.Core.Tests.Metadata
{ {
[TestFixture] [TestFixture]
public class TestMediaScannerTests public class TestMediaScannerTests
{
[TestFixture]
public class NewMovieTests
{ {
private readonly TestMediaScanner _scanner = new(); private readonly TestMediaScanner _scanner = new();
[Test] [Test]
public void NewMovieFile_WithoutNfo_WithoutPoster() public void WithoutNfo_WithoutPoster()
{ {
// new movie file without nfo and without poster should have statistics and fallback metadata
var movieFileName = "/movies/test (2021)/test (2021).mkv"; var movieFileName = "/movies/test (2021)/test (2021).mkv";
string[] fileNames = { movieFileName }; string[] fileNames = { movieFileName };
@ -35,11 +37,10 @@ namespace ErsatzTV.Core.Tests.Metadata
} }
[Test] [Test]
public void NewMovieFile_WithNfo_WithoutPoster( public void WithNfo_WithoutPoster(
[Values("test (2021).nfo", "movie.nfo")] [Values("test (2021).nfo", "movie.nfo")]
string nfoFile) string nfoFile)
{ {
// new movie file without nfo and without poster should have statistics and fallback metadata
var movieFileName = "/movies/test (2021)/test (2021).mkv"; var movieFileName = "/movies/test (2021)/test (2021).mkv";
var nfoFileName = $"/movies/test (2021)/{nfoFile}"; var nfoFileName = $"/movies/test (2021)/{nfoFile}";
string[] fileNames = { movieFileName, nfoFileName }; string[] fileNames = { movieFileName, nfoFileName };
@ -60,13 +61,12 @@ namespace ErsatzTV.Core.Tests.Metadata
} }
[Test] [Test]
public void NewMovieFile_WithoutNfo_WithPoster( public void WithoutNfo_WithPoster(
[Values("", "test (2021)-")] [Values("", "test (2021)-")]
string basePosterName, string basePosterName,
[Values("jpg", "jpeg", "png", "gif", "tbn")] [Values("jpg", "jpeg", "png", "gif", "tbn")]
string posterExtension) string posterExtension)
{ {
// new movie file without nfo and without poster should have statistics and fallback metadata
var movieFileName = "/movies/test (2021)/test (2021).mkv"; var movieFileName = "/movies/test (2021)/test (2021).mkv";
var posterFileName = $"/movies/test (2021)/{basePosterName}poster.{posterExtension}"; var posterFileName = $"/movies/test (2021)/{basePosterName}poster.{posterExtension}";
@ -89,7 +89,7 @@ namespace ErsatzTV.Core.Tests.Metadata
} }
[Test] [Test]
public void NewMovieFile_WithNfo_WithPoster( public void WithNfo_WithPoster(
[Values("test (2021).nfo", "movie.nfo")] [Values("test (2021).nfo", "movie.nfo")]
string nfoFile, string nfoFile,
[Values("", "test (2021)-")] [Values("", "test (2021)-")]
@ -97,7 +97,6 @@ namespace ErsatzTV.Core.Tests.Metadata
[Values("jpg", "jpeg", "png", "gif", "tbn")] [Values("jpg", "jpeg", "png", "gif", "tbn")]
string posterExtension) string posterExtension)
{ {
// new movie file without nfo and without poster should have statistics and fallback metadata
var movieFileName = "/movies/test (2021)/test (2021).mkv"; var movieFileName = "/movies/test (2021)/test (2021).mkv";
var nfoFileName = $"/movies/test (2021)/{nfoFile}"; var nfoFileName = $"/movies/test (2021)/{nfoFile}";
var posterFileName = $"/movies/test (2021)/{basePosterName}poster.{posterExtension}"; var posterFileName = $"/movies/test (2021)/{basePosterName}poster.{posterExtension}";
@ -119,14 +118,19 @@ namespace ErsatzTV.Core.Tests.Metadata
new ItemScanningPlan(posterFileName, ScanningAction.Poster), new ItemScanningPlan(posterFileName, ScanningAction.Poster),
new ItemScanningPlan(movieFileName, ScanningAction.Collections)); new ItemScanningPlan(movieFileName, ScanningAction.Collections));
} }
}
[TestFixture]
public class ExistingMovieTests
{
private readonly TestMediaScanner _scanner = new();
// TODO: mtime should affect this // TODO: mtime should affect this
[Test] [Test]
public void ExistingMovieFile_WithNewNfo_WithoutPoster( public void WithNewNfo_WithoutPoster(
[Values("test (2021).nfo", "movie.nfo")] [Values("test (2021).nfo", "movie.nfo")]
string nfoFile) string nfoFile)
{ {
// new movie file without nfo and without poster should have statistics and fallback metadata
var movieMediaItem = new MediaItem var movieMediaItem = new MediaItem
{ {
Metadata = new MediaMetadata { Source = MetadataSource.Fallback }, Metadata = new MediaMetadata { Source = MetadataSource.Fallback },
@ -151,13 +155,12 @@ namespace ErsatzTV.Core.Tests.Metadata
} }
[Test] [Test]
public void ExistingMovieFile_WithoutNfo_WithNewPoster( public void WithoutNfo_WithNewPoster(
[Values("", "test (2021)-")] [Values("", "test (2021)-")]
string basePosterName, string basePosterName,
[Values("jpg", "jpeg", "png", "gif", "tbn")] [Values("jpg", "jpeg", "png", "gif", "tbn")]
string posterExtension) string posterExtension)
{ {
// new movie file without nfo and without poster should have statistics and fallback metadata
var movieMediaItem = new MediaItem var movieMediaItem = new MediaItem
{ {
Metadata = new MediaMetadata { Source = MetadataSource.Fallback }, Metadata = new MediaMetadata { Source = MetadataSource.Fallback },
@ -181,7 +184,7 @@ namespace ErsatzTV.Core.Tests.Metadata
} }
[Test] [Test]
public void ExistingMovieFile_WithNewNfo_WithNewPoster( public void WithNewNfo_WithNewPoster(
[Values("test (2021).nfo", "movie.nfo")] [Values("test (2021).nfo", "movie.nfo")]
string nfoFile, string nfoFile,
[Values("", "test (2021)-")] [Values("", "test (2021)-")]
@ -189,7 +192,6 @@ namespace ErsatzTV.Core.Tests.Metadata
[Values("jpg", "jpeg", "png", "gif", "tbn")] [Values("jpg", "jpeg", "png", "gif", "tbn")]
string posterExtension) string posterExtension)
{ {
// new movie file without nfo and without poster should have statistics and fallback metadata
var movieMediaItem = new MediaItem var movieMediaItem = new MediaItem
{ {
Metadata = new MediaMetadata { Source = MetadataSource.Fallback }, Metadata = new MediaMetadata { Source = MetadataSource.Fallback },
@ -215,4 +217,197 @@ namespace ErsatzTV.Core.Tests.Metadata
new ItemScanningPlan(movieMediaItem.Path, ScanningAction.Collections)); new ItemScanningPlan(movieMediaItem.Path, ScanningAction.Collections));
} }
} }
[TestFixture]
public class NewEpisodeTests
{
private readonly TestMediaScanner _scanner = new();
[Test]
public void WithoutNfo_WithoutPoster()
{
var episodeFileName = "/tv/test (2021)/season 01/test (2021) - s01e03.mkv";
string[] fileNames = { episodeFileName };
Seq<LocalMediaItemScanningPlan> result = _scanner.DetermineActions(
MediaType.TvShow,
Seq<MediaItem>.Empty,
fileNames.ToSeq());
result.Count.Should().Be(1);
(Either<string, MediaItem> source, List<ItemScanningPlan> itemScanningPlans) = result.Head();
source.IsLeft.Should().BeTrue();
source.LeftToSeq().Should().BeEquivalentTo(episodeFileName);
itemScanningPlans.Should().BeEquivalentTo(
new ItemScanningPlan(episodeFileName, ScanningAction.Statistics),
new ItemScanningPlan(episodeFileName, ScanningAction.FallbackMetadata),
new ItemScanningPlan(episodeFileName, ScanningAction.Collections));
}
[Test]
public void WithNfo_WithoutPoster()
{
var episodeFileName = "/tv/test (2021)/season 01/test (2021) - s01e03.mkv";
var nfoFileName = "/tv/test (2021)/season 01/test (2021) - s01e03.nfo";
string[] fileNames = { episodeFileName, nfoFileName };
Seq<LocalMediaItemScanningPlan> result = _scanner.DetermineActions(
MediaType.TvShow,
Seq<MediaItem>.Empty,
fileNames.ToSeq());
result.Count.Should().Be(1);
(Either<string, MediaItem> source, List<ItemScanningPlan> itemScanningPlans) = result.Head();
source.IsLeft.Should().BeTrue();
source.LeftToSeq().Should().BeEquivalentTo(episodeFileName);
itemScanningPlans.Should().BeEquivalentTo(
new ItemScanningPlan(episodeFileName, ScanningAction.Statistics),
new ItemScanningPlan(nfoFileName, ScanningAction.SidecarMetadata),
new ItemScanningPlan(episodeFileName, ScanningAction.Collections));
}
[Test]
public void WithoutNfo_WithPoster(
[Values("jpg", "jpeg", "png", "gif", "tbn")]
string posterExtension)
{
var episodeFileName = "/tv/test (2021)/season 01/test (2021) - s01e03.mkv";
var posterFileName = $"/tv/test (2021)/poster.{posterExtension}";
string[] fileNames = { episodeFileName, posterFileName };
Seq<LocalMediaItemScanningPlan> result = _scanner.DetermineActions(
MediaType.TvShow,
Seq<MediaItem>.Empty,
fileNames.ToSeq());
result.Count.Should().Be(1);
(Either<string, MediaItem> source, List<ItemScanningPlan> itemScanningPlans) = result.Head();
source.IsLeft.Should().BeTrue();
source.LeftToSeq().Should().BeEquivalentTo(episodeFileName);
itemScanningPlans.Should().BeEquivalentTo(
new ItemScanningPlan(episodeFileName, ScanningAction.Statistics),
new ItemScanningPlan(episodeFileName, ScanningAction.FallbackMetadata),
new ItemScanningPlan(posterFileName, ScanningAction.Poster),
new ItemScanningPlan(episodeFileName, ScanningAction.Collections));
}
[Test]
public void WithNfo_WithPoster(
[Values("jpg", "jpeg", "png", "gif", "tbn")]
string posterExtension)
{
var episodeFileName = "/tv/test (2021)/season 01/test (2021) - s01e03.mkv";
var nfoFileName = "/tv/test (2021)/season 01/test (2021) - s01e03.nfo";
var posterFileName = $"/tv/test (2021)/poster.{posterExtension}";
string[] fileNames = { episodeFileName, nfoFileName, posterFileName };
Seq<LocalMediaItemScanningPlan> result = _scanner.DetermineActions(
MediaType.TvShow,
Seq<MediaItem>.Empty,
fileNames.ToSeq());
result.Count.Should().Be(1);
(Either<string, MediaItem> source, List<ItemScanningPlan> itemScanningPlans) = result.Head();
source.IsLeft.Should().BeTrue();
source.LeftToSeq().Should().BeEquivalentTo(episodeFileName);
itemScanningPlans.Should().BeEquivalentTo(
new ItemScanningPlan(episodeFileName, ScanningAction.Statistics),
new ItemScanningPlan(nfoFileName, ScanningAction.SidecarMetadata),
new ItemScanningPlan(posterFileName, ScanningAction.Poster),
new ItemScanningPlan(episodeFileName, ScanningAction.Collections));
}
}
[TestFixture]
public class ExistingEpisodeTests
{
private readonly TestMediaScanner _scanner = new();
// TODO: mtime should affect this
[Test]
public void WithNewNfo_WithoutPoster()
{
var episodeMediaItem = new MediaItem
{
Metadata = new MediaMetadata { Source = MetadataSource.Fallback },
Path = "/tv/test (2021)/season 01/test (2021) - s01e03.mkv"
};
var nfoFileName = "/tv/test (2021)/season 01/test (2021) - s01e03.nfo";
string[] fileNames = { episodeMediaItem.Path, nfoFileName };
Seq<LocalMediaItemScanningPlan> result = _scanner.DetermineActions(
MediaType.TvShow,
Seq.create(episodeMediaItem),
fileNames.ToSeq());
result.Count.Should().Be(1);
(Either<string, MediaItem> source, List<ItemScanningPlan> itemScanningPlans) = result.Head();
source.IsRight.Should().BeTrue();
source.RightToSeq().Should().BeEquivalentTo(episodeMediaItem);
itemScanningPlans.Should().BeEquivalentTo(
new ItemScanningPlan(nfoFileName, ScanningAction.SidecarMetadata),
new ItemScanningPlan(episodeMediaItem.Path, ScanningAction.Collections));
}
[Test]
public void WithoutNfo_WithNewPoster(
[Values("jpg", "jpeg", "png", "gif", "tbn")]
string posterExtension)
{
var episodeMediaItem = new MediaItem
{
Metadata = new MediaMetadata { Source = MetadataSource.Fallback },
Path = "/tv/test (2021)/season 01/test (2021) - s01e03.mkv"
};
var posterFileName = $"/tv/test (2021)/poster.{posterExtension}";
string[] fileNames = { episodeMediaItem.Path, posterFileName };
Seq<LocalMediaItemScanningPlan> result = _scanner.DetermineActions(
MediaType.TvShow,
Seq.create(episodeMediaItem),
fileNames.ToSeq());
result.Count.Should().Be(1);
(Either<string, MediaItem> source, List<ItemScanningPlan> itemScanningPlans) = result.Head();
source.IsRight.Should().BeTrue();
source.RightToSeq().Should().BeEquivalentTo(episodeMediaItem);
itemScanningPlans.Should()
.BeEquivalentTo(new ItemScanningPlan(posterFileName, ScanningAction.Poster));
}
[Test]
public void WithNewNfo_WithNewPoster(
[Values("jpg", "jpeg", "png", "gif", "tbn")]
string posterExtension)
{
var episodeMediaItem = new MediaItem
{
Metadata = new MediaMetadata { Source = MetadataSource.Fallback },
Path = "/tv/test (2021)/season 01/test (2021) - s01e03.mkv"
};
var nfoFileName = "/tv/test (2021)/season 01/test (2021) - s01e03.nfo";
var posterFileName = $"/tv/test (2021)/poster.{posterExtension}";
string[] fileNames = { episodeMediaItem.Path, nfoFileName, posterFileName };
Seq<LocalMediaItemScanningPlan> result = _scanner.DetermineActions(
MediaType.TvShow,
Seq.create(episodeMediaItem),
fileNames.ToSeq());
result.Count.Should().Be(1);
(Either<string, MediaItem> source, List<ItemScanningPlan> itemScanningPlans) = result.Head();
source.IsRight.Should().BeTrue();
source.RightToSeq().Should().BeEquivalentTo(episodeMediaItem);
itemScanningPlans.Should().BeEquivalentTo(
new ItemScanningPlan(nfoFileName, ScanningAction.SidecarMetadata),
new ItemScanningPlan(posterFileName, ScanningAction.Poster),
new ItemScanningPlan(episodeMediaItem.Path, ScanningAction.Collections));
}
}
}
} }

15
ErsatzTV.Core/Metadata/TestMediaScanner.cs

@ -81,6 +81,11 @@ namespace ErsatzTV.Core.Metadata
return Seq(movieAsNfo, movieNfo) return Seq(movieAsNfo, movieNfo)
.Filter(s => files.Contains(s)) .Filter(s => files.Contains(s))
.HeadOrNone(); .HeadOrNone();
case MediaType.TvShow:
string episodeAsNfo = Path.ChangeExtension(file, "nfo");
return Optional(episodeAsNfo)
.Filter(s => files.Contains(s))
.HeadOrNone();
} }
return None; return None;
@ -93,10 +98,16 @@ namespace ErsatzTV.Core.Metadata
switch (mediaType) switch (mediaType)
{ {
case MediaType.Movie: case MediaType.Movie:
IEnumerable<string> possiblePosters = ImageFileExtensions.Collect( IEnumerable<string> possibleMoviePosters = ImageFileExtensions.Collect(
ext => new[] { $"poster.{ext}", Path.GetFileNameWithoutExtension(file) + $"-poster.{ext}" }) ext => new[] { $"poster.{ext}", Path.GetFileNameWithoutExtension(file) + $"-poster.{ext}" })
.Map(f => Path.Combine(folder, f)); .Map(f => Path.Combine(folder, f));
return possiblePosters.Filter(s => files.Contains(s)).HeadOrNone(); return possibleMoviePosters.Filter(p => files.Contains(p)).HeadOrNone();
case MediaType.TvShow:
string parentFolder = Directory.GetParent(folder)?.FullName ?? string.Empty;
IEnumerable<string> possibleTvPosters = ImageFileExtensions
.Collect(ext => new[] { $"poster.{ext}" })
.Map(f => Path.Combine(parentFolder, f));
return possibleTvPosters.Filter(p => files.Contains(p)).HeadOrNone();
} }
return None; return None;

Loading…
Cancel
Save