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