parent
16e2d130e6
commit
6216a71f8c
@ -0,0 +1,112 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Download.Aggregation.Aggregators;
|
||||||
|
using NzbDrone.Core.Languages;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Download.Aggregation.Aggregators
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class AggregateLanguagesFixture : CoreTest<AggregateLanguages>
|
||||||
|
{
|
||||||
|
private RemoteEpisode _remoteEpisode;
|
||||||
|
private Series _series;
|
||||||
|
private string _simpleReleaseTitle = "Series.Title.S01E01.xyz-RlsGroup";
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
var episodes = Builder<Episode>.CreateListOfSize(1)
|
||||||
|
.BuildList();
|
||||||
|
|
||||||
|
_series = Builder<Series>.CreateNew()
|
||||||
|
.With(m => m.OriginalLanguage = Language.English)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_remoteEpisode = Builder<RemoteEpisode>.CreateNew()
|
||||||
|
.With(l => l.ParsedEpisodeInfo = null)
|
||||||
|
.With(l => l.Episodes = episodes)
|
||||||
|
.With(l => l.Series = _series)
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ParsedEpisodeInfo GetParsedEpisodeInfo(List<Language> languages, string releaseTitle, string releaseTokens = "")
|
||||||
|
{
|
||||||
|
return new ParsedEpisodeInfo
|
||||||
|
{
|
||||||
|
Languages = languages,
|
||||||
|
ReleaseTitle = releaseTitle,
|
||||||
|
ReleaseTokens = releaseTokens
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_existing_language_if_episode_title_does_not_have_language()
|
||||||
|
{
|
||||||
|
_remoteEpisode.ParsedEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.Original }, _simpleReleaseTitle);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteEpisode).Languages.Should().Contain(_series.OriginalLanguage);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_parsed_language()
|
||||||
|
{
|
||||||
|
_remoteEpisode.ParsedEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.French }, _simpleReleaseTitle);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteEpisode).Languages.Should().Equal(_remoteEpisode.ParsedEpisodeInfo.Languages);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_exclude_language_that_is_part_of_episode_title_when_release_tokens_contains_episode_title()
|
||||||
|
{
|
||||||
|
var releaseTitle = "Series.Title.S01E01.Jimmy.The.Greek.xyz-RlsGroup";
|
||||||
|
var releaseTokens = ".Jimmy.The.Greek.xyz-RlsGroup";
|
||||||
|
|
||||||
|
_remoteEpisode.Episodes.First().Title = "Jimmy The Greek";
|
||||||
|
_remoteEpisode.ParsedEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.Greek }, releaseTitle, releaseTokens);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteEpisode).Languages.Should().Equal(_series.OriginalLanguage);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_remove_parsed_language_that_is_part_of_episode_title_when_release_tokens_contains_episode_title()
|
||||||
|
{
|
||||||
|
var releaseTitle = "Series.Title.S01E01.Jimmy.The.Greek.French.xyz-RlsGroup";
|
||||||
|
var releaseTokens = ".Jimmy.The.Greek.French.xyz-RlsGroup";
|
||||||
|
|
||||||
|
_remoteEpisode.Episodes.First().Title = "Jimmy The Greek";
|
||||||
|
_remoteEpisode.ParsedEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.Greek, Language.French }, releaseTitle, releaseTokens);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteEpisode).Languages.Should().Equal(Language.French);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_exclude_language_that_is_part_of_episode_title_when_release_tokens_does_not_contain_episode_title()
|
||||||
|
{
|
||||||
|
var releaseTitle = "Series.Title.S01E01.xyz-RlsGroup";
|
||||||
|
var releaseTokens = ".xyz-RlsGroup";
|
||||||
|
|
||||||
|
_remoteEpisode.Episodes.First().Title = "Jimmy The Greek";
|
||||||
|
_remoteEpisode.ParsedEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.Greek }, releaseTitle, releaseTokens);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteEpisode).Languages.Should().Equal(Language.Greek);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_use_reparse_language_after_determining_languages_that_are_in_episode_titles()
|
||||||
|
{
|
||||||
|
var releaseTitle = "Series.Title.S01E01.Jimmy.The.Greek.Greek.xyz-RlsGroup";
|
||||||
|
var releaseTokens = ".Jimmy.The.Greek.Greek.xyz-RlsGroup";
|
||||||
|
|
||||||
|
_remoteEpisode.Episodes.First().Title = "Jimmy The Greek";
|
||||||
|
_remoteEpisode.ParsedEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.Greek }, releaseTitle, releaseTokens);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteEpisode).Languages.Should().Equal(Language.Greek);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.Languages;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.CustomFormats
|
||||||
|
{
|
||||||
|
public class CustomFormatInput
|
||||||
|
{
|
||||||
|
public ParsedEpisodeInfo EpisodeInfo { get; set; }
|
||||||
|
public Series Series { get; set; }
|
||||||
|
public long Size { get; set; }
|
||||||
|
public List<Language> Languages { get; set; }
|
||||||
|
public string Filename { get; set; }
|
||||||
|
|
||||||
|
public CustomFormatInput()
|
||||||
|
{
|
||||||
|
Languages = new List<Language>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// public CustomFormatInput(ParsedEpisodeInfo episodeInfo, Series series)
|
||||||
|
// {
|
||||||
|
// EpisodeInfo = episodeInfo;
|
||||||
|
// Series = series;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public CustomFormatInput(ParsedEpisodeInfo episodeInfo, Series series, long size, List<Language> languages)
|
||||||
|
// {
|
||||||
|
// EpisodeInfo = episodeInfo;
|
||||||
|
// Series = series;
|
||||||
|
// Size = size;
|
||||||
|
// Languages = languages;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public CustomFormatInput(ParsedEpisodeInfo episodeInfo, Series series, long size, List<Language> languages, string filename)
|
||||||
|
// {
|
||||||
|
// EpisodeInfo = episodeInfo;
|
||||||
|
// Series = series;
|
||||||
|
// Size = size;
|
||||||
|
// Languages = languages;
|
||||||
|
// Filename = filename;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Core.Languages;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Aggregation.Aggregators
|
||||||
|
{
|
||||||
|
public class AggregateLanguages : IAggregateRemoteEpisode
|
||||||
|
{
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public AggregateLanguages(Logger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RemoteEpisode Aggregate(RemoteEpisode remoteEpisode)
|
||||||
|
{
|
||||||
|
var parsedEpisodeInfo = remoteEpisode.ParsedEpisodeInfo;
|
||||||
|
var languages = parsedEpisodeInfo.Languages;
|
||||||
|
var series = remoteEpisode.Series;
|
||||||
|
var releaseTokens = parsedEpisodeInfo.ReleaseTokens ?? parsedEpisodeInfo.ReleaseTitle;
|
||||||
|
var normalizedReleaseTokens = Parser.Parser.NormalizeEpisodeTitle(releaseTokens);
|
||||||
|
var languagesToRemove = new List<Language>();
|
||||||
|
|
||||||
|
if (series == null)
|
||||||
|
{
|
||||||
|
_logger.Debug("Unable to aggregate languages, using parsed values: {0}", string.Join(", ", languages.ToList()));
|
||||||
|
|
||||||
|
remoteEpisode.Languages = languages;
|
||||||
|
|
||||||
|
return remoteEpisode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exclude any languages that are part of the episode title, if the episode title is in the release tokens (falls back to release title)
|
||||||
|
foreach (var episode in remoteEpisode.Episodes)
|
||||||
|
{
|
||||||
|
var episodeTitleLanguage = LanguageParser.ParseLanguages(episode.Title);
|
||||||
|
|
||||||
|
if (!episodeTitleLanguage.Contains(Language.Unknown))
|
||||||
|
{
|
||||||
|
var normalizedEpisodeTitle = Parser.Parser.NormalizeEpisodeTitle(episode.Title);
|
||||||
|
var episodeTitleIndex = normalizedReleaseTokens.IndexOf(normalizedEpisodeTitle, StringComparison.CurrentCultureIgnoreCase);
|
||||||
|
|
||||||
|
if (episodeTitleIndex >= 0)
|
||||||
|
{
|
||||||
|
releaseTokens = releaseTokens.Remove(episodeTitleIndex, normalizedEpisodeTitle.Length);
|
||||||
|
languagesToRemove.AddRange(episodeTitleLanguage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove any languages still in the title that would normally be removed
|
||||||
|
languagesToRemove = languagesToRemove.Except(LanguageParser.ParseLanguages(releaseTokens)).ToList();
|
||||||
|
|
||||||
|
// Remove all languages that aren't part of the updated releaseTokens
|
||||||
|
languages = languages.Except(languagesToRemove).ToList();
|
||||||
|
|
||||||
|
// Use series language as fallback if we couldn't parse a language
|
||||||
|
if (languages.Count == 0 || (languages.Count == 1 && languages.First() == Language.Unknown))
|
||||||
|
{
|
||||||
|
languages = new List<Language> { series.OriginalLanguage };
|
||||||
|
_logger.Debug("Language couldn't be parsed from release, fallback to series original language: {0}", series.OriginalLanguage.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (languages.Contains(Language.Original))
|
||||||
|
{
|
||||||
|
languages.Remove(Language.Original);
|
||||||
|
|
||||||
|
if (!languages.Contains(series.OriginalLanguage))
|
||||||
|
{
|
||||||
|
languages.Add(series.OriginalLanguage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
languages.Add(Language.Unknown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Debug("Selected languages: {0}", string.Join(", ", languages.ToList()));
|
||||||
|
|
||||||
|
remoteEpisode.Languages = languages;
|
||||||
|
|
||||||
|
return remoteEpisode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue