Browse Source

add fallback metadata for movie sources

pull/9/head
Jason Dove 6 years ago
parent
commit
7538779d5e
  1. 14
      ErsatzTV.Core.Tests/Metadata/FallbackMetadataProviderTests.cs
  2. 54
      ErsatzTV.Core/Metadata/FallbackMetadataProvider.cs
  3. 21
      ErsatzTV.Core/Metadata/LocalMetadataProvider.cs

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

@ -25,11 +25,19 @@ namespace ErsatzTV.Core.Tests.Metadata
[TestCase("Awesome Show - S01E02 - Episode Title-720p.mkv", "Awesome Show", 1, 2)] [TestCase("Awesome Show - S01E02 - Episode Title-720p.mkv", "Awesome Show", 1, 2)]
[TestCase("Awesome Show - s1e2 - Episode Title-720p.mkv", "Awesome Show", 1, 2)] [TestCase("Awesome Show - s1e2 - Episode Title-720p.mkv", "Awesome Show", 1, 2)]
[TestCase("Awesome Show - S1E2 - Episode Title-720p.mkv", "Awesome Show", 1, 2)] [TestCase("Awesome Show - S1E2 - Episode Title-720p.mkv", "Awesome Show", 1, 2)]
[TestCase("Awesome Show (2021) - S01E02 - Description; More Description (1080p QUALITY codec GROUP).mkv", "Awesome Show (2021)", 1, 2)] [TestCase(
[TestCase("Awesome.Show.S01E02.Description.more.Description.QUAlity.codec.CODEC-GROUP.mkv", "Awesome.Show", 1, 2)] "Awesome Show (2021) - S01E02 - Description; More Description (1080p QUALITY codec GROUP).mkv",
"Awesome Show (2021)",
1,
2)]
[TestCase(
"Awesome.Show.S01E02.Description.more.Description.QUAlity.codec.CODEC-GROUP.mkv",
"Awesome.Show",
1,
2)]
public void GetFallbackMetadata_ShouldHandleVariousFormats(string path, string title, int season, int episode) public void GetFallbackMetadata_ShouldHandleVariousFormats(string path, string title, int season, int episode)
{ {
var metadata = FallbackMetadataProvider.GetFallbackMetadata(path); MediaMetadata metadata = FallbackMetadataProvider.GetFallbackMetadata(new MediaItem { Path = path });
metadata.MediaType.Should().Be(MediaType.TvShow); metadata.MediaType.Should().Be(MediaType.TvShow);
metadata.Title.Should().Be(title); metadata.Title.Should().Be(title);

54
ErsatzTV.Core/Metadata/FallbackMetadataProvider.cs

@ -1,4 +1,5 @@
using System.IO; using System;
using System.IO;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
@ -6,12 +7,32 @@ namespace ErsatzTV.Core.Metadata
{ {
public static class FallbackMetadataProvider public static class FallbackMetadataProvider
{ {
public static MediaMetadata GetFallbackMetadata(string path) public static MediaMetadata GetFallbackMetadata(MediaItem mediaItem)
{ {
string fileName = Path.GetFileName(path); string fileName = Path.GetFileName(mediaItem.Path);
var metadata = new MediaMetadata { Title = fileName ?? path }; var metadata = new MediaMetadata { Title = fileName ?? mediaItem.Path };
if (fileName != null) if (fileName != null)
{
if (!(mediaItem.Source is LocalMediaSource localMediaSource))
{
return metadata;
}
return localMediaSource.MediaType switch
{
MediaType.TvShow => GetTvShowMetadata(fileName, metadata),
MediaType.Movie => GetMovieMetadata(fileName, metadata),
_ => metadata
};
}
return metadata;
}
private static MediaMetadata GetTvShowMetadata(string fileName, MediaMetadata metadata)
{
try
{ {
const string PATTERN = @"^(.*?)[.\s-]+[sS](\d+)[eE](\d+).*\.\w+$"; const string PATTERN = @"^(.*?)[.\s-]+[sS](\d+)[eE](\d+).*\.\w+$";
Match match = Regex.Match(fileName, PATTERN); Match match = Regex.Match(fileName, PATTERN);
@ -23,6 +44,31 @@ namespace ErsatzTV.Core.Metadata
metadata.EpisodeNumber = int.Parse(match.Groups[3].Value); metadata.EpisodeNumber = int.Parse(match.Groups[3].Value);
} }
} }
catch (Exception)
{
// ignored
}
return metadata;
}
private static MediaMetadata GetMovieMetadata(string fileName, MediaMetadata metadata)
{
try
{
const string PATTERN = @"^(.*?)[.\(](\d{4})[.\)].*\.\w+$";
Match match = Regex.Match(fileName, PATTERN);
if (match.Success)
{
metadata.MediaType = MediaType.Movie;
metadata.Title = match.Groups[1].Value;
metadata.Aired = new DateTime(int.Parse(match.Groups[2].Value), 1, 1);
}
}
catch (Exception)
{
// ignored
}
return metadata; return metadata;
} }

21
ErsatzTV.Core/Metadata/LocalMetadataProvider.cs

@ -6,6 +6,7 @@ using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Metadata;
using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Repositories;
using LanguageExt; using LanguageExt;
using Microsoft.Extensions.Logging;
using static LanguageExt.Prelude; using static LanguageExt.Prelude;
namespace ErsatzTV.Core.Metadata namespace ErsatzTV.Core.Metadata
@ -14,17 +15,21 @@ namespace ErsatzTV.Core.Metadata
{ {
private static readonly XmlSerializer MovieSerializer = new(typeof(MovieNfo)); private static readonly XmlSerializer MovieSerializer = new(typeof(MovieNfo));
private static readonly XmlSerializer TvShowSerializer = new(typeof(TvShowEpisodeNfo)); private static readonly XmlSerializer TvShowSerializer = new(typeof(TvShowEpisodeNfo));
private readonly ILogger<LocalMetadataProvider> _logger;
private readonly IMediaItemRepository _mediaItemRepository; private readonly IMediaItemRepository _mediaItemRepository;
public LocalMetadataProvider(IMediaItemRepository mediaItemRepository) => public LocalMetadataProvider(IMediaItemRepository mediaItemRepository, ILogger<LocalMetadataProvider> logger)
{
_mediaItemRepository = mediaItemRepository; _mediaItemRepository = mediaItemRepository;
_logger = logger;
}
public async Task RefreshMetadata(MediaItem mediaItem) public async Task RefreshMetadata(MediaItem mediaItem)
{ {
Option<MediaMetadata> maybeMetadata = await LoadMetadata(mediaItem); Option<MediaMetadata> maybeMetadata = await LoadMetadata(mediaItem);
MediaMetadata metadata = MediaMetadata metadata =
maybeMetadata.IfNone(() => FallbackMetadataProvider.GetFallbackMetadata(mediaItem.Path)); maybeMetadata.IfNone(() => FallbackMetadataProvider.GetFallbackMetadata(mediaItem));
await ApplyMetadataUpdate(mediaItem, metadata); await ApplyMetadataUpdate(mediaItem, metadata);
} }
@ -52,11 +57,13 @@ namespace ErsatzTV.Core.Metadata
string nfoFileName = Path.ChangeExtension(mediaItem.Path, "nfo"); string nfoFileName = Path.ChangeExtension(mediaItem.Path, "nfo");
if (nfoFileName == null || !File.Exists(nfoFileName)) if (nfoFileName == null || !File.Exists(nfoFileName))
{ {
_logger.LogDebug("NFO file does not exist at {Path}", nfoFileName);
return None; return None;
} }
if (!(mediaItem.Source is LocalMediaSource localMediaSource)) if (!(mediaItem.Source is LocalMediaSource localMediaSource))
{ {
_logger.LogDebug("Media source {Name} is not a local media source", mediaItem.Source.Name);
return None; return None;
} }
@ -68,7 +75,7 @@ namespace ErsatzTV.Core.Metadata
}; };
} }
private static async Task<Option<MediaMetadata>> LoadTvShowMetadata(string nfoFileName) private async Task<Option<MediaMetadata>> LoadTvShowMetadata(string nfoFileName)
{ {
try try
{ {
@ -87,13 +94,14 @@ namespace ErsatzTV.Core.Metadata
}, },
None); None);
} }
catch (Exception) catch (Exception ex)
{ {
_logger.LogDebug(ex, "Failed to read TV nfo metadata from {Path}", nfoFileName);
return None; return None;
} }
} }
private static async Task<Option<MediaMetadata>> LoadMovieMetadata(string nfoFileName) private async Task<Option<MediaMetadata>> LoadMovieMetadata(string nfoFileName)
{ {
try try
{ {
@ -110,8 +118,9 @@ namespace ErsatzTV.Core.Metadata
}, },
None); None);
} }
catch (Exception) catch (Exception ex)
{ {
_logger.LogDebug(ex, "Failed to read Movie nfo metadata from {Path}", nfoFileName);
return None; return None;
} }
} }

Loading…
Cancel
Save