New: Custom Format Updates (#8067)
parent
c72e64f081
commit
cbcf3d1058
@ -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.Movies;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Download.Aggregation.Aggregators
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class AggregateLanguagesFixture : CoreTest<AggregateLanguages>
|
||||||
|
{
|
||||||
|
private RemoteMovie _remoteMovie;
|
||||||
|
private Movie _movie;
|
||||||
|
private string _simpleReleaseTitle = "Series.Title.S01E01.xyz-RlsGroup";
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_movie = Builder<Movie>.CreateNew()
|
||||||
|
.With(m => m.MovieMetadata = new MovieMetadata
|
||||||
|
{
|
||||||
|
Title = "Some Movie",
|
||||||
|
OriginalLanguage = Language.English
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_remoteMovie = Builder<RemoteMovie>.CreateNew()
|
||||||
|
.With(l => l.ParsedMovieInfo = null)
|
||||||
|
.With(l => l.Movie = _movie)
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ParsedMovieInfo GetParsedMovieInfo(List<Language> languages, string releaseTitle, string releaseTokens = "")
|
||||||
|
{
|
||||||
|
return new ParsedMovieInfo
|
||||||
|
{
|
||||||
|
Languages = languages,
|
||||||
|
ReleaseTitle = releaseTitle,
|
||||||
|
SimpleReleaseTitle = releaseTokens
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_existing_language_if_episode_title_does_not_have_language()
|
||||||
|
{
|
||||||
|
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { Language.Original }, _simpleReleaseTitle);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteMovie).Languages.Should().Contain(_movie.MovieMetadata.Value.OriginalLanguage);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_parsed_language()
|
||||||
|
{
|
||||||
|
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { Language.French }, _simpleReleaseTitle);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteMovie).Languages.Should().Equal(_remoteMovie.ParsedMovieInfo.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";
|
||||||
|
|
||||||
|
_remoteMovie.Movie.Title = "Jimmy The Greek";
|
||||||
|
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { Language.Greek }, releaseTitle, releaseTokens);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteMovie).Languages.Should().Equal(_movie.MovieMetadata.Value.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";
|
||||||
|
|
||||||
|
_remoteMovie.Movie.Title = "Jimmy The Greek";
|
||||||
|
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { Language.Greek, Language.French }, releaseTitle, releaseTokens);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteMovie).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";
|
||||||
|
|
||||||
|
_remoteMovie.Movie.Title = "Jimmy The Greek";
|
||||||
|
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { Language.Greek }, releaseTitle, releaseTokens);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteMovie).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";
|
||||||
|
|
||||||
|
_remoteMovie.Movie.Title = "Jimmy The Greek";
|
||||||
|
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { Language.Greek }, releaseTitle, releaseTokens);
|
||||||
|
|
||||||
|
Subject.Aggregate(_remoteMovie).Languages.Should().Equal(Language.Greek);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,28 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Core.Parser.Augmenters;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
using NzbDrone.Core.Qualities;
|
|
||||||
using NzbDrone.Core.Test.Framework;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public abstract class AugmentMovieInfoFixture<TAugmenter> : CoreTest<TAugmenter>
|
|
||||||
where TAugmenter : class, IAugmentParsedMovieInfo
|
|
||||||
{
|
|
||||||
protected ParsedMovieInfo MovieInfo;
|
|
||||||
|
|
||||||
[SetUp]
|
|
||||||
public virtual void Setup()
|
|
||||||
{
|
|
||||||
MovieInfo = new ParsedMovieInfo
|
|
||||||
{
|
|
||||||
MovieTitles = new List<string> { "A Movie" },
|
|
||||||
Year = 1998,
|
|
||||||
SimpleReleaseTitle = "A Movie Title 1998 Bluray 1080p",
|
|
||||||
Quality = new QualityModel(Quality.Bluray1080p)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,109 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using FluentAssertions;
|
|
||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Core.History;
|
|
||||||
using NzbDrone.Core.Indexers;
|
|
||||||
using NzbDrone.Core.Indexers.Rarbg;
|
|
||||||
using NzbDrone.Core.Languages;
|
|
||||||
using NzbDrone.Core.Parser.Augmenters;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class AugmentWithHistoryFixture : AugmentMovieInfoFixture<AugmentWithHistory>
|
|
||||||
{
|
|
||||||
private AugmentWithHistory _customSubject { get; set; }
|
|
||||||
|
|
||||||
[SetUp]
|
|
||||||
public override void Setup()
|
|
||||||
{
|
|
||||||
base.Setup();
|
|
||||||
|
|
||||||
// Add multi indexer
|
|
||||||
GivenIndexerSettings(new RarbgSettings
|
|
||||||
{
|
|
||||||
MultiLanguages = new List<int>
|
|
||||||
{
|
|
||||||
(int)Language.English,
|
|
||||||
(int)Language.French,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected new AugmentWithHistory Subject
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_customSubject == null)
|
|
||||||
{
|
|
||||||
_customSubject = new AugmentWithHistory(new List<Lazy<IAugmentParsedMovieInfo>> { new (Mocker.Resolve<AugmentWithReleaseInfo>()) });
|
|
||||||
}
|
|
||||||
|
|
||||||
return _customSubject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenIndexerSettings(IIndexerSettings indexerSettings)
|
|
||||||
{
|
|
||||||
Mocker.GetMock<IIndexerFactory>().Setup(f => f.Get(It.IsAny<int>())).Returns(new IndexerDefinition
|
|
||||||
{
|
|
||||||
Settings = indexerSettings
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private MovieHistory HistoryWithData(params string[] data)
|
|
||||||
{
|
|
||||||
var dict = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
|
|
||||||
for (var i = 0; i < data.Length; i += 2)
|
|
||||||
{
|
|
||||||
dict.Add(data[i], data[i + 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new MovieHistory
|
|
||||||
{
|
|
||||||
Data = dict,
|
|
||||||
EventType = MovieHistoryEventType.Grabbed
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_add_indexer_flags()
|
|
||||||
{
|
|
||||||
var history = HistoryWithData("IndexerFlags", (IndexerFlags.PTP_Approved | IndexerFlags.PTP_Golden).ToString());
|
|
||||||
var movieInfo = Subject.AugmentMovieInfo(MovieInfo, history);
|
|
||||||
movieInfo.ExtraInfo["IndexerFlags"].Should().BeEquivalentTo(IndexerFlags.PTP_Golden | IndexerFlags.PTP_Approved);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_add_size()
|
|
||||||
{
|
|
||||||
var history = HistoryWithData("Size", 9663676416.ToString());
|
|
||||||
var movieInfo = Subject.AugmentMovieInfo(MovieInfo, history);
|
|
||||||
movieInfo.ExtraInfo["Size"].Should().BeEquivalentTo(9663676416);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_use_settings_languages_when_necessary()
|
|
||||||
{
|
|
||||||
var history = HistoryWithData("IndexerId", 1.ToString());
|
|
||||||
|
|
||||||
var movieInfo = Subject.AugmentMovieInfo(MovieInfo, history);
|
|
||||||
movieInfo.Languages.Should().BeEquivalentTo();
|
|
||||||
|
|
||||||
MovieInfo.SimpleReleaseTitle = "A Movie 1998 Bluray 1080p MULTI";
|
|
||||||
var multiInfo = Subject.AugmentMovieInfo(MovieInfo, history);
|
|
||||||
multiInfo.Languages.Should().BeEquivalentTo(Language.English, Language.French);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_use_settings_languages()
|
|
||||||
{
|
|
||||||
var unknownIndexer = HistoryWithData();
|
|
||||||
var unknownIndexerInfo = Subject.AugmentMovieInfo(MovieInfo, unknownIndexer);
|
|
||||||
unknownIndexerInfo.Languages.Should().BeEquivalentTo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
using System;
|
|
||||||
using FluentAssertions;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Core.Languages;
|
|
||||||
using NzbDrone.Core.Parser.Augmenters;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class AugmentWithOriginalLanguageFixture : AugmentMovieInfoFixture<AugmentWithOriginalLanguage>
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void should_add_movie_original_language()
|
|
||||||
{
|
|
||||||
var releaseInfo = new ParsedMovieInfo();
|
|
||||||
var movie = new Movies.Movie
|
|
||||||
{
|
|
||||||
MovieMetadata = new Movies.MovieMetadata
|
|
||||||
{
|
|
||||||
OriginalLanguage = Language.English
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var result = Subject.AugmentMovieInfo(releaseInfo, movie);
|
|
||||||
result.ExtraInfo.Should().ContainKey("OriginalLanguage");
|
|
||||||
result.ExtraInfo["OriginalLanguage"].Should().Be(Language.English);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using FluentAssertions;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Core.Languages;
|
|
||||||
using NzbDrone.Core.Parser.Augmenters;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class AugmentWithParsedMovieInfoFixture : AugmentMovieInfoFixture<AugmentWithParsedMovieInfo>
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void should_add_edition_if_null()
|
|
||||||
{
|
|
||||||
var folderInfo = new ParsedMovieInfo
|
|
||||||
{
|
|
||||||
Edition = "Directors Cut"
|
|
||||||
};
|
|
||||||
|
|
||||||
var result = Subject.AugmentMovieInfo(MovieInfo, folderInfo);
|
|
||||||
|
|
||||||
result.Edition.Should().Be(folderInfo.Edition);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_preferr_longer_edition()
|
|
||||||
{
|
|
||||||
var folderInfo = new ParsedMovieInfo
|
|
||||||
{
|
|
||||||
Edition = "Super duper cut"
|
|
||||||
};
|
|
||||||
|
|
||||||
MovieInfo.Edition = "Rogue";
|
|
||||||
|
|
||||||
var result = Subject.AugmentMovieInfo(MovieInfo, folderInfo);
|
|
||||||
|
|
||||||
result.Edition.Should().Be(folderInfo.Edition);
|
|
||||||
|
|
||||||
MovieInfo.Edition = "Super duper awesome cut";
|
|
||||||
|
|
||||||
result = Subject.AugmentMovieInfo(MovieInfo, folderInfo);
|
|
||||||
|
|
||||||
result.Edition.Should().Be(MovieInfo.Edition);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_combine_languages()
|
|
||||||
{
|
|
||||||
var folderInfo = new ParsedMovieInfo
|
|
||||||
{
|
|
||||||
Languages = new List<Language> { Language.French }
|
|
||||||
};
|
|
||||||
|
|
||||||
MovieInfo.Languages = new List<Language> { Language.English };
|
|
||||||
|
|
||||||
var result = Subject.AugmentMovieInfo(MovieInfo, folderInfo);
|
|
||||||
|
|
||||||
result.Languages.Should().BeEquivalentTo(Language.English, Language.French);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_use_folder_release_group()
|
|
||||||
{
|
|
||||||
var folderInfo = new ParsedMovieInfo
|
|
||||||
{
|
|
||||||
ReleaseGroup = "AwesomeGroup"
|
|
||||||
};
|
|
||||||
|
|
||||||
MovieInfo.ReleaseGroup = "";
|
|
||||||
|
|
||||||
var result = Subject.AugmentMovieInfo(MovieInfo, folderInfo);
|
|
||||||
|
|
||||||
result.ReleaseGroup.Should().BeEquivalentTo(folderInfo.ReleaseGroup);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,82 +0,0 @@
|
|||||||
using System.Linq;
|
|
||||||
using FluentAssertions;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Core.Indexers;
|
|
||||||
using NzbDrone.Core.Indexers.Rarbg;
|
|
||||||
using NzbDrone.Core.Languages;
|
|
||||||
using NzbDrone.Core.Parser.Augmenters;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class AugmentWithReleaseInfoFixture : AugmentMovieInfoFixture<AugmentWithReleaseInfo>
|
|
||||||
{
|
|
||||||
private IndexerDefinition _indexerDefinition;
|
|
||||||
|
|
||||||
private ReleaseInfo ReleaseInfoWithLanguages(params Language[] languages)
|
|
||||||
{
|
|
||||||
_indexerDefinition = new IndexerDefinition
|
|
||||||
{
|
|
||||||
Settings = new RarbgSettings { MultiLanguages = languages.ToList().Select(l => (int)l) }
|
|
||||||
};
|
|
||||||
|
|
||||||
Mocker.GetMock<IIndexerFactory>()
|
|
||||||
.Setup(v => v.Get(1))
|
|
||||||
.Returns(_indexerDefinition);
|
|
||||||
|
|
||||||
return new ReleaseInfo
|
|
||||||
{
|
|
||||||
IndexerId = 1
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_add_language_from_indexer()
|
|
||||||
{
|
|
||||||
var releaseInfo = ReleaseInfoWithLanguages(Language.English, Language.French);
|
|
||||||
MovieInfo.SimpleReleaseTitle = "A Movie Title 1998 Bluray 1080p MULTI";
|
|
||||||
var movieInfo = Subject.AugmentMovieInfo(MovieInfo, releaseInfo);
|
|
||||||
movieInfo.Languages.Count.Should().Be(2);
|
|
||||||
movieInfo.Languages.Should().BeEquivalentTo(Language.English, Language.French);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_add_size_info()
|
|
||||||
{
|
|
||||||
var releaseInfo = new ReleaseInfo
|
|
||||||
{
|
|
||||||
Size = 1500
|
|
||||||
};
|
|
||||||
|
|
||||||
var movieInfo = Subject.AugmentMovieInfo(MovieInfo, releaseInfo);
|
|
||||||
movieInfo.ExtraInfo["Size"].Should().BeEquivalentTo(1500);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_add_size_when_already_present()
|
|
||||||
{
|
|
||||||
var releaseInfo = new ReleaseInfo
|
|
||||||
{
|
|
||||||
Size = 1500
|
|
||||||
};
|
|
||||||
|
|
||||||
MovieInfo.ExtraInfo["Size"] = 1600;
|
|
||||||
|
|
||||||
var movieInfo = Subject.AugmentMovieInfo(MovieInfo, releaseInfo);
|
|
||||||
movieInfo.ExtraInfo["Size"].Should().BeEquivalentTo(1600);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_add_indexer_flags()
|
|
||||||
{
|
|
||||||
var releaseInfo = new ReleaseInfo
|
|
||||||
{
|
|
||||||
IndexerFlags = IndexerFlags.PTP_Approved | IndexerFlags.PTP_Golden
|
|
||||||
};
|
|
||||||
|
|
||||||
var movieInfo = Subject.AugmentMovieInfo(MovieInfo, releaseInfo);
|
|
||||||
movieInfo.ExtraInfo["IndexerFlags"].Should().BeEquivalentTo(IndexerFlags.PTP_Approved | IndexerFlags.PTP_Golden);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,22 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.Languages;
|
||||||
|
using NzbDrone.Core.Movies;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.CustomFormats
|
||||||
|
{
|
||||||
|
public class CustomFormatInput
|
||||||
|
{
|
||||||
|
public ParsedMovieInfo MovieInfo { get; set; }
|
||||||
|
public Movie Movie { get; set; }
|
||||||
|
public long Size { get; set; }
|
||||||
|
public IndexerFlags IndexerFlags { get; set; }
|
||||||
|
public List<Language> Languages { get; set; }
|
||||||
|
public string Filename { get; set; }
|
||||||
|
|
||||||
|
public CustomFormatInput()
|
||||||
|
{
|
||||||
|
Languages = new List<Language>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
|
{
|
||||||
|
public class HardcodeSubsSpecification : IDecisionEngineSpecification
|
||||||
|
{
|
||||||
|
private readonly IConfigService _configService;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public HardcodeSubsSpecification(IConfigService configService, Logger logger)
|
||||||
|
{
|
||||||
|
_configService = configService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpecificationPriority Priority => SpecificationPriority.Default;
|
||||||
|
public RejectionType Type => RejectionType.Permanent;
|
||||||
|
|
||||||
|
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
|
||||||
|
{
|
||||||
|
var hardcodeSubs = subject.ParsedMovieInfo.HardcodedSubs;
|
||||||
|
|
||||||
|
if (_configService.AllowHardcodedSubs || hardcodeSubs.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
return Decision.Accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
var whitelisted = _configService.WhitelistedHardcodedSubs.Split(',');
|
||||||
|
|
||||||
|
if (whitelisted != null && whitelisted.Any(t => (hardcodeSubs.ToLower().Contains(t.ToLower()) && t.IsNotNullOrWhiteSpace())))
|
||||||
|
{
|
||||||
|
_logger.Debug("Release hardcode subs ({0}) are in allowed values ({1})", hardcodeSubs, whitelisted);
|
||||||
|
return Decision.Accept();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Debug("Hardcode subs found: {0}", hardcodeSubs);
|
||||||
|
return Decision.Reject("Hardcode subs found: {0}", hardcodeSubs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
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 : IAggregateRemoteMovie
|
||||||
|
{
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public AggregateLanguages(Logger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RemoteMovie Aggregate(RemoteMovie remoteMovie)
|
||||||
|
{
|
||||||
|
var parsedMovieInfo = remoteMovie.ParsedMovieInfo;
|
||||||
|
var languages = parsedMovieInfo.Languages;
|
||||||
|
var movie = remoteMovie.Movie;
|
||||||
|
var releaseTokens = parsedMovieInfo.SimpleReleaseTitle ?? parsedMovieInfo.ReleaseTitle;
|
||||||
|
var normalizedReleaseTokens = Parser.Parser.NormalizeEpisodeTitle(releaseTokens);
|
||||||
|
var languagesToRemove = new List<Language>();
|
||||||
|
|
||||||
|
if (movie == null)
|
||||||
|
{
|
||||||
|
_logger.Debug("Unable to aggregate languages, using parsed values: {0}", string.Join(", ", languages.ToList()));
|
||||||
|
|
||||||
|
remoteMovie.Languages = languages;
|
||||||
|
|
||||||
|
return remoteMovie;
|
||||||
|
}
|
||||||
|
|
||||||
|
var movieTitleLanguage = LanguageParser.ParseLanguages(movie.Title);
|
||||||
|
|
||||||
|
if (!movieTitleLanguage.Contains(Language.Unknown))
|
||||||
|
{
|
||||||
|
var normalizedEpisodeTitle = Parser.Parser.NormalizeEpisodeTitle(movie.Title);
|
||||||
|
var movieTitleIndex = normalizedReleaseTokens.IndexOf(normalizedEpisodeTitle, StringComparison.CurrentCultureIgnoreCase);
|
||||||
|
|
||||||
|
if (movieTitleIndex >= 0)
|
||||||
|
{
|
||||||
|
releaseTokens = releaseTokens.Remove(movieTitleIndex, normalizedEpisodeTitle.Length);
|
||||||
|
languagesToRemove.AddRange(movieTitleLanguage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 movie 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> { movie.MovieMetadata.Value.OriginalLanguage };
|
||||||
|
_logger.Debug("Language couldn't be parsed from release, fallback to movie original language: {0}", movie.MovieMetadata.Value.OriginalLanguage.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (languages.Contains(Language.Original))
|
||||||
|
{
|
||||||
|
languages.Remove(Language.Original);
|
||||||
|
|
||||||
|
if (!languages.Contains(movie.MovieMetadata.Value.OriginalLanguage))
|
||||||
|
{
|
||||||
|
languages.Add(movie.MovieMetadata.Value.OriginalLanguage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
languages.Add(Language.Unknown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Debug("Selected languages: {0}", string.Join(", ", languages.ToList()));
|
||||||
|
|
||||||
|
remoteMovie.Languages = languages;
|
||||||
|
|
||||||
|
return remoteMovie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Aggregation.Aggregators
|
||||||
|
{
|
||||||
|
public interface IAggregateRemoteMovie
|
||||||
|
{
|
||||||
|
RemoteMovie Aggregate(RemoteMovie remoteMovie);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Core.Download.Aggregation.Aggregators;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Aggregation
|
||||||
|
{
|
||||||
|
public interface IRemoteMovieAggregationService
|
||||||
|
{
|
||||||
|
RemoteMovie Augment(RemoteMovie remoteMovie);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RemoteMovieAggregationService : IRemoteMovieAggregationService
|
||||||
|
{
|
||||||
|
private readonly IEnumerable<IAggregateRemoteMovie> _augmenters;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public RemoteMovieAggregationService(IEnumerable<IAggregateRemoteMovie> augmenters,
|
||||||
|
Logger logger)
|
||||||
|
{
|
||||||
|
_augmenters = augmenters;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RemoteMovie Augment(RemoteMovie remoteMovie)
|
||||||
|
{
|
||||||
|
foreach (var augmenter in _augmenters)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
augmenter.Aggregate(remoteMovie);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Warn(ex, ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return remoteMovie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using NzbDrone.Core.CustomFormats;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Notifications.Webhook
|
||||||
|
{
|
||||||
|
public class WebhookCustomFormat
|
||||||
|
{
|
||||||
|
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public WebhookCustomFormat(CustomFormat customFormat)
|
||||||
|
{
|
||||||
|
Id = customFormat.Id;
|
||||||
|
Name = customFormat.Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NzbDrone.Core.CustomFormats;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Notifications.Webhook
|
||||||
|
{
|
||||||
|
public class WebhookCustomFormatInfo
|
||||||
|
{
|
||||||
|
public List<WebhookCustomFormat> CustomFormats { get; set; }
|
||||||
|
public int CustomFormatScore { get; set; }
|
||||||
|
|
||||||
|
public WebhookCustomFormatInfo(List<CustomFormat> customFormats, int customFormatScore)
|
||||||
|
{
|
||||||
|
CustomFormats = customFormats.Select(c => new WebhookCustomFormat(c)).ToList();
|
||||||
|
CustomFormatScore = customFormatScore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,59 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using NzbDrone.Core.History;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Parser.Augmenters
|
|
||||||
{
|
|
||||||
public class AugmentWithHistory : IAugmentParsedMovieInfo
|
|
||||||
{
|
|
||||||
private readonly IEnumerable<Lazy<IAugmentParsedMovieInfo>> _augmenters;
|
|
||||||
|
|
||||||
public AugmentWithHistory(IEnumerable<Lazy<IAugmentParsedMovieInfo>> augmenters)
|
|
||||||
{
|
|
||||||
_augmenters = augmenters;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type HelperType
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return typeof(MovieHistory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ParsedMovieInfo AugmentMovieInfo(ParsedMovieInfo movieInfo, object helper)
|
|
||||||
{
|
|
||||||
if (helper is MovieHistory history && history.EventType == MovieHistoryEventType.Grabbed)
|
|
||||||
{
|
|
||||||
// First we create a release info from history data.
|
|
||||||
var releaseInfo = new ReleaseInfo();
|
|
||||||
|
|
||||||
if (int.TryParse(history.Data.GetValueOrDefault("indexerId"), out var indexerId))
|
|
||||||
{
|
|
||||||
releaseInfo.IndexerId = indexerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (long.TryParse(history.Data.GetValueOrDefault("size"), out var size))
|
|
||||||
{
|
|
||||||
releaseInfo.Size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Enum.TryParse(history.Data.GetValueOrDefault("indexerFlags"), true, out IndexerFlags indexerFlags))
|
|
||||||
{
|
|
||||||
releaseInfo.IndexerFlags = indexerFlags;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we run the release info augmenters from the history release info. TODO: Add setting to only do that if you trust your indexer!
|
|
||||||
var releaseInfoAugmenters = _augmenters.Where(a => a.Value.HelperType.IsInstanceOfType(releaseInfo));
|
|
||||||
foreach (var augmenter in releaseInfoAugmenters)
|
|
||||||
{
|
|
||||||
movieInfo = augmenter.Value.AugmentMovieInfo(movieInfo, releaseInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return movieInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
using System;
|
|
||||||
using NzbDrone.Core.MediaFiles.MediaInfo;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
using NzbDrone.Core.Qualities;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Parser.Augmenters
|
|
||||||
{
|
|
||||||
public class AugmentWithMediaInfo : IAugmentParsedMovieInfo
|
|
||||||
{
|
|
||||||
public Type HelperType
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return typeof(MediaInfoModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ParsedMovieInfo AugmentMovieInfo(ParsedMovieInfo movieInfo, object helper)
|
|
||||||
{
|
|
||||||
if (helper is MediaInfoModel mediaInfo)
|
|
||||||
{
|
|
||||||
var quality = movieInfo.Quality;
|
|
||||||
if (!(quality.Quality.Modifier == Modifier.BRDISK || quality.Quality.Modifier == Modifier.REMUX) &&
|
|
||||||
(quality.Quality.Source == Source.BLURAY || quality.Quality.Source == Source.TV ||
|
|
||||||
quality.Quality.Source == Source.WEBDL) &&
|
|
||||||
!(quality.Quality.Resolution == (int)Resolution.R480p || quality.Quality.Resolution == (int)Resolution.R576p))
|
|
||||||
{
|
|
||||||
var width = mediaInfo.Width;
|
|
||||||
var existing = quality.Quality.Resolution;
|
|
||||||
|
|
||||||
if (width > 854)
|
|
||||||
{
|
|
||||||
quality.Quality.Resolution = (int)Resolution.R720p;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (width > 1280)
|
|
||||||
{
|
|
||||||
quality.Quality.Resolution = (int)Resolution.R1080p;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (width > 1920)
|
|
||||||
{
|
|
||||||
quality.Quality.Resolution = (int)Resolution.R2160p;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existing != quality.Quality.Resolution)
|
|
||||||
{
|
|
||||||
// _logger.Debug("Overwriting resolution info {0} with info from media info {1}", existing, quality.Resolution);
|
|
||||||
quality.ResolutionDetectionSource = QualityDetectionSource.MediaInfo;
|
|
||||||
movieInfo.Quality = quality;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return movieInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
using System;
|
|
||||||
using NzbDrone.Core.Movies;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Parser.Augmenters
|
|
||||||
{
|
|
||||||
public class AugmentWithOriginalLanguage : IAugmentParsedMovieInfo
|
|
||||||
{
|
|
||||||
public Type HelperType
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return typeof(Movie);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ParsedMovieInfo AugmentMovieInfo(ParsedMovieInfo movieInfo, object helper)
|
|
||||||
{
|
|
||||||
if (helper is Movie movie && movie?.MovieMetadata.Value.OriginalLanguage != null && movieInfo != null)
|
|
||||||
{
|
|
||||||
movieInfo.ExtraInfo["OriginalLanguage"] = movie.MovieMetadata.Value.OriginalLanguage;
|
|
||||||
}
|
|
||||||
|
|
||||||
return movieInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using NzbDrone.Common.Extensions;
|
|
||||||
using NzbDrone.Core.Indexers;
|
|
||||||
using NzbDrone.Core.Languages;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Parser.Augmenters
|
|
||||||
{
|
|
||||||
public class AugmentWithReleaseInfo : IAugmentParsedMovieInfo
|
|
||||||
{
|
|
||||||
private readonly Lazy<IIndexerFactory> _indexerFactory;
|
|
||||||
|
|
||||||
public AugmentWithReleaseInfo(Lazy<IIndexerFactory> indexerFactory)
|
|
||||||
{
|
|
||||||
_indexerFactory = indexerFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type HelperType
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return typeof(ReleaseInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ParsedMovieInfo AugmentMovieInfo(ParsedMovieInfo movieInfo, object helper)
|
|
||||||
{
|
|
||||||
if (helper is ReleaseInfo releaseInfo)
|
|
||||||
{
|
|
||||||
IIndexerSettings indexerSettings = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
indexerSettings = _indexerFactory.Value.Get(releaseInfo.IndexerId)?.Settings as IIndexerSettings;
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
// _logger.Debug("Indexer with id {0} does not exist, skipping minimum seeder checks.", subject.Release.IndexerId);
|
|
||||||
} // First, let's augment the language!
|
|
||||||
|
|
||||||
var languageTitle = movieInfo.SimpleReleaseTitle;
|
|
||||||
if (movieInfo.PrimaryMovieTitle.IsNotNullOrWhiteSpace())
|
|
||||||
{
|
|
||||||
if (languageTitle.ToLower().Contains("multi") && indexerSettings?.MultiLanguages?.Any() == true)
|
|
||||||
{
|
|
||||||
foreach (var i in indexerSettings.MultiLanguages)
|
|
||||||
{
|
|
||||||
var language = (Language)i;
|
|
||||||
if (!movieInfo.Languages.Contains(language))
|
|
||||||
{
|
|
||||||
movieInfo.Languages.Add(language);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next, let's add other useful info to the extra info dict
|
|
||||||
if (!movieInfo.ExtraInfo.ContainsKey("Size"))
|
|
||||||
{
|
|
||||||
movieInfo.ExtraInfo["Size"] = releaseInfo.Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
movieInfo.ExtraInfo["IndexerFlags"] = releaseInfo.IndexerFlags;
|
|
||||||
}
|
|
||||||
|
|
||||||
return movieInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in new issue