mirror of
https://github.com/Radarr/Radarr.git
synced 2025-04-24 06:27:08 -04:00
New: Custom Format Updates (#8067)
This commit is contained in:
parent
c72e64f081
commit
cbcf3d1058
90 changed files with 767 additions and 1053 deletions
|
@ -56,6 +56,7 @@ class HistoryRow extends Component {
|
|||
movie,
|
||||
quality,
|
||||
customFormats,
|
||||
customFormatScore,
|
||||
languages,
|
||||
qualityCutoffNotMet,
|
||||
eventType,
|
||||
|
@ -175,7 +176,7 @@ class HistoryRow extends Component {
|
|||
key={name}
|
||||
className={styles.customFormatScore}
|
||||
>
|
||||
{formatCustomFormatScore(data.customFormatScore)}
|
||||
{formatCustomFormatScore(customFormatScore)}
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
@ -241,8 +242,9 @@ HistoryRow.propTypes = {
|
|||
movie: PropTypes.object.isRequired,
|
||||
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
quality: PropTypes.object.isRequired,
|
||||
customFormats: PropTypes.arrayOf(PropTypes.object),
|
||||
customFormatScore: PropTypes.number.isRequired,
|
||||
qualityCutoffNotMet: PropTypes.bool.isRequired,
|
||||
customFormats: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
eventType: PropTypes.string.isRequired,
|
||||
sourceTitle: PropTypes.string.isRequired,
|
||||
date: PropTypes.string.isRequired,
|
||||
|
|
|
@ -64,6 +64,15 @@ const columns = [
|
|||
isSortable: true,
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'customFormats',
|
||||
label: React.createElement(Icon, {
|
||||
name: icons.INTERACTIVE,
|
||||
title: translate('CustomFormat')
|
||||
}),
|
||||
isSortable: true,
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'rejections',
|
||||
label: React.createElement(Icon, {
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
}
|
||||
|
||||
.quality,
|
||||
.language {
|
||||
.languages {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.label {
|
||||
|
@ -21,3 +23,7 @@
|
|||
margin-top: 0;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
.customFormatTooltip {
|
||||
max-width: 250px;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import SelectLanguageModal from 'InteractiveImport/Language/SelectLanguageModal'
|
|||
import SelectMovieModal from 'InteractiveImport/Movie/SelectMovieModal';
|
||||
import SelectQualityModal from 'InteractiveImport/Quality/SelectQualityModal';
|
||||
import SelectReleaseGroupModal from 'InteractiveImport/ReleaseGroup/SelectReleaseGroupModal';
|
||||
import MovieFormats from 'Movie/MovieFormats';
|
||||
import MovieLanguage from 'Movie/MovieLanguage';
|
||||
import MovieQuality from 'Movie/MovieQuality';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
|
@ -150,6 +151,7 @@ class InteractiveImportRow extends Component {
|
|||
languages,
|
||||
releaseGroup,
|
||||
size,
|
||||
customFormats,
|
||||
rejections,
|
||||
isReprocessing,
|
||||
isSelected,
|
||||
|
@ -226,7 +228,7 @@ class InteractiveImportRow extends Component {
|
|||
</TableRowCellButton>
|
||||
|
||||
<TableRowCellButton
|
||||
className={styles.language}
|
||||
className={styles.languages}
|
||||
title={translate('ClickToChangeLanguage')}
|
||||
onPress={this.onSelectLanguagePress}
|
||||
>
|
||||
|
@ -259,7 +261,26 @@ class InteractiveImportRow extends Component {
|
|||
|
||||
<TableRowCell>
|
||||
{
|
||||
!!rejections.length &&
|
||||
customFormats?.length ?
|
||||
<Popover
|
||||
anchor={
|
||||
<Icon name={icons.INTERACTIVE} />
|
||||
}
|
||||
title="Formats"
|
||||
body={
|
||||
<div className={styles.customFormatTooltip}>
|
||||
<MovieFormats formats={customFormats} />
|
||||
</div>
|
||||
}
|
||||
position={tooltipPositions.LEFT}
|
||||
/> :
|
||||
null
|
||||
}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell>
|
||||
{
|
||||
rejections.length ?
|
||||
<Popover
|
||||
anchor={
|
||||
<Icon
|
||||
|
@ -282,7 +303,9 @@ class InteractiveImportRow extends Component {
|
|||
</ul>
|
||||
}
|
||||
position={tooltipPositions.LEFT}
|
||||
/>
|
||||
canFlip={false}
|
||||
/> :
|
||||
null
|
||||
}
|
||||
</TableRowCell>
|
||||
|
||||
|
@ -330,6 +353,7 @@ InteractiveImportRow.propTypes = {
|
|||
languages: PropTypes.arrayOf(PropTypes.object),
|
||||
releaseGroup: PropTypes.string,
|
||||
size: PropTypes.number.isRequired,
|
||||
customFormats: PropTypes.arrayOf(PropTypes.object),
|
||||
rejections: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
isReprocessing: PropTypes.bool,
|
||||
isSelected: PropTypes.bool,
|
||||
|
|
|
@ -62,6 +62,7 @@ class MovieHistoryRow extends Component {
|
|||
sourceTitle,
|
||||
quality,
|
||||
customFormats,
|
||||
customFormatScore,
|
||||
languages,
|
||||
qualityCutoffNotMet,
|
||||
date,
|
||||
|
@ -106,7 +107,7 @@ class MovieHistoryRow extends Component {
|
|||
</TableRowCell>
|
||||
|
||||
<TableRowCell key={name}>
|
||||
{formatCustomFormatScore(data.customFormatScore)}
|
||||
{formatCustomFormatScore(customFormatScore)}
|
||||
</TableRowCell>
|
||||
|
||||
<RelativeDateCellConnector
|
||||
|
@ -161,7 +162,8 @@ MovieHistoryRow.propTypes = {
|
|||
sourceTitle: PropTypes.string.isRequired,
|
||||
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
quality: PropTypes.object.isRequired,
|
||||
customFormats: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
customFormats: PropTypes.arrayOf(PropTypes.object),
|
||||
customFormatScore: PropTypes.number.isRequired,
|
||||
qualityCutoffNotMet: PropTypes.bool.isRequired,
|
||||
date: PropTypes.string.isRequired,
|
||||
data: PropTypes.object.isRequired,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
function formatCustomFormatScore(input) {
|
||||
function formatCustomFormatScore(input, customFormatsLength = 0) {
|
||||
const score = Number(input);
|
||||
|
||||
if (score > 0) {
|
||||
|
@ -10,7 +9,7 @@ function formatCustomFormatScore(input) {
|
|||
return score;
|
||||
}
|
||||
|
||||
return '';
|
||||
return customFormatsLength > 0 ? '+0' : '';
|
||||
}
|
||||
|
||||
export default formatCustomFormatScore;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
|
@ -9,7 +9,7 @@ using NzbDrone.Core.Test.Framework;
|
|||
namespace NzbDrone.Core.Test.CustomFormats
|
||||
{
|
||||
[TestFixture]
|
||||
public class CustomFormatsFixture : CoreTest
|
||||
public class CustomFormatsTestHelpers : CoreTest
|
||||
{
|
||||
private static List<CustomFormat> _customFormats { get; set; }
|
||||
|
|
@ -46,14 +46,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
ParsedMovieInfo = new ParsedMovieInfo { Quality = new QualityModel(Quality.DVD, new Revision(version: 2)) },
|
||||
};
|
||||
|
||||
CustomFormatsFixture.GivenCustomFormats(_format1, _format2);
|
||||
CustomFormatsTestHelpers.GivenCustomFormats(_format1, _format2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_allow_if_format_score_greater_than_min()
|
||||
{
|
||||
_remoteMovie.CustomFormats = new List<CustomFormat> { _format1 };
|
||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name);
|
||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name);
|
||||
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
||||
|
||||
Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeTrue();
|
||||
|
@ -63,7 +63,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
public void should_deny_if_format_score_not_greater_than_min()
|
||||
{
|
||||
_remoteMovie.CustomFormats = new List<CustomFormat> { _format2 };
|
||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name);
|
||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name);
|
||||
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
||||
|
||||
Console.WriteLine(_remoteMovie.CustomFormatScore);
|
||||
|
@ -76,7 +76,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
public void should_deny_if_format_score_not_greater_than_min_2()
|
||||
{
|
||||
_remoteMovie.CustomFormats = new List<CustomFormat> { _format2, _format1 };
|
||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name);
|
||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name);
|
||||
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
||||
|
||||
Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeFalse();
|
||||
|
@ -86,7 +86,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
public void should_allow_if_all_format_is_defined_in_profile()
|
||||
{
|
||||
_remoteMovie.CustomFormats = new List<CustomFormat> { _format2, _format1 };
|
||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name, _format2.Name);
|
||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name, _format2.Name);
|
||||
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
||||
|
||||
Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeTrue();
|
||||
|
@ -96,7 +96,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
public void should_deny_if_no_format_was_parsed_and_min_score_positive()
|
||||
{
|
||||
_remoteMovie.CustomFormats = new List<CustomFormat> { };
|
||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name, _format2.Name);
|
||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name, _format2.Name);
|
||||
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
||||
|
||||
Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeFalse();
|
||||
|
@ -106,7 +106,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
public void should_allow_if_no_format_was_parsed_min_score_is_zero()
|
||||
{
|
||||
_remoteMovie.CustomFormats = new List<CustomFormat> { };
|
||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(_format1.Name, _format2.Name);
|
||||
_remoteMovie.Movie.Profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_format1.Name, _format2.Name);
|
||||
_remoteMovie.Movie.Profile.MinFormatScore = 0;
|
||||
_remoteMovie.CustomFormatScore = _remoteMovie.Movie.Profile.CalculateCustomFormatScore(_remoteMovie.CustomFormats);
|
||||
|
||||
|
|
|
@ -40,8 +40,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
|
||||
private void GivenProfile(Profile profile)
|
||||
{
|
||||
CustomFormatsFixture.GivenCustomFormats();
|
||||
profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems();
|
||||
CustomFormatsTestHelpers.GivenCustomFormats();
|
||||
profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems();
|
||||
profile.MinFormatScore = 0;
|
||||
_remoteMovie.Movie.Profile = profile;
|
||||
|
||||
|
@ -74,7 +74,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
{
|
||||
_customFormat = new CustomFormat("My Format", new ResolutionSpecification { Value = (int)Resolution.R1080p }) { Id = 1 };
|
||||
|
||||
CustomFormatsFixture.GivenCustomFormats(_customFormat);
|
||||
CustomFormatsTestHelpers.GivenCustomFormats(_customFormat);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -157,7 +157,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
Cutoff = Quality.HDTV720p.Id,
|
||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||
MinFormatScore = 0,
|
||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems("My Format"),
|
||||
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems("My Format"),
|
||||
UpgradeAllowed = true
|
||||
});
|
||||
|
||||
|
|
|
@ -38,14 +38,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
Mocker.Resolve<UpgradableSpecification>();
|
||||
_upgradeHistory = Mocker.Resolve<HistorySpecification>();
|
||||
|
||||
CustomFormatsFixture.GivenCustomFormats();
|
||||
CustomFormatsTestHelpers.GivenCustomFormats();
|
||||
|
||||
_fakeMovie = Builder<Movie>.CreateNew()
|
||||
.With(c => c.Profile = new Profile
|
||||
{
|
||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||
Cutoff = Quality.Bluray1080p.Id,
|
||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems("None"),
|
||||
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems("None"),
|
||||
MinFormatScore = 0,
|
||||
UpgradeAllowed = true
|
||||
})
|
||||
|
@ -66,7 +66,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
.Returns(true);
|
||||
|
||||
Mocker.GetMock<ICustomFormatCalculationService>()
|
||||
.Setup(x => x.ParseCustomFormat(It.IsAny<MovieHistory>()))
|
||||
.Setup(x => x.ParseCustomFormat(It.IsAny<MovieHistory>(), It.IsAny<Movie>()))
|
||||
.Returns(new List<CustomFormat>());
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
{
|
||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||
Cutoff = Quality.Bluray1080p.Id,
|
||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems(),
|
||||
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(),
|
||||
MinFormatScore = 0
|
||||
};
|
||||
|
||||
|
@ -171,7 +171,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
_upgradableQuality = new QualityModel(Quality.WEBDL1080p, new Revision(version: 1));
|
||||
|
||||
Mocker.GetMock<ICustomFormatCalculationService>()
|
||||
.Setup(x => x.ParseCustomFormat(It.IsAny<MovieHistory>()))
|
||||
.Setup(x => x.ParseCustomFormat(It.IsAny<MovieHistory>(), It.IsAny<Movie>()))
|
||||
.Returns(new List<CustomFormat>());
|
||||
|
||||
GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _upgradableQuality, DateTime.UtcNow, MovieHistoryEventType.Grabbed);
|
||||
|
@ -186,7 +186,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
{
|
||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||
Cutoff = Quality.WEBDL1080p.Id,
|
||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems(),
|
||||
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(),
|
||||
MinFormatScore = 0
|
||||
};
|
||||
|
||||
|
@ -221,7 +221,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
{
|
||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||
Cutoff = Quality.WEBDL1080p.Id,
|
||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems(),
|
||||
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(),
|
||||
MinFormatScore = 0
|
||||
};
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
_customFormat1 = new CustomFormat("My Format 1", new LanguageSpecification { Value = (int)Language.English }) { Id = 1 };
|
||||
_customFormat2 = new CustomFormat("My Format 2", new LanguageSpecification { Value = (int)Language.French }) { Id = 2 };
|
||||
|
||||
CustomFormatsFixture.GivenCustomFormats(_customFormat1, _customFormat2);
|
||||
CustomFormatsTestHelpers.GivenCustomFormats(_customFormat1, _customFormat2);
|
||||
|
||||
Mocker.GetMock<IQualityDefinitionService>()
|
||||
.Setup(s => s.Get(It.IsAny<Quality>()))
|
||||
|
@ -62,7 +62,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
remoteMovie.Movie = Builder<Movie>.CreateNew().With(m => m.Profile = new Profile
|
||||
{
|
||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems(_customFormat1.Name, _customFormat2.Name),
|
||||
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_customFormat1.Name, _customFormat2.Name),
|
||||
MinFormatScore = 0
|
||||
})
|
||||
.With(m => m.Title = "A Movie")
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
CustomFormatsFixture.GivenCustomFormats(_customFormat1, _customFormat2);
|
||||
CustomFormatsTestHelpers.GivenCustomFormats(_customFormat1, _customFormat2);
|
||||
}
|
||||
|
||||
private void GivenAutoDownloadPropers(ProperDownloadTypes type)
|
||||
|
@ -73,7 +73,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
var profile = new Profile
|
||||
{
|
||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems(_customFormat1.Name, _customFormat2.Name),
|
||||
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(_customFormat1.Name, _customFormat2.Name),
|
||||
MinFormatScore = 0
|
||||
};
|
||||
|
||||
|
|
|
@ -32,13 +32,13 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
{
|
||||
Mocker.Resolve<UpgradableSpecification>();
|
||||
|
||||
CustomFormatsFixture.GivenCustomFormats();
|
||||
CustomFormatsTestHelpers.GivenCustomFormats();
|
||||
|
||||
_movie = Builder<Movie>.CreateNew()
|
||||
.With(e => e.Profile = new Profile
|
||||
{
|
||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems(),
|
||||
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(),
|
||||
MinFormatScore = 0,
|
||||
UpgradeAllowed = true
|
||||
})
|
||||
|
@ -58,7 +58,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
.Build();
|
||||
|
||||
Mocker.GetMock<ICustomFormatCalculationService>()
|
||||
.Setup(x => x.ParseCustomFormat(It.IsAny<ParsedMovieInfo>(), _movie))
|
||||
.Setup(x => x.ParseCustomFormat(It.IsAny<RemoteMovie>(), It.IsAny<long>()))
|
||||
.Returns(new List<CustomFormat>());
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
Mocker.Resolve<UpgradableSpecification>();
|
||||
_upgradeDisk = Mocker.Resolve<UpgradeDiskSpecification>();
|
||||
|
||||
CustomFormatsFixture.GivenCustomFormats();
|
||||
CustomFormatsTestHelpers.GivenCustomFormats();
|
||||
|
||||
_firstFile = new MovieFile { Quality = new QualityModel(Quality.Bluray1080p, new Revision(version: 2)), DateAdded = DateTime.Now };
|
||||
|
||||
|
@ -39,7 +39,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
.With(c => c.Profile = new Profile
|
||||
{
|
||||
Cutoff = Quality.Bluray1080p.Id, Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems(),
|
||||
FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(),
|
||||
MinFormatScore = 0
|
||||
})
|
||||
.With(e => e.MovieFile = _firstFile)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -54,6 +54,7 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
|
|||
Id = id,
|
||||
Title = "Movie.Title.2020.720p-Radarr",
|
||||
ParsedMovieInfo = new ParsedMovieInfo { MovieTitles = new List<string> { title }, Year = year },
|
||||
Release = Builder<ReleaseInfo>.CreateNew().Build(),
|
||||
MovieId = _movie.Id
|
||||
});
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace NzbDrone.Core.Test.MovieTests.MovieRepositoryTests
|
|||
var profile = new Profile
|
||||
{
|
||||
Items = Qualities.QualityFixture.GetDefaultQualities(Quality.Bluray1080p, Quality.DVD, Quality.HDTV720p),
|
||||
FormatItems = CustomFormatsFixture.GetDefaultFormatItems(),
|
||||
FormatItems = CustomFormatsTestHelpers.GetDefaultFormatItems(),
|
||||
MinFormatScore = 0,
|
||||
Cutoff = Quality.Bluray1080p.Id,
|
||||
Name = "TestProfile"
|
||||
|
|
|
@ -255,6 +255,18 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
parsed.Languages.Should().Contain(Language.German);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.2016.1080p.KORSUB.WEBRip.x264.AAC2.0-RADARR", "KORSUB")]
|
||||
[TestCase("Movie.Title.2016.1080p.KORSUBS.WEBRip.x264.AAC2.0-RADARR", "KORSUBS")]
|
||||
[TestCase("Movie Title 2017 HC 720p HDRiP DD5 1 x264-LEGi0N", "Generic Hardcoded Subs")]
|
||||
[TestCase("Movie.Title.2017.720p.SUBBED.HDRip.V2.XViD-26k.avi", "Generic Hardcoded Subs")]
|
||||
[TestCase("Movie.Title.2000.1080p.BlueRay.x264.DTS.RoSubbed-playHD", null)]
|
||||
[TestCase("Movie Title! 2018 [Web][MKV][h264][480p][AAC 2.0][Softsubs]", null)]
|
||||
[TestCase("Movie Title! 2019 [HorribleSubs][Web][MKV][h264][848x480][AAC 2.0][Softsubs(HorribleSubs)]", null)]
|
||||
public void should_parse_hardcoded_subs(string postTitle, string sub)
|
||||
{
|
||||
Parser.Parser.ParseMovieTitle(postTitle).HardcodedSubs.Should().Be(sub);
|
||||
}
|
||||
|
||||
[TestCase("That Italian Movie 2008 [tt1234567] 720p BluRay X264", "tt1234567")]
|
||||
[TestCase("That Italian Movie 2008 [tt12345678] 720p BluRay X264", "tt12345678")]
|
||||
public void should_parse_imdb_in_title(string postTitle, string imdb)
|
||||
|
|
|
@ -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,23 +0,0 @@
|
|||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Parser.Augmenters;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class AugmentWithFileSizeFixture : AugmentMovieInfoFixture<AugmentWithFileSize>
|
||||
{
|
||||
[Test]
|
||||
public void should_add_file_size()
|
||||
{
|
||||
var localMovie = new LocalMovie
|
||||
{
|
||||
Size = 1500
|
||||
};
|
||||
|
||||
var movieInfo = Subject.AugmentMovieInfo(MovieInfo, localMovie);
|
||||
movieInfo.ExtraInfo["Size"].Should().BeEquivalentTo(1500);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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,90 +0,0 @@
|
|||
// using FluentAssertions;
|
||||
// using NUnit.Framework;
|
||||
// using NzbDrone.Core.CustomFormats;
|
||||
// using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||
// using NzbDrone.Core.Parser;
|
||||
// using NzbDrone.Core.Parser.Augmenters;
|
||||
// using NzbDrone.Core.Qualities;
|
||||
|
||||
// namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests
|
||||
// {
|
||||
// [TestFixture]
|
||||
// public class AugmentWithMediaInfoFixture : AugmentMovieInfoFixture<AugmentWithMediaInfo>
|
||||
// {
|
||||
// [TestCase(Resolution.R720p, Source.BLURAY, Resolution.R1080p)]
|
||||
// [TestCase(Resolution.R1080p, Source.TV, Resolution.R720p)]
|
||||
// public void should_correct_resolution(Resolution resolution, Source source, Resolution realResolution)
|
||||
// {
|
||||
// var quality = new QualityModel
|
||||
// {
|
||||
// Source = source,
|
||||
// Resolution = resolution,
|
||||
// };
|
||||
// MovieInfo.Quality = quality;
|
||||
|
||||
// var realWidth = 480;
|
||||
// switch (realResolution)
|
||||
// {
|
||||
// case Resolution.R720p:
|
||||
// realWidth = 1280;
|
||||
// break;
|
||||
// case Resolution.R1080p:
|
||||
// realWidth = 1920;
|
||||
// break;
|
||||
// case Resolution.R2160p:
|
||||
// realWidth = 2160;
|
||||
// break;
|
||||
|
||||
// }
|
||||
|
||||
// var mediaInfo = new MediaInfoModel
|
||||
// {
|
||||
// Width = realWidth
|
||||
// };
|
||||
|
||||
// var movieInfo = Subject.AugmentMovieInfo(MovieInfo, mediaInfo);
|
||||
// movieInfo.Quality.Resolution.Should().BeEquivalentTo(realResolution);
|
||||
// movieInfo.Quality.QualityDetectionSource.Should().BeEquivalentTo(QualityDetectionSource.MediaInfo);
|
||||
// }
|
||||
|
||||
// [TestCase(Resolution.R720P, Source.BLURAY, Resolution.R1080P, Modifier.BRDISK)]
|
||||
// [TestCase(Resolution.R1080P, Source.BLURAY, Resolution.R720P, Modifier.REMUX)]
|
||||
// [TestCase(Resolution.R480P, Source.BLURAY, Resolution.R720P)]
|
||||
// [TestCase(Resolution.R720P, Source.DVD, Resolution.R480P)]
|
||||
// public void should_not_correct_resolution(Resolution resolution, Source source, Resolution realResolution, Modifier modifier = Modifier.NONE)
|
||||
// {
|
||||
// var quality = new QualityModel
|
||||
// {
|
||||
// Source = source,
|
||||
// Resolution = resolution,
|
||||
// Modifier = modifier,
|
||||
// };
|
||||
|
||||
// MovieInfo.Quality = quality;
|
||||
|
||||
// var realWidth = 480;
|
||||
// switch (realResolution)
|
||||
// {
|
||||
// case Resolution.R720P:
|
||||
// realWidth = 1280;
|
||||
// break;
|
||||
// case Resolution.R1080P:
|
||||
// realWidth = 1920;
|
||||
// break;
|
||||
// case Resolution.R2160P:
|
||||
// realWidth = 2160;
|
||||
// break;
|
||||
|
||||
// }
|
||||
|
||||
// var mediaInfo = new MediaInfoModel
|
||||
// {
|
||||
// Width = realWidth
|
||||
// };
|
||||
|
||||
// var movieInfo = Subject.AugmentMovieInfo(MovieInfo, mediaInfo);
|
||||
// movieInfo.Quality.Resolution.Should().BeEquivalentTo(resolution);
|
||||
// movieInfo.Quality.QualityDetectionSource.Should().BeEquivalentTo(QualityDetectionSource.Name);
|
||||
// }
|
||||
// }
|
||||
// }
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -194,20 +194,5 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||
Subject.Map(_umlautInfo, "", _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
|
||||
Subject.Map(_umlautAltInfo, "", _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_convert_original()
|
||||
{
|
||||
Subject.Map(_multiLanguageInfo, "", _movieSearchCriteria).RemoteMovie.ParsedMovieInfo.Languages.Should().Contain(Language.English);
|
||||
Subject.Map(_multiLanguageInfo, "", _movieSearchCriteria).RemoteMovie.ParsedMovieInfo.Languages.Should().Contain(Language.French);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_remove_original_as_already_exists()
|
||||
{
|
||||
Subject.Map(_multiLanguageWithOriginalInfo, "", _movieSearchCriteria).RemoteMovie.ParsedMovieInfo.Languages.Should().Contain(Language.English);
|
||||
Subject.Map(_multiLanguageWithOriginalInfo, "", _movieSearchCriteria).RemoteMovie.ParsedMovieInfo.Languages.Should().Contain(Language.French);
|
||||
Subject.Map(_multiLanguageWithOriginalInfo, "", _movieSearchCriteria).RemoteMovie.ParsedMovieInfo.Languages.Should().NotContain(Language.Original);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -452,18 +452,6 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
result.ResolutionDetectionSource.Should().Be(QualityDetectionSource.Name);
|
||||
}
|
||||
|
||||
[TestCase("Movie.Title.2016.1080p.KORSUB.WEBRip.x264.AAC2.0-RADARR", "KORSUB")]
|
||||
[TestCase("Movie.Title.2016.1080p.KORSUBS.WEBRip.x264.AAC2.0-RADARR", "KORSUBS")]
|
||||
[TestCase("Movie Title 2017 HC 720p HDRiP DD5 1 x264-LEGi0N", "Generic Hardcoded Subs")]
|
||||
[TestCase("Movie.Title.2017.720p.SUBBED.HDRip.V2.XViD-26k.avi", "Generic Hardcoded Subs")]
|
||||
[TestCase("Movie.Title.2000.1080p.BlueRay.x264.DTS.RoSubbed-playHD", null)]
|
||||
[TestCase("Movie Title! 2018 [Web][MKV][h264][480p][AAC 2.0][Softsubs]", null)]
|
||||
[TestCase("Movie Title! 2019 [HorribleSubs][Web][MKV][h264][848x480][AAC 2.0][Softsubs(HorribleSubs)]", null)]
|
||||
public void should_parse_hardcoded_subs(string postTitle, string sub)
|
||||
{
|
||||
QualityParser.ParseQuality(postTitle).HardcodedSubs.Should().Be(sub);
|
||||
}
|
||||
|
||||
[TestCase("Movie Title 2018 REPACK 720p x264 aAF", true)]
|
||||
[TestCase("Movie.Title.2018.REPACK.720p.x264-aAF", true)]
|
||||
[TestCase("Movie.Title.2018.PROPER.720p.x264-aAF", false)]
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace NzbDrone.Core.Test.Profiles
|
|||
{
|
||||
Items = Qualities.QualityFixture.GetDefaultQualities(Quality.Bluray1080p, Quality.DVD, Quality.HDTV720p),
|
||||
MinFormatScore = 0,
|
||||
FormatItems = CustomFormatsFixture.GetDefaultFormatItems(),
|
||||
FormatItems = CustomFormatsTestHelpers.GetDefaultFormatItems(),
|
||||
Cutoff = Quality.Bluray1080p.Id,
|
||||
Name = "TestProfile"
|
||||
};
|
||||
|
|
|
@ -170,9 +170,9 @@ namespace NzbDrone.Core.Test.Profiles
|
|||
var customFormat1 = new CustomFormat("My Format 1", new LanguageSpecification { Value = (int)Language.English }) { Id = 1 };
|
||||
var customFormat2 = new CustomFormat("My Format 2", new LanguageSpecification { Value = (int)Language.French }) { Id = 2 };
|
||||
|
||||
CustomFormatsFixture.GivenCustomFormats(customFormat1, customFormat2);
|
||||
CustomFormatsTestHelpers.GivenCustomFormats(customFormat1, customFormat2);
|
||||
|
||||
profile.FormatItems = CustomFormatsFixture.GetSampleFormatItems(customFormat2.Name);
|
||||
profile.FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems(customFormat2.Name);
|
||||
|
||||
Mocker.GetMock<IProfileRepository>()
|
||||
.Setup(s => s.Get(It.IsAny<int>()))
|
||||
|
|
|
@ -14,28 +14,133 @@ namespace NzbDrone.Core.CustomFormats
|
|||
{
|
||||
public interface ICustomFormatCalculationService
|
||||
{
|
||||
List<CustomFormat> ParseCustomFormat(ParsedMovieInfo movieInfo, Movie movie);
|
||||
List<CustomFormat> ParseCustomFormat(RemoteMovie remoteMovie, long size);
|
||||
List<CustomFormat> ParseCustomFormat(MovieFile movieFile, Movie movie);
|
||||
List<CustomFormat> ParseCustomFormat(MovieFile movieFile);
|
||||
List<CustomFormat> ParseCustomFormat(Blocklist blocklist);
|
||||
List<CustomFormat> ParseCustomFormat(MovieHistory history);
|
||||
List<CustomFormat> ParseCustomFormat(Blocklist blocklist, Movie movie);
|
||||
List<CustomFormat> ParseCustomFormat(MovieHistory history, Movie movie);
|
||||
List<CustomFormat> ParseCustomFormat(LocalMovie localMovie);
|
||||
}
|
||||
|
||||
public class CustomFormatCalculationService : ICustomFormatCalculationService
|
||||
{
|
||||
private readonly ICustomFormatService _formatService;
|
||||
private readonly IParsingService _parsingService;
|
||||
private readonly IMovieService _movieService;
|
||||
|
||||
public CustomFormatCalculationService(ICustomFormatService formatService,
|
||||
IParsingService parsingService,
|
||||
IMovieService movieService)
|
||||
public CustomFormatCalculationService(ICustomFormatService formatService)
|
||||
{
|
||||
_formatService = formatService;
|
||||
_parsingService = parsingService;
|
||||
_movieService = movieService;
|
||||
}
|
||||
|
||||
public static List<CustomFormat> ParseCustomFormat(ParsedMovieInfo movieInfo, List<CustomFormat> allCustomFormats)
|
||||
public List<CustomFormat> ParseCustomFormat(RemoteMovie remoteMovie, long size)
|
||||
{
|
||||
var input = new CustomFormatInput
|
||||
{
|
||||
MovieInfo = remoteMovie.ParsedMovieInfo,
|
||||
Movie = remoteMovie.Movie,
|
||||
Size = size,
|
||||
Languages = remoteMovie.Languages
|
||||
};
|
||||
|
||||
return ParseCustomFormat(input);
|
||||
}
|
||||
|
||||
public List<CustomFormat> ParseCustomFormat(MovieFile movieFile, Movie movie)
|
||||
{
|
||||
return ParseCustomFormat(movieFile, movie, _formatService.All());
|
||||
}
|
||||
|
||||
public List<CustomFormat> ParseCustomFormat(MovieFile movieFile)
|
||||
{
|
||||
return ParseCustomFormat(movieFile, movieFile.Movie, _formatService.All());
|
||||
}
|
||||
|
||||
public List<CustomFormat> ParseCustomFormat(Blocklist blocklist, Movie movie)
|
||||
{
|
||||
var parsed = Parser.Parser.ParseMovieTitle(blocklist.SourceTitle);
|
||||
|
||||
var movieInfo = new ParsedMovieInfo
|
||||
{
|
||||
MovieTitles = new List<string>() { movie.Title },
|
||||
SimpleReleaseTitle = parsed?.SimpleReleaseTitle ?? blocklist.SourceTitle.SimplifyReleaseTitle(),
|
||||
ReleaseTitle = parsed?.ReleaseTitle ?? blocklist.SourceTitle,
|
||||
Edition = parsed?.Edition,
|
||||
Quality = blocklist.Quality,
|
||||
Languages = blocklist.Languages,
|
||||
ReleaseGroup = parsed?.ReleaseGroup
|
||||
};
|
||||
|
||||
var input = new CustomFormatInput
|
||||
{
|
||||
MovieInfo = movieInfo,
|
||||
Movie = movie,
|
||||
Size = blocklist.Size ?? 0,
|
||||
IndexerFlags = blocklist.IndexerFlags,
|
||||
Languages = blocklist.Languages
|
||||
};
|
||||
|
||||
return ParseCustomFormat(input);
|
||||
}
|
||||
|
||||
public List<CustomFormat> ParseCustomFormat(MovieHistory history, Movie movie)
|
||||
{
|
||||
var parsed = Parser.Parser.ParseMovieTitle(history.SourceTitle);
|
||||
|
||||
long.TryParse(history.Data.GetValueOrDefault("size"), out var size);
|
||||
Enum.TryParse(history.Data.GetValueOrDefault("indexerFlags"), true, out IndexerFlags flags);
|
||||
|
||||
var movieInfo = new ParsedMovieInfo
|
||||
{
|
||||
MovieTitles = new List<string>() { movie.Title },
|
||||
SimpleReleaseTitle = parsed?.SimpleReleaseTitle ?? history.SourceTitle.SimplifyReleaseTitle(),
|
||||
ReleaseTitle = parsed?.ReleaseTitle ?? history.SourceTitle,
|
||||
Edition = parsed?.Edition,
|
||||
Quality = history.Quality,
|
||||
Languages = history.Languages,
|
||||
ReleaseGroup = parsed?.ReleaseGroup,
|
||||
};
|
||||
|
||||
var input = new CustomFormatInput
|
||||
{
|
||||
MovieInfo = movieInfo,
|
||||
Movie = movie,
|
||||
Size = size,
|
||||
IndexerFlags = flags,
|
||||
Languages = history.Languages
|
||||
};
|
||||
|
||||
return ParseCustomFormat(input);
|
||||
}
|
||||
|
||||
public List<CustomFormat> ParseCustomFormat(LocalMovie localMovie)
|
||||
{
|
||||
var episodeInfo = new ParsedMovieInfo
|
||||
{
|
||||
MovieTitles = new List<string>() { localMovie.Movie.Title },
|
||||
SimpleReleaseTitle = localMovie.SceneName.SimplifyReleaseTitle(),
|
||||
ReleaseTitle = localMovie.SceneName,
|
||||
Quality = localMovie.Quality,
|
||||
Edition = localMovie.Edition,
|
||||
Languages = localMovie.Languages,
|
||||
ReleaseGroup = localMovie.ReleaseGroup
|
||||
};
|
||||
|
||||
var input = new CustomFormatInput
|
||||
{
|
||||
MovieInfo = episodeInfo,
|
||||
Movie = localMovie.Movie,
|
||||
Size = localMovie.Size,
|
||||
Languages = localMovie.Languages
|
||||
};
|
||||
|
||||
return ParseCustomFormat(input);
|
||||
}
|
||||
|
||||
private List<CustomFormat> ParseCustomFormat(CustomFormatInput input)
|
||||
{
|
||||
return ParseCustomFormat(input, _formatService.All());
|
||||
}
|
||||
|
||||
private static List<CustomFormat> ParseCustomFormat(CustomFormatInput input, List<CustomFormat> allCustomFormats)
|
||||
{
|
||||
var matches = new List<CustomFormat>();
|
||||
|
||||
|
@ -45,7 +150,7 @@ namespace NzbDrone.Core.CustomFormats
|
|||
.GroupBy(t => t.GetType())
|
||||
.Select(g => new SpecificationMatchesGroup
|
||||
{
|
||||
Matches = g.ToDictionary(t => t, t => t.IsSatisfiedBy(movieInfo))
|
||||
Matches = g.ToDictionary(t => t, t => t.IsSatisfiedBy(input))
|
||||
})
|
||||
.ToList();
|
||||
|
||||
|
@ -58,7 +163,7 @@ namespace NzbDrone.Core.CustomFormats
|
|||
return matches;
|
||||
}
|
||||
|
||||
public static List<CustomFormat> ParseCustomFormat(MovieFile movieFile, List<CustomFormat> allCustomFormats)
|
||||
private static List<CustomFormat> ParseCustomFormat(MovieFile movieFile, Movie movie, List<CustomFormat> allCustomFormats)
|
||||
{
|
||||
var sceneName = string.Empty;
|
||||
if (movieFile.SceneName.IsNotNullOrWhiteSpace())
|
||||
|
@ -74,90 +179,29 @@ namespace NzbDrone.Core.CustomFormats
|
|||
sceneName = Path.GetFileName(movieFile.RelativePath);
|
||||
}
|
||||
|
||||
var info = new ParsedMovieInfo
|
||||
var movieInfo = new ParsedMovieInfo
|
||||
{
|
||||
MovieTitles = new List<string>() { movieFile.Movie.MovieMetadata.Value.Title },
|
||||
MovieTitles = new List<string>() { movie.Title },
|
||||
SimpleReleaseTitle = sceneName.SimplifyReleaseTitle(),
|
||||
Quality = movieFile.Quality,
|
||||
Languages = movieFile.Languages,
|
||||
ReleaseGroup = movieFile.ReleaseGroup,
|
||||
Edition = movieFile.Edition,
|
||||
Year = movieFile.Movie.MovieMetadata.Value.Year,
|
||||
ImdbId = movieFile.Movie.MovieMetadata.Value.ImdbId,
|
||||
ExtraInfo = new Dictionary<string, object>
|
||||
{
|
||||
{ "IndexerFlags", movieFile.IndexerFlags },
|
||||
{ "Size", movieFile.Size },
|
||||
{ "Filename", Path.GetFileName(movieFile.RelativePath) },
|
||||
{ "OriginalLanguage", movieFile.Movie.MovieMetadata.Value.OriginalLanguage }
|
||||
}
|
||||
ImdbId = movieFile.Movie.MovieMetadata.Value.ImdbId
|
||||
};
|
||||
|
||||
return ParseCustomFormat(info, allCustomFormats);
|
||||
}
|
||||
|
||||
public List<CustomFormat> ParseCustomFormat(ParsedMovieInfo movieInfo, Movie movie)
|
||||
{
|
||||
movieInfo = _parsingService.EnhanceMovieInfo(movieInfo, new List<object> { movie }) ?? movieInfo;
|
||||
return ParseCustomFormat(movieInfo, _formatService.All());
|
||||
}
|
||||
|
||||
public List<CustomFormat> ParseCustomFormat(MovieFile movieFile)
|
||||
{
|
||||
return ParseCustomFormat(movieFile, _formatService.All());
|
||||
}
|
||||
|
||||
public List<CustomFormat> ParseCustomFormat(Blocklist blocklist)
|
||||
{
|
||||
var movie = _movieService.GetMovie(blocklist.MovieId);
|
||||
var parsed = _parsingService.ParseMovieInfo(blocklist.SourceTitle, null);
|
||||
|
||||
var info = new ParsedMovieInfo
|
||||
var input = new CustomFormatInput
|
||||
{
|
||||
MovieTitles = new List<string>() { movie.MovieMetadata.Value.Title },
|
||||
SimpleReleaseTitle = parsed?.SimpleReleaseTitle ?? blocklist.SourceTitle.SimplifyReleaseTitle(),
|
||||
Quality = blocklist.Quality,
|
||||
Languages = blocklist.Languages,
|
||||
ReleaseGroup = parsed?.ReleaseGroup,
|
||||
Edition = parsed?.Edition,
|
||||
Year = movie.MovieMetadata.Value.Year,
|
||||
ImdbId = movie.MovieMetadata.Value.ImdbId,
|
||||
ExtraInfo = new Dictionary<string, object>
|
||||
{
|
||||
{ "IndexerFlags", blocklist.IndexerFlags },
|
||||
{ "Size", blocklist.Size }
|
||||
}
|
||||
MovieInfo = movieInfo,
|
||||
Movie = movie,
|
||||
Size = movieFile.Size,
|
||||
IndexerFlags = movieFile.IndexerFlags,
|
||||
Languages = movieFile.Languages,
|
||||
Filename = Path.GetFileName(movieFile.RelativePath)
|
||||
};
|
||||
|
||||
return ParseCustomFormat(info, movie);
|
||||
}
|
||||
|
||||
public List<CustomFormat> ParseCustomFormat(MovieHistory history)
|
||||
{
|
||||
var movie = _movieService.GetMovie(history.MovieId);
|
||||
var parsed = _parsingService.ParseMovieInfo(history.SourceTitle, null);
|
||||
|
||||
Enum.TryParse(history.Data.GetValueOrDefault("indexerFlags"), true, out IndexerFlags flags);
|
||||
long.TryParse(history.Data.GetValueOrDefault("size"), out var size);
|
||||
|
||||
var info = new ParsedMovieInfo
|
||||
{
|
||||
MovieTitles = new List<string>() { movie.MovieMetadata.Value.Title },
|
||||
SimpleReleaseTitle = parsed?.SimpleReleaseTitle ?? history.SourceTitle.SimplifyReleaseTitle(),
|
||||
Quality = history.Quality,
|
||||
Languages = history.Languages,
|
||||
ReleaseGroup = parsed?.ReleaseGroup,
|
||||
Edition = parsed?.Edition,
|
||||
Year = movie.MovieMetadata.Value.Year,
|
||||
ImdbId = movie.MovieMetadata.Value.ImdbId,
|
||||
ExtraInfo = new Dictionary<string, object>
|
||||
{
|
||||
{ "IndexerFlags", flags },
|
||||
{ "Size", size }
|
||||
}
|
||||
};
|
||||
|
||||
return ParseCustomFormat(info, movie);
|
||||
return ParseCustomFormat(input, allCustomFormats);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
22
src/NzbDrone.Core/CustomFormats/CustomFormatInput.cs
Normal file
22
src/NzbDrone.Core/CustomFormats/CustomFormatInput.cs
Normal file
|
@ -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>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,9 +21,9 @@ namespace NzbDrone.Core.CustomFormats
|
|||
|
||||
public abstract NzbDroneValidationResult Validate();
|
||||
|
||||
public bool IsSatisfiedBy(ParsedMovieInfo movieInfo)
|
||||
public bool IsSatisfiedBy(CustomFormatInput input)
|
||||
{
|
||||
var match = IsSatisfiedByWithoutNegate(movieInfo);
|
||||
var match = IsSatisfiedByWithoutNegate(input);
|
||||
if (Negate)
|
||||
{
|
||||
match = !match;
|
||||
|
@ -32,6 +32,6 @@ namespace NzbDrone.Core.CustomFormats
|
|||
return match;
|
||||
}
|
||||
|
||||
protected abstract bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo);
|
||||
protected abstract bool IsSatisfiedByWithoutNegate(CustomFormatInput input);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.CustomFormats
|
||||
{
|
||||
public class EditionSpecification : RegexSpecificationBase
|
||||
|
@ -8,9 +6,9 @@ namespace NzbDrone.Core.CustomFormats
|
|||
public override string ImplementationName => "Edition";
|
||||
public override string InfoLink => "https://wiki.servarr.com/radarr/settings#custom-formats-2";
|
||||
|
||||
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
||||
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
|
||||
{
|
||||
return MatchString(movieInfo.Edition);
|
||||
return MatchString(input.MovieInfo.Edition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,6 @@ namespace NzbDrone.Core.CustomFormats
|
|||
NzbDroneValidationResult Validate();
|
||||
|
||||
ICustomFormatSpecification Clone();
|
||||
bool IsSatisfiedBy(ParsedMovieInfo movieInfo);
|
||||
bool IsSatisfiedBy(CustomFormatInput input);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,10 +32,9 @@ namespace NzbDrone.Core.CustomFormats
|
|||
[FieldDefinition(1, Label = "Flag", Type = FieldType.Select, SelectOptions = typeof(IndexerFlags))]
|
||||
public int Value { get; set; }
|
||||
|
||||
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
||||
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
|
||||
{
|
||||
var flags = movieInfo?.ExtraInfo?.GetValueOrDefault("IndexerFlags") as IndexerFlags?;
|
||||
return flags?.HasFlag((IndexerFlags)Value) == true;
|
||||
return input.IndexerFlags.HasFlag((IndexerFlags)Value) == true;
|
||||
}
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
|
|
|
@ -32,12 +32,12 @@ namespace NzbDrone.Core.CustomFormats
|
|||
[FieldDefinition(1, Label = "Language", Type = FieldType.Select, SelectOptions = typeof(LanguageFieldConverter))]
|
||||
public int Value { get; set; }
|
||||
|
||||
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
||||
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
|
||||
{
|
||||
var comparedLanguage = movieInfo != null && Value == Language.Original.Id && movieInfo.ExtraInfo.ContainsKey("OriginalLanguage")
|
||||
? (Language)movieInfo.ExtraInfo["OriginalLanguage"]
|
||||
var comparedLanguage = input.MovieInfo != null && Value == Language.Original.Id && input.Movie.MovieMetadata.Value.OriginalLanguage != Language.Unknown
|
||||
? input.Movie.MovieMetadata.Value.OriginalLanguage
|
||||
: (Language)Value;
|
||||
return movieInfo?.Languages?.Contains(comparedLanguage) ?? false;
|
||||
return input?.Languages?.Contains(comparedLanguage) ?? false;
|
||||
}
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
|
|
|
@ -32,9 +32,9 @@ namespace NzbDrone.Core.CustomFormats
|
|||
[FieldDefinition(1, Label = "Quality Modifier", Type = FieldType.Select, SelectOptions = typeof(Modifier))]
|
||||
public int Value { get; set; }
|
||||
|
||||
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
||||
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
|
||||
{
|
||||
return (movieInfo?.Quality?.Quality?.Modifier ?? (int)Modifier.NONE) == (Modifier)Value;
|
||||
return (input.MovieInfo?.Quality?.Quality?.Modifier ?? (int)Modifier.NONE) == (Modifier)Value;
|
||||
}
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
|
|
|
@ -8,9 +8,9 @@ namespace NzbDrone.Core.CustomFormats
|
|||
public override string ImplementationName => "Release Group";
|
||||
public override string InfoLink => "https://wiki.servarr.com/radarr/settings#custom-formats-2";
|
||||
|
||||
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
||||
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
|
||||
{
|
||||
return MatchString(movieInfo?.ReleaseGroup);
|
||||
return MatchString(input.MovieInfo?.ReleaseGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,11 +9,9 @@ namespace NzbDrone.Core.CustomFormats
|
|||
public override string ImplementationName => "Release Title";
|
||||
public override string InfoLink => "https://wiki.servarr.com/radarr/settings#custom-formats-2";
|
||||
|
||||
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
||||
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
|
||||
{
|
||||
var filename = (string)movieInfo?.ExtraInfo?.GetValueOrDefault("Filename");
|
||||
|
||||
return MatchString(movieInfo?.SimpleReleaseTitle) || MatchString(filename);
|
||||
return MatchString(input.MovieInfo?.SimpleReleaseTitle) || MatchString(input.Filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@ namespace NzbDrone.Core.CustomFormats
|
|||
[FieldDefinition(1, Label = "Resolution", Type = FieldType.Select, SelectOptions = typeof(Resolution))]
|
||||
public int Value { get; set; }
|
||||
|
||||
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
||||
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
|
||||
{
|
||||
return (movieInfo?.Quality?.Quality?.Resolution ?? (int)Resolution.Unknown) == Value;
|
||||
return (input.MovieInfo?.Quality?.Quality?.Resolution ?? (int)Resolution.Unknown) == Value;
|
||||
}
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
|
|
|
@ -28,9 +28,9 @@ namespace NzbDrone.Core.CustomFormats
|
|||
[FieldDefinition(1, Label = "Maximum Size", HelpText = "Release must be less than or equal to this size", Unit = "GB", Type = FieldType.Number)]
|
||||
public double Max { get; set; }
|
||||
|
||||
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
||||
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
|
||||
{
|
||||
var size = (movieInfo?.ExtraInfo?.GetValueOrDefault("Size", 0.0) as long?) ?? 0;
|
||||
var size = input.Size;
|
||||
|
||||
return size > Min.Gigabytes() && size <= Max.Gigabytes();
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@ namespace NzbDrone.Core.CustomFormats
|
|||
[FieldDefinition(1, Label = "Source", Type = FieldType.Select, SelectOptions = typeof(Source))]
|
||||
public int Value { get; set; }
|
||||
|
||||
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
||||
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
|
||||
{
|
||||
return (movieInfo?.Quality?.Quality?.Source ?? (int)Source.UNKNOWN) == (Source)Value;
|
||||
return (input.MovieInfo?.Quality?.Quality?.Source ?? (int)Source.UNKNOWN) == (Source)Value;
|
||||
}
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
|
|
|
@ -8,6 +8,7 @@ using NzbDrone.Common.Serializer;
|
|||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.CustomFormats;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Download.Aggregation;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Parser;
|
||||
|
@ -28,18 +29,21 @@ namespace NzbDrone.Core.DecisionEngine
|
|||
private readonly IParsingService _parsingService;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly ICustomFormatCalculationService _formatCalculator;
|
||||
private readonly IRemoteMovieAggregationService _aggregationService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public DownloadDecisionMaker(IEnumerable<IDecisionEngineSpecification> specifications,
|
||||
IParsingService parsingService,
|
||||
IConfigService configService,
|
||||
ICustomFormatCalculationService formatCalculator,
|
||||
IRemoteMovieAggregationService aggregationService,
|
||||
Logger logger)
|
||||
{
|
||||
_specifications = specifications;
|
||||
_parsingService = parsingService;
|
||||
_configService = configService;
|
||||
_formatCalculator = formatCalculator;
|
||||
_aggregationService = aggregationService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
@ -104,11 +108,11 @@ namespace NzbDrone.Core.DecisionEngine
|
|||
|
||||
result.ReleaseName = report.Title;
|
||||
var remoteMovie = result.RemoteMovie;
|
||||
remoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(parsedMovieInfo, result?.Movie);
|
||||
remoteMovie.CustomFormatScore = remoteMovie?.Movie?.Profile?.CalculateCustomFormatScore(remoteMovie.CustomFormats) ?? 0;
|
||||
remoteMovie.Release = report;
|
||||
remoteMovie.MappingResult = result.MappingResultType;
|
||||
|
||||
_aggregationService.Augment(remoteMovie);
|
||||
|
||||
if (result.MappingResultType != MappingResultType.Success)
|
||||
{
|
||||
var rejection = result.ToRejection();
|
||||
|
@ -116,33 +120,11 @@ namespace NzbDrone.Core.DecisionEngine
|
|||
}
|
||||
else
|
||||
{
|
||||
if (parsedMovieInfo.Quality.HardcodedSubs.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
// remoteMovie.DownloadAllowed = true;
|
||||
if (_configService.AllowHardcodedSubs)
|
||||
{
|
||||
decision = GetDecisionForReport(remoteMovie, searchCriteria);
|
||||
}
|
||||
else
|
||||
{
|
||||
var whitelisted = _configService.WhitelistedHardcodedSubs.Split(',');
|
||||
_logger.Debug("Testing: {0}", whitelisted);
|
||||
if (whitelisted != null && whitelisted.Any(t => (parsedMovieInfo.Quality.HardcodedSubs.ToLower().Contains(t.ToLower()) && t.IsNotNullOrWhiteSpace())))
|
||||
{
|
||||
decision = GetDecisionForReport(remoteMovie, searchCriteria);
|
||||
}
|
||||
else
|
||||
{
|
||||
decision = new DownloadDecision(remoteMovie, new Rejection("Hardcoded subs found: " + parsedMovieInfo.Quality.HardcodedSubs));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// _aggregationService.Augment(remoteMovie);
|
||||
remoteMovie.DownloadAllowed = remoteMovie.Movie != null;
|
||||
decision = GetDecisionForReport(remoteMovie, searchCriteria);
|
||||
}
|
||||
remoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(remoteMovie, remoteMovie.Release.Size);
|
||||
remoteMovie.CustomFormatScore = remoteMovie?.Movie?.Profile?.CalculateCustomFormatScore(remoteMovie.CustomFormats) ?? 0;
|
||||
|
||||
remoteMovie.DownloadAllowed = remoteMovie.Movie != null;
|
||||
decision = GetDecisionForReport(remoteMovie, searchCriteria);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -50,7 +50,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
|||
continue;
|
||||
}
|
||||
|
||||
var customFormats = _formatService.ParseCustomFormat(remoteMovie.ParsedMovieInfo, subject.Movie);
|
||||
var customFormats = _formatService.ParseCustomFormat(remoteMovie, (long)queueItem.Size);
|
||||
|
||||
_logger.Debug("Checking if existing release in queue meets cutoff. Queued quality is: {0} - {1}",
|
||||
remoteMovie.ParsedMovieInfo.Quality,
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
|
|||
|
||||
if (mostRecent != null && mostRecent.EventType == MovieHistoryEventType.Grabbed)
|
||||
{
|
||||
var customFormats = _formatService.ParseCustomFormat(mostRecent);
|
||||
var customFormats = _formatService.ParseCustomFormat(mostRecent, subject.Movie);
|
||||
|
||||
var cutoffUnmet = _upgradableSpecification.CutoffNotMet(subject.Movie.Profile,
|
||||
mostRecent.Quality,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -58,7 +58,7 @@ namespace NzbDrone.Core.Download.Clients.Flood
|
|||
result.Add(remoteMovie.ParsedMovieInfo.Quality.Quality.ToString());
|
||||
break;
|
||||
case (int)AdditionalTags.Languages:
|
||||
result.UnionWith(remoteMovie.ParsedMovieInfo.Languages.ConvertAll(language => language.ToString()));
|
||||
result.UnionWith(remoteMovie.Languages.ConvertAll(language => language.ToString()));
|
||||
break;
|
||||
case (int)AdditionalTags.ReleaseGroup:
|
||||
result.Add(remoteMovie.ParsedMovieInfo.ReleaseGroup);
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace NzbDrone.Core.Download
|
|||
var downloadIgnoredEvent = new DownloadIgnoredEvent
|
||||
{
|
||||
MovieId = movie.Id,
|
||||
Languages = trackedDownload.RemoteMovie.ParsedMovieInfo.Languages,
|
||||
Languages = trackedDownload.RemoteMovie.Languages,
|
||||
Quality = trackedDownload.RemoteMovie.ParsedMovieInfo.Quality,
|
||||
SourceTitle = trackedDownload.DownloadItem.Title,
|
||||
DownloadClientInfo = trackedDownload.DownloadItem.DownloadClientInfo,
|
||||
|
|
|
@ -7,6 +7,7 @@ using NzbDrone.Common.Extensions;
|
|||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.CustomFormats;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Download.Aggregation;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Jobs;
|
||||
using NzbDrone.Core.Languages;
|
||||
|
@ -44,6 +45,7 @@ namespace NzbDrone.Core.Download.Pending
|
|||
private readonly IDelayProfileService _delayProfileService;
|
||||
private readonly ITaskManager _taskManager;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly IRemoteMovieAggregationService _aggregationService;
|
||||
private readonly ICustomFormatCalculationService _formatCalculator;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly Logger _logger;
|
||||
|
@ -55,6 +57,7 @@ namespace NzbDrone.Core.Download.Pending
|
|||
IDelayProfileService delayProfileService,
|
||||
ITaskManager taskManager,
|
||||
IConfigService configService,
|
||||
IRemoteMovieAggregationService aggregationService,
|
||||
ICustomFormatCalculationService formatCalculator,
|
||||
IEventAggregator eventAggregator,
|
||||
Logger logger)
|
||||
|
@ -66,6 +69,7 @@ namespace NzbDrone.Core.Download.Pending
|
|||
_delayProfileService = delayProfileService;
|
||||
_taskManager = taskManager;
|
||||
_configService = configService;
|
||||
_aggregationService = aggregationService;
|
||||
_formatCalculator = formatCalculator;
|
||||
_eventAggregator = eventAggregator;
|
||||
_logger = logger;
|
||||
|
@ -163,8 +167,6 @@ namespace NzbDrone.Core.Download.Pending
|
|||
{
|
||||
if (pendingRelease.RemoteMovie != null)
|
||||
{
|
||||
pendingRelease.RemoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(pendingRelease.ParsedMovieInfo, pendingRelease.RemoteMovie.Movie);
|
||||
|
||||
var ect = pendingRelease.Release.PublishDate.AddMinutes(GetDelay(pendingRelease.RemoteMovie));
|
||||
|
||||
if (ect < nextRssSync.Value)
|
||||
|
@ -188,7 +190,7 @@ namespace NzbDrone.Core.Download.Pending
|
|||
Id = GetQueueId(pendingRelease, pendingRelease.RemoteMovie.Movie),
|
||||
Movie = pendingRelease.RemoteMovie.Movie,
|
||||
Quality = pendingRelease.RemoteMovie.ParsedMovieInfo?.Quality ?? new QualityModel(),
|
||||
Languages = pendingRelease.RemoteMovie.ParsedMovieInfo?.Languages ?? new List<Language>(),
|
||||
Languages = pendingRelease.RemoteMovie.Languages,
|
||||
Title = pendingRelease.Title,
|
||||
Size = pendingRelease.RemoteMovie.Release.Size,
|
||||
Sizeleft = pendingRelease.RemoteMovie.Release.Size,
|
||||
|
@ -296,6 +298,9 @@ namespace NzbDrone.Core.Download.Pending
|
|||
Release = release.Release
|
||||
};
|
||||
|
||||
_aggregationService.Augment(release.RemoteMovie);
|
||||
release.RemoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(release.RemoteMovie, release.Release.Size);
|
||||
|
||||
result.Add(release);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ using NzbDrone.Common.Cache;
|
|||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.CustomFormats;
|
||||
using NzbDrone.Core.Download.Aggregation;
|
||||
using NzbDrone.Core.Download.History;
|
||||
using NzbDrone.Core.History;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
|
@ -32,6 +33,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
|
|||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly IDownloadHistoryService _downloadHistoryService;
|
||||
private readonly IConfigService _config;
|
||||
private readonly IRemoteMovieAggregationService _aggregationService;
|
||||
private readonly ICustomFormatCalculationService _formatCalculator;
|
||||
private readonly Logger _logger;
|
||||
private readonly ICached<TrackedDownload> _cache;
|
||||
|
@ -40,6 +42,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
|
|||
ICacheManager cacheManager,
|
||||
IHistoryService historyService,
|
||||
IConfigService config,
|
||||
IRemoteMovieAggregationService aggregationService,
|
||||
ICustomFormatCalculationService formatCalculator,
|
||||
IEventAggregator eventAggregator,
|
||||
IDownloadHistoryService downloadHistoryService,
|
||||
|
@ -49,6 +52,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
|
|||
_historyService = historyService;
|
||||
_cache = cacheManager.GetCache<TrackedDownload>(GetType());
|
||||
_config = config;
|
||||
_aggregationService = aggregationService;
|
||||
_formatCalculator = formatCalculator;
|
||||
_eventAggregator = eventAggregator;
|
||||
_downloadHistoryService = downloadHistoryService;
|
||||
|
@ -118,6 +122,8 @@ namespace NzbDrone.Core.Download.TrackedDownloads
|
|||
if (parsedMovieInfo != null)
|
||||
{
|
||||
trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie;
|
||||
|
||||
_aggregationService.Augment(trackedDownload.RemoteMovie);
|
||||
}
|
||||
|
||||
var downloadHistory = _downloadHistoryService.GetLatestDownloadHistoryItem(downloadItem.DownloadId);
|
||||
|
@ -151,7 +157,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
|
|||
// Calculate custom formats
|
||||
if (trackedDownload.RemoteMovie != null)
|
||||
{
|
||||
trackedDownload.RemoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(parsedMovieInfo, trackedDownload.RemoteMovie.Movie);
|
||||
trackedDownload.RemoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(trackedDownload.RemoteMovie, downloadItem.TotalSize);
|
||||
}
|
||||
|
||||
// Track it so it can be displayed in the queue even though we can't determine which movie it is for
|
||||
|
@ -192,6 +198,8 @@ namespace NzbDrone.Core.Download.TrackedDownloads
|
|||
var parsedMovieInfo = Parser.Parser.ParseMovieTitle(trackedDownload.DownloadItem.Title);
|
||||
|
||||
trackedDownload.RemoteMovie = parsedMovieInfo == null ? null : _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie;
|
||||
|
||||
_aggregationService.Augment(trackedDownload.RemoteMovie);
|
||||
}
|
||||
|
||||
private static TrackedDownloadState GetStateFromHistory(DownloadHistoryEventType eventType)
|
||||
|
|
|
@ -132,7 +132,7 @@ namespace NzbDrone.Core.History
|
|||
EventType = MovieHistoryEventType.Grabbed,
|
||||
Date = DateTime.UtcNow,
|
||||
Quality = message.Movie.ParsedMovieInfo.Quality,
|
||||
Languages = message.Movie.ParsedMovieInfo.Languages,
|
||||
Languages = message.Movie.Languages,
|
||||
SourceTitle = message.Movie.Release.Title,
|
||||
DownloadId = message.DownloadId,
|
||||
MovieId = message.Movie.Movie.Id
|
||||
|
@ -203,6 +203,7 @@ namespace NzbDrone.Core.History
|
|||
history.Data.Add("DownloadClient", message.DownloadClientInfo?.Type);
|
||||
history.Data.Add("DownloadClientName", message.DownloadClientInfo?.Name);
|
||||
history.Data.Add("ReleaseGroup", message.MovieInfo.ReleaseGroup);
|
||||
history.Data.Add("CustomFormatScore", message.MovieInfo.CustomFormatScore.ToString());
|
||||
|
||||
_historyRepository.Insert(history);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.CustomFormats;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.MediaFiles.MovieImport.Aggregation;
|
||||
|
@ -30,6 +31,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport
|
|||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IDetectSample _detectSample;
|
||||
private readonly IParsingService _parsingService;
|
||||
private readonly ICustomFormatCalculationService _formatCalculator;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public ImportDecisionMaker(IEnumerable<IImportDecisionEngineSpecification> specifications,
|
||||
|
@ -38,6 +40,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport
|
|||
IDiskProvider diskProvider,
|
||||
IDetectSample detectSample,
|
||||
IParsingService parsingService,
|
||||
ICustomFormatCalculationService formatCalculator,
|
||||
Logger logger)
|
||||
{
|
||||
_specifications = specifications;
|
||||
|
@ -46,6 +49,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport
|
|||
_diskProvider = diskProvider;
|
||||
_detectSample = detectSample;
|
||||
_parsingService = parsingService;
|
||||
_formatCalculator = formatCalculator;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
@ -75,7 +79,6 @@ namespace NzbDrone.Core.MediaFiles.MovieImport
|
|||
if (downloadClientItem != null)
|
||||
{
|
||||
downloadClientItemInfo = Parser.Parser.ParseMovieTitle(downloadClientItem.Title);
|
||||
downloadClientItemInfo = _parsingService.EnhanceMovieInfo(downloadClientItemInfo);
|
||||
}
|
||||
|
||||
var nonSampleVideoFileCount = GetNonSampleVideoFileCount(newFiles, movie.MovieMetadata);
|
||||
|
@ -115,11 +118,6 @@ namespace NzbDrone.Core.MediaFiles.MovieImport
|
|||
|
||||
var fileMovieInfo = Parser.Parser.ParseMoviePath(localMovie.Path);
|
||||
|
||||
if (fileMovieInfo != null)
|
||||
{
|
||||
fileMovieInfo = _parsingService.EnhanceMovieInfo(fileMovieInfo);
|
||||
}
|
||||
|
||||
localMovie.FileMovieInfo = fileMovieInfo;
|
||||
localMovie.Size = _diskProvider.GetFileSize(localMovie.Path);
|
||||
|
||||
|
@ -133,6 +131,9 @@ namespace NzbDrone.Core.MediaFiles.MovieImport
|
|||
}
|
||||
else
|
||||
{
|
||||
localMovie.CustomFormats = _formatCalculator.ParseCustomFormat(localMovie);
|
||||
localMovie.CustomFormatScore = localMovie.Movie.Profile?.CalculateCustomFormatScore(localMovie.CustomFormats) ?? 0;
|
||||
|
||||
decision = GetDecision(localMovie, downloadClientItem);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.CustomFormats;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Movies;
|
||||
|
@ -17,7 +18,13 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
|
|||
public List<Language> Languages { get; set; }
|
||||
public string ReleaseGroup { get; set; }
|
||||
public string DownloadId { get; set; }
|
||||
public List<CustomFormat> CustomFormats { get; set; }
|
||||
public IEnumerable<Rejection> Rejections { get; set; }
|
||||
public Movie Movie { get; set; }
|
||||
|
||||
public ManualImportItem()
|
||||
{
|
||||
CustomFormats = new List<CustomFormat>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ using NLog;
|
|||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Instrumentation.Extensions;
|
||||
using NzbDrone.Core.CustomFormats;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.TrackedDownloads;
|
||||
|
@ -37,6 +38,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
|
|||
private readonly IAggregationService _aggregationService;
|
||||
private readonly ITrackedDownloadService _trackedDownloadService;
|
||||
private readonly IDownloadedMovieImportService _downloadedMovieImportService;
|
||||
private readonly ICustomFormatCalculationService _formatCalculator;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly Logger _logger;
|
||||
|
||||
|
@ -49,6 +51,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
|
|||
IImportApprovedMovie importApprovedMovie,
|
||||
ITrackedDownloadService trackedDownloadService,
|
||||
IDownloadedMovieImportService downloadedMovieImportService,
|
||||
ICustomFormatCalculationService formatCalculator,
|
||||
IEventAggregator eventAggregator,
|
||||
Logger logger)
|
||||
{
|
||||
|
@ -61,6 +64,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
|
|||
_importApprovedMovie = importApprovedMovie;
|
||||
_trackedDownloadService = trackedDownloadService;
|
||||
_downloadedMovieImportService = downloadedMovieImportService;
|
||||
_formatCalculator = formatCalculator;
|
||||
_eventAggregator = eventAggregator;
|
||||
_logger = logger;
|
||||
}
|
||||
|
@ -291,6 +295,8 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
|
|||
if (decision.LocalMovie.Movie != null)
|
||||
{
|
||||
item.Movie = decision.LocalMovie.Movie;
|
||||
|
||||
item.CustomFormats = _formatCalculator.ParseCustomFormat(decision.LocalMovie);
|
||||
}
|
||||
|
||||
item.Quality = decision.LocalMovie.Quality;
|
||||
|
@ -343,7 +349,10 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
|
|||
localMovie.SceneSource = !existingFile;
|
||||
}
|
||||
|
||||
// Augment movie file so imported files have all additional information an automatic import would
|
||||
localMovie = _aggregationService.Augment(localMovie, trackedDownload?.DownloadItem);
|
||||
localMovie.CustomFormats = _formatCalculator.ParseCustomFormat(localMovie);
|
||||
localMovie.CustomFormatScore = localMovie.Movie.Profile?.CalculateCustomFormatScore(localMovie.CustomFormats) ?? 0;
|
||||
|
||||
// Apply the user-chosen values.
|
||||
localMovie.Movie = movie;
|
||||
|
|
|
@ -118,6 +118,8 @@ namespace NzbDrone.Core.Notifications.CustomScript
|
|||
environmentVariables.Add("Radarr_MovieFile_MediaInfo_Subtitles", movieFile.MediaInfo.Subtitles.ConcatToString(" / "));
|
||||
environmentVariables.Add("Radarr_MovieFile_MediaInfo_VideoCodec", MediaInfoFormatter.FormatVideoCodec(movieFile.MediaInfo, null));
|
||||
environmentVariables.Add("Radarr_MovieFile_MediaInfo_VideoDynamicRangeType", MediaInfoFormatter.FormatVideoDynamicRangeType(movieFile.MediaInfo));
|
||||
environmentVariables.Add("Radarr_MovieFile_CustomFormat", string.Join("|", message.MovieInfo.CustomFormats));
|
||||
environmentVariables.Add("Radarr_MovieFile_CustomFormatScore", message.MovieInfo.CustomFormatScore.ToString());
|
||||
|
||||
if (message.OldMovieFiles.Any())
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@ using System.Collections.Generic;
|
|||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Movies;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.Notifications
|
||||
{
|
||||
|
@ -9,6 +10,7 @@ namespace NzbDrone.Core.Notifications
|
|||
{
|
||||
public string Message { get; set; }
|
||||
public Movie Movie { get; set; }
|
||||
public LocalMovie MovieInfo { get; set; }
|
||||
public MovieFile MovieFile { get; set; }
|
||||
public List<MovieFile> OldMovieFiles { get; set; }
|
||||
public string SourcePath { get; set; }
|
||||
|
|
|
@ -130,6 +130,7 @@ namespace NzbDrone.Core.Notifications
|
|||
var downloadMessage = new DownloadMessage
|
||||
{
|
||||
Message = GetMessage(message.MovieInfo.Movie, message.MovieInfo.Quality),
|
||||
MovieInfo = message.MovieInfo,
|
||||
MovieFile = message.ImportedMovie,
|
||||
Movie = message.MovieInfo.Movie,
|
||||
OldMovieFiles = message.OldFiles,
|
||||
|
|
|
@ -36,7 +36,8 @@ namespace NzbDrone.Core.Notifications.Webhook
|
|||
Release = new WebhookRelease(quality, remoteMovie),
|
||||
DownloadClient = message.DownloadClientName,
|
||||
DownloadClientType = message.DownloadClientType,
|
||||
DownloadId = message.DownloadId
|
||||
DownloadId = message.DownloadId,
|
||||
CustomFormatInfo = new WebhookCustomFormatInfo(remoteMovie.CustomFormats, remoteMovie.CustomFormatScore)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -55,7 +56,8 @@ namespace NzbDrone.Core.Notifications.Webhook
|
|||
IsUpgrade = message.OldMovieFiles.Any(),
|
||||
DownloadClient = message.DownloadClientInfo?.Name,
|
||||
DownloadClientType = message.DownloadClientInfo?.Type,
|
||||
DownloadId = message.DownloadId
|
||||
DownloadId = message.DownloadId,
|
||||
CustomFormatInfo = new WebhookCustomFormatInfo(message.MovieInfo.CustomFormats, message.MovieInfo.CustomFormatScore)
|
||||
};
|
||||
|
||||
if (message.OldMovieFiles.Any())
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,5 +8,6 @@ namespace NzbDrone.Core.Notifications.Webhook
|
|||
public string DownloadClient { get; set; }
|
||||
public string DownloadClientType { get; set; }
|
||||
public string DownloadId { get; set; }
|
||||
public WebhookCustomFormatInfo CustomFormatInfo { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,5 +12,6 @@ namespace NzbDrone.Core.Notifications.Webhook
|
|||
public string DownloadClientType { get; set; }
|
||||
public string DownloadId { get; set; }
|
||||
public List<WebhookMovieFile> DeletedFiles { get; set; }
|
||||
public WebhookCustomFormatInfo CustomFormatInfo { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace NzbDrone.Core.Organizer
|
|||
private readonly IQualityDefinitionService _qualityDefinitionService;
|
||||
private readonly IUpdateMediaInfo _mediaInfoUpdater;
|
||||
private readonly IMovieTranslationService _movieTranslationService;
|
||||
private readonly ICustomFormatService _formatService;
|
||||
private readonly ICustomFormatCalculationService _formatCalculator;
|
||||
private readonly Logger _logger;
|
||||
|
||||
private static readonly Regex TitleRegex = new Regex(@"(?<tag>\{(?:imdb-|edition-))?\{(?<prefix>[- ._\[(]*)(?<token>(?:[a-z0-9]+)(?:(?<separator>[- ._]+)(?:[a-z0-9]+))?)(?::(?<customFormat>[a-z0-9|+-]+(?<!-)))?(?<suffix>[-} ._)\]]*)\}",
|
||||
|
@ -83,14 +83,14 @@ namespace NzbDrone.Core.Organizer
|
|||
IQualityDefinitionService qualityDefinitionService,
|
||||
IUpdateMediaInfo mediaInfoUpdater,
|
||||
IMovieTranslationService movieTranslationService,
|
||||
ICustomFormatService formatService,
|
||||
ICustomFormatCalculationService formatCalculator,
|
||||
Logger logger)
|
||||
{
|
||||
_namingConfigService = namingConfigService;
|
||||
_qualityDefinitionService = qualityDefinitionService;
|
||||
_mediaInfoUpdater = mediaInfoUpdater;
|
||||
_movieTranslationService = movieTranslationService;
|
||||
_formatService = formatService;
|
||||
_formatCalculator = formatCalculator;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
@ -397,7 +397,7 @@ namespace NzbDrone.Core.Organizer
|
|||
if (customFormats == null)
|
||||
{
|
||||
movieFile.Movie = movie;
|
||||
customFormats = CustomFormatCalculationService.ParseCustomFormat(movieFile, _formatService.All());
|
||||
customFormats = _formatCalculator.ParseCustomFormat(movieFile, movie);
|
||||
}
|
||||
|
||||
tokenHandlers["{Custom Formats}"] = m => string.Join(" ", customFormats.Where(x => x.IncludeCustomFormatWhenRenaming));
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
using System;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.Parser.Augmenters
|
||||
{
|
||||
public class AugmentWithFileSize : IAugmentParsedMovieInfo
|
||||
{
|
||||
public Type HelperType
|
||||
{
|
||||
get
|
||||
{
|
||||
return typeof(LocalMovie);
|
||||
}
|
||||
}
|
||||
|
||||
public ParsedMovieInfo AugmentMovieInfo(ParsedMovieInfo movieInfo, object helper)
|
||||
{
|
||||
if (helper is LocalMovie localMovie && localMovie.Size != 0)
|
||||
{
|
||||
movieInfo.ExtraInfo["Size"] = localMovie.Size;
|
||||
}
|
||||
|
||||
return movieInfo;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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,42 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.Parser.Augmenters
|
||||
{
|
||||
public class AugmentWithParsedMovieInfo : IAugmentParsedMovieInfo
|
||||
{
|
||||
public Type HelperType
|
||||
{
|
||||
get
|
||||
{
|
||||
return typeof(ParsedMovieInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public ParsedMovieInfo AugmentMovieInfo(ParsedMovieInfo movieInfo, object helper)
|
||||
{
|
||||
if (helper is ParsedMovieInfo otherInfo)
|
||||
{
|
||||
// Create union of all languages
|
||||
if (otherInfo.Languages != null)
|
||||
{
|
||||
movieInfo.Languages = movieInfo.Languages.Union(otherInfo.Languages).Distinct().ToList();
|
||||
}
|
||||
|
||||
if ((otherInfo.Edition?.Length ?? 0) > (movieInfo.Edition?.Length ?? 0))
|
||||
{
|
||||
movieInfo.Edition = otherInfo.Edition;
|
||||
}
|
||||
|
||||
if (otherInfo.ReleaseGroup.IsNotNullOrWhiteSpace() && movieInfo.ReleaseGroup.IsNullOrWhiteSpace())
|
||||
{
|
||||
movieInfo.ReleaseGroup = otherInfo.ReleaseGroup;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
using System;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.Parser.Augmenters
|
||||
{
|
||||
public interface IAugmentParsedMovieInfo
|
||||
{
|
||||
Type HelperType { get; }
|
||||
|
||||
ParsedMovieInfo AugmentMovieInfo(ParsedMovieInfo movieInfo, object helper);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.CustomFormats;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||
using NzbDrone.Core.Movies;
|
||||
|
@ -10,6 +11,7 @@ namespace NzbDrone.Core.Parser.Model
|
|||
{
|
||||
public LocalMovie()
|
||||
{
|
||||
CustomFormats = new List<CustomFormat>();
|
||||
}
|
||||
|
||||
public string Path { get; set; }
|
||||
|
@ -27,6 +29,8 @@ namespace NzbDrone.Core.Parser.Model
|
|||
public string Edition { get; set; }
|
||||
public string SceneName { get; set; }
|
||||
public bool OtherVideoFiles { get; set; }
|
||||
public List<CustomFormat> CustomFormats { get; set; }
|
||||
public int CustomFormatScore { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
|
|
|
@ -25,8 +25,7 @@ namespace NzbDrone.Core.Parser.Model
|
|||
public int Year { get; set; }
|
||||
public string ImdbId { get; set; }
|
||||
public int TmdbId { get; set; }
|
||||
[JsonIgnore]
|
||||
public Dictionary<string, object> ExtraInfo { get; set; } = new Dictionary<string, object>();
|
||||
public string HardcodedSubs { get; set; }
|
||||
|
||||
public string MovieTitle => PrimaryMovieTitle;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.CustomFormats;
|
||||
using NzbDrone.Core.Download.Clients;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Movies;
|
||||
|
||||
namespace NzbDrone.Core.Parser.Model
|
||||
|
@ -15,6 +16,13 @@ namespace NzbDrone.Core.Parser.Model
|
|||
public MappingResultType MappingResult { get; set; }
|
||||
public bool DownloadAllowed { get; set; }
|
||||
public TorrentSeedConfiguration SeedConfiguration { get; set; }
|
||||
public List<Language> Languages { get; set; }
|
||||
|
||||
public RemoteMovie()
|
||||
{
|
||||
CustomFormats = new List<CustomFormat>();
|
||||
Languages = new List<Language>();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
|
|
|
@ -18,6 +18,9 @@ namespace NzbDrone.Core.Parser
|
|||
|
||||
private static readonly Regex ReportEditionRegex = new Regex(@"^.+?" + EditionRegex, RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
private static readonly Regex HardcodedSubsRegex = new Regex(@"\b((?<hcsub>(\w+(?<!SOFT|HORRIBLE)SUBS?))|(?<hc>(HC|SUBBED)))\b",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
||||
|
||||
private static readonly RegexReplace[] PreSubstitutionRegex = Array.Empty<RegexReplace>();
|
||||
|
||||
private static readonly Regex[] ReportMovieTitleRegex = new[]
|
||||
|
@ -295,6 +298,8 @@ namespace NzbDrone.Core.Parser
|
|||
result.ReleaseGroup = subGroup;
|
||||
}
|
||||
|
||||
result.HardcodedSubs = ParseHardcodeSubs(title);
|
||||
|
||||
Logger.Debug("Release Group parsed: {0}", result.ReleaseGroup);
|
||||
|
||||
result.Languages = LanguageParser.ParseLanguages(result.ReleaseGroup.IsNotNullOrWhiteSpace() ? simpleReleaseTitle.Replace(result.ReleaseGroup, "RlsGrp") : simpleReleaseTitle);
|
||||
|
@ -491,6 +496,25 @@ namespace NzbDrone.Core.Parser
|
|||
return SimpleReleaseTitleRegex.Replace(title, string.Empty);
|
||||
}
|
||||
|
||||
public static string ParseHardcodeSubs(string title)
|
||||
{
|
||||
var subMatch = HardcodedSubsRegex.Matches(title).OfType<Match>().LastOrDefault();
|
||||
|
||||
if (subMatch != null && subMatch.Success)
|
||||
{
|
||||
if (subMatch.Groups["hcsub"].Success)
|
||||
{
|
||||
return subMatch.Groups["hcsub"].Value;
|
||||
}
|
||||
else if (subMatch.Groups["hc"].Success)
|
||||
{
|
||||
return "Generic Hardcoded Subs";
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string ParseReleaseGroup(string title)
|
||||
{
|
||||
title = title.Trim();
|
||||
|
|
|
@ -6,7 +6,6 @@ using NzbDrone.Core.DecisionEngine;
|
|||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Movies;
|
||||
using NzbDrone.Core.Parser.Augmenters;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Parser.RomanNumerals;
|
||||
|
||||
|
@ -17,7 +16,6 @@ namespace NzbDrone.Core.Parser
|
|||
Movie GetMovie(string title);
|
||||
MappingResult Map(ParsedMovieInfo parsedMovieInfo, string imdbId, SearchCriteriaBase searchCriteria = null);
|
||||
ParsedMovieInfo ParseMovieInfo(string title, List<object> helpers);
|
||||
ParsedMovieInfo EnhanceMovieInfo(ParsedMovieInfo parsedMovieInfo, List<object> helpers = null);
|
||||
ParsedMovieInfo ParseMinimalMovieInfo(string path, bool isDir = false);
|
||||
ParsedMovieInfo ParseMinimalPathMovieInfo(string path);
|
||||
}
|
||||
|
@ -27,15 +25,12 @@ namespace NzbDrone.Core.Parser
|
|||
private static HashSet<ArabicRomanNumeral> _arabicRomanNumeralMappings;
|
||||
|
||||
private readonly IMovieService _movieService;
|
||||
private readonly IEnumerable<IAugmentParsedMovieInfo> _augmenters;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public ParsingService(IMovieService movieService,
|
||||
IEnumerable<IAugmentParsedMovieInfo> augmenters,
|
||||
Logger logger)
|
||||
{
|
||||
_movieService = movieService;
|
||||
_augmenters = augmenters;
|
||||
_logger = logger;
|
||||
|
||||
if (_arabicRomanNumeralMappings == null)
|
||||
|
@ -53,27 +48,9 @@ namespace NzbDrone.Core.Parser
|
|||
return null;
|
||||
}
|
||||
|
||||
result = EnhanceMovieInfo(result, helpers);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public ParsedMovieInfo EnhanceMovieInfo(ParsedMovieInfo minimalInfo, List<object> helpers = null)
|
||||
{
|
||||
if (helpers != null)
|
||||
{
|
||||
var augmenters = _augmenters.Where(a => helpers.Any(t => a.HelperType.IsInstanceOfType(t)) || a.HelperType == null);
|
||||
|
||||
foreach (var augmenter in augmenters)
|
||||
{
|
||||
minimalInfo = augmenter.AugmentMovieInfo(minimalInfo,
|
||||
helpers.FirstOrDefault(h => augmenter.HelperType.IsInstanceOfType(h)));
|
||||
}
|
||||
}
|
||||
|
||||
return minimalInfo;
|
||||
}
|
||||
|
||||
public ParsedMovieInfo ParseMinimalMovieInfo(string file, bool isDir = false)
|
||||
{
|
||||
return Parser.ParseMovieTitle(file, isDir);
|
||||
|
@ -127,27 +104,6 @@ namespace NzbDrone.Core.Parser
|
|||
result.Movie = null;
|
||||
}
|
||||
|
||||
// Use movie language as fallback if we could't parse a language (more accurate than just using English)
|
||||
if (parsedMovieInfo.Languages.Count <= 1 && parsedMovieInfo.Languages.First() == Language.Unknown && result.Movie != null)
|
||||
{
|
||||
parsedMovieInfo.Languages = new List<Language> { result.Movie.MovieMetadata.Value.OriginalLanguage };
|
||||
_logger.Debug("Language couldn't be parsed from release, fallback to movie original language: {0}", result.Movie.MovieMetadata.Value.OriginalLanguage.Name);
|
||||
}
|
||||
|
||||
if (parsedMovieInfo.Languages.Contains(Language.Original))
|
||||
{
|
||||
parsedMovieInfo.Languages.Remove(Language.Original);
|
||||
|
||||
if (result.Movie != null && !parsedMovieInfo.Languages.Contains(result.Movie.MovieMetadata.Value.OriginalLanguage))
|
||||
{
|
||||
parsedMovieInfo.Languages.Add(result.Movie.MovieMetadata.Value.OriginalLanguage);
|
||||
}
|
||||
else
|
||||
{
|
||||
parsedMovieInfo.Languages.Add(Language.Unknown);
|
||||
}
|
||||
}
|
||||
|
||||
result.RemoteMovie.ParsedMovieInfo = parsedMovieInfo;
|
||||
|
||||
return result;
|
||||
|
|
|
@ -75,9 +75,6 @@ namespace NzbDrone.Core.Parser
|
|||
|
||||
private static readonly Regex RemuxRegex = new Regex(@"(?:[_. \[]|\d{4}p-)(?<remux>(?:(BD|UHD)[-_. ]?)?Remux)\b|(?<remux>(?:(BD|UHD)[-_. ]?)?Remux[_. ]\d{4}p)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
private static readonly Regex HardcodedSubsRegex = new Regex(@"\b((?<hcsub>(\w+(?<!SOFT|HORRIBLE)SUBS?))|(?<hc>(HC|SUBBED)))\b",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
||||
|
||||
public static QualityModel ParseQuality(string name)
|
||||
{
|
||||
Logger.Debug("Trying to parse quality for {0}", name);
|
||||
|
@ -110,19 +107,6 @@ namespace NzbDrone.Core.Parser
|
|||
{
|
||||
var normalizedName = name.Replace('_', ' ').Trim();
|
||||
var result = ParseQualityModifiers(name, normalizedName);
|
||||
var subMatch = HardcodedSubsRegex.Matches(normalizedName).OfType<Match>().LastOrDefault();
|
||||
|
||||
if (subMatch != null && subMatch.Success)
|
||||
{
|
||||
if (subMatch.Groups["hcsub"].Success)
|
||||
{
|
||||
result.HardcodedSubs = subMatch.Groups["hcsub"].Value;
|
||||
}
|
||||
else if (subMatch.Groups["hc"].Success)
|
||||
{
|
||||
result.HardcodedSubs = "Generic Hardcoded Subs";
|
||||
}
|
||||
}
|
||||
|
||||
var sourceMatches = SourceRegex.Matches(normalizedName);
|
||||
var sourceMatch = sourceMatches.OfType<Match>().LastOrDefault();
|
||||
|
|
|
@ -10,8 +10,6 @@ namespace NzbDrone.Core.Qualities
|
|||
|
||||
public Revision Revision { get; set; }
|
||||
|
||||
public string HardcodedSubs { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public QualityDetectionSource SourceDetectionSource { get; set; }
|
||||
|
||||
|
|
|
@ -17,13 +17,14 @@ namespace Radarr.Api.V3.Blocklist
|
|||
private readonly ICustomFormatCalculationService _formatCalculator;
|
||||
|
||||
public BlocklistController(IBlocklistService blocklistService,
|
||||
ICustomFormatCalculationService formatCalculator)
|
||||
ICustomFormatCalculationService formatCalculator)
|
||||
{
|
||||
_blocklistService = blocklistService;
|
||||
_formatCalculator = formatCalculator;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Produces("application/json")]
|
||||
public PagingResource<BlocklistResource> GetBlocklist()
|
||||
{
|
||||
var pagingResource = Request.ReadPagingResourceFromRequest<BlocklistResource>();
|
||||
|
@ -45,6 +46,7 @@ namespace Radarr.Api.V3.Blocklist
|
|||
}
|
||||
|
||||
[HttpDelete("bulk")]
|
||||
[Produces("application/json")]
|
||||
public object Remove([FromBody] BlocklistBulkResource resource)
|
||||
{
|
||||
_blocklistService.Delete(resource.Ids);
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace Radarr.Api.V3.Blocklist
|
|||
SourceTitle = model.SourceTitle,
|
||||
Languages = model.Languages,
|
||||
Quality = model.Quality,
|
||||
CustomFormats = formatCalculator.ParseCustomFormat(model).ToResource(),
|
||||
CustomFormats = formatCalculator.ParseCustomFormat(model, model.Movie).ToResource(false),
|
||||
Date = model.Date,
|
||||
Protocol = model.Protocol,
|
||||
Indexer = model.Indexer,
|
||||
|
|
|
@ -45,10 +45,11 @@ namespace Radarr.Api.V3.CustomFormats
|
|||
|
||||
protected override CustomFormatResource GetResourceById(int id)
|
||||
{
|
||||
return _formatService.GetById(id).ToResource();
|
||||
return _formatService.GetById(id).ToResource(true);
|
||||
}
|
||||
|
||||
[RestPostById]
|
||||
[Consumes("application/json")]
|
||||
public ActionResult<CustomFormatResource> Create(CustomFormatResource customFormatResource)
|
||||
{
|
||||
var model = customFormatResource.ToModel(_specifications);
|
||||
|
@ -59,6 +60,7 @@ namespace Radarr.Api.V3.CustomFormats
|
|||
}
|
||||
|
||||
[RestPutById]
|
||||
[Consumes("application/json")]
|
||||
public ActionResult<CustomFormatResource> Update(CustomFormatResource resource)
|
||||
{
|
||||
var model = resource.ToModel(_specifications);
|
||||
|
@ -71,9 +73,10 @@ namespace Radarr.Api.V3.CustomFormats
|
|||
}
|
||||
|
||||
[HttpGet]
|
||||
[Produces("application/json")]
|
||||
public List<CustomFormatResource> GetAll()
|
||||
{
|
||||
return _formatService.All().ToResource();
|
||||
return _formatService.All().ToResource(true);
|
||||
}
|
||||
|
||||
[RestDeleteById]
|
||||
|
|
|
@ -13,26 +13,32 @@ namespace Radarr.Api.V3.CustomFormats
|
|||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool IncludeCustomFormatWhenRenaming { get; set; }
|
||||
public bool? IncludeCustomFormatWhenRenaming { get; set; }
|
||||
public List<CustomFormatSpecificationSchema> Specifications { get; set; }
|
||||
}
|
||||
|
||||
public static class CustomFormatResourceMapper
|
||||
{
|
||||
public static CustomFormatResource ToResource(this CustomFormat model)
|
||||
public static CustomFormatResource ToResource(this CustomFormat model, bool includeDetails)
|
||||
{
|
||||
return new CustomFormatResource
|
||||
var resource = new CustomFormatResource
|
||||
{
|
||||
Id = model.Id,
|
||||
Name = model.Name,
|
||||
IncludeCustomFormatWhenRenaming = model.IncludeCustomFormatWhenRenaming,
|
||||
Specifications = model.Specifications.Select(x => x.ToSchema()).ToList()
|
||||
Name = model.Name
|
||||
};
|
||||
|
||||
if (includeDetails)
|
||||
{
|
||||
resource.IncludeCustomFormatWhenRenaming = model.IncludeCustomFormatWhenRenaming;
|
||||
resource.Specifications = model.Specifications.Select(x => x.ToSchema()).ToList();
|
||||
}
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
public static List<CustomFormatResource> ToResource(this IEnumerable<CustomFormat> models)
|
||||
public static List<CustomFormatResource> ToResource(this IEnumerable<CustomFormat> models, bool includeDetails)
|
||||
{
|
||||
return models.Select(m => m.ToResource()).ToList();
|
||||
return models.Select(m => m.ToResource(includeDetails)).ToList();
|
||||
}
|
||||
|
||||
public static CustomFormat ToModel(this CustomFormatResource resource, List<ICustomFormatSpecification> specifications)
|
||||
|
@ -41,14 +47,15 @@ namespace Radarr.Api.V3.CustomFormats
|
|||
{
|
||||
Id = resource.Id,
|
||||
Name = resource.Name,
|
||||
IncludeCustomFormatWhenRenaming = resource.IncludeCustomFormatWhenRenaming,
|
||||
Specifications = resource.Specifications.Select(x => MapSpecification(x, specifications)).ToList()
|
||||
IncludeCustomFormatWhenRenaming = resource.IncludeCustomFormatWhenRenaming ?? false,
|
||||
Specifications = resource.Specifications?.Select(x => MapSpecification(x, specifications)).ToList() ?? new List<ICustomFormatSpecification>()
|
||||
};
|
||||
}
|
||||
|
||||
private static ICustomFormatSpecification MapSpecification(CustomFormatSpecificationSchema resource, List<ICustomFormatSpecification> specifications)
|
||||
{
|
||||
var matchingSpec = specifications.SingleOrDefault(x => x.GetType().Name == resource.Implementation);
|
||||
var matchingSpec =
|
||||
specifications.SingleOrDefault(x => x.GetType().Name == resource.Implementation);
|
||||
|
||||
if (matchingSpec is null)
|
||||
{
|
||||
|
@ -57,6 +64,7 @@ namespace Radarr.Api.V3.CustomFormats
|
|||
}
|
||||
|
||||
var type = matchingSpec.GetType();
|
||||
|
||||
var spec = (ICustomFormatSpecification)SchemaBuilder.ReadFromSchema(resource.Fields, type);
|
||||
spec.Name = resource.Name;
|
||||
spec.Negate = resource.Negate;
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace Radarr.Api.V3.History
|
|||
public List<Language> Languages { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public List<CustomFormatResource> CustomFormats { get; set; }
|
||||
public int CustomFormatScore { get; set; }
|
||||
public bool QualityCutoffNotMet { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
public string DownloadId { get; set; }
|
||||
|
@ -37,6 +38,9 @@ namespace Radarr.Api.V3.History
|
|||
return null;
|
||||
}
|
||||
|
||||
var customFormats = formatCalculator.ParseCustomFormat(model, model.Movie);
|
||||
var customFormatScore = model.Movie.Profile.CalculateCustomFormatScore(customFormats);
|
||||
|
||||
return new HistoryResource
|
||||
{
|
||||
Id = model.Id,
|
||||
|
@ -45,7 +49,8 @@ namespace Radarr.Api.V3.History
|
|||
SourceTitle = model.SourceTitle,
|
||||
Languages = model.Languages,
|
||||
Quality = model.Quality,
|
||||
CustomFormats = formatCalculator.ParseCustomFormat(model).ToResource(),
|
||||
CustomFormats = customFormats.ToResource(false),
|
||||
CustomFormatScore = customFormatScore,
|
||||
|
||||
// QualityCutoffNotMet
|
||||
Date = model.Date,
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace Radarr.Api.V3.Indexers
|
|||
{
|
||||
Guid = releaseInfo.Guid,
|
||||
Quality = parsedMovieInfo.Quality,
|
||||
CustomFormats = remoteMovie.CustomFormats.ToResource(),
|
||||
CustomFormats = remoteMovie.CustomFormats.ToResource(false),
|
||||
CustomFormatScore = remoteMovie.CustomFormatScore,
|
||||
|
||||
// QualityWeight
|
||||
|
@ -87,7 +87,7 @@ namespace Radarr.Api.V3.Indexers
|
|||
ReleaseHash = parsedMovieInfo.ReleaseHash,
|
||||
Title = releaseInfo.Title,
|
||||
MovieTitles = parsedMovieInfo.MovieTitles,
|
||||
Languages = parsedMovieInfo.Languages,
|
||||
Languages = remoteMovie.Languages,
|
||||
Approved = model.Approved,
|
||||
TemporarilyRejected = model.TemporarilyRejected,
|
||||
Rejected = model.Rejected,
|
||||
|
|
|
@ -5,6 +5,7 @@ using NzbDrone.Core.DecisionEngine;
|
|||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.MediaFiles.MovieImport.Manual;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using Radarr.Api.V3.CustomFormats;
|
||||
using Radarr.Api.V3.Movies;
|
||||
using Radarr.Http.REST;
|
||||
|
||||
|
@ -23,6 +24,7 @@ namespace Radarr.Api.V3.ManualImport
|
|||
public string ReleaseGroup { get; set; }
|
||||
public int QualityWeight { get; set; }
|
||||
public string DownloadId { get; set; }
|
||||
public List<CustomFormatResource> CustomFormats { get; set; }
|
||||
public IEnumerable<Rejection> Rejections { get; set; }
|
||||
}
|
||||
|
||||
|
@ -44,9 +46,10 @@ namespace Radarr.Api.V3.ManualImport
|
|||
Name = model.Name,
|
||||
Size = model.Size,
|
||||
Movie = model.Movie.ToResource(0),
|
||||
ReleaseGroup = model.ReleaseGroup,
|
||||
Quality = model.Quality,
|
||||
Languages = model.Languages,
|
||||
ReleaseGroup = model.ReleaseGroup,
|
||||
CustomFormats = model.CustomFormats.ToResource(false),
|
||||
|
||||
// QualityWeight
|
||||
DownloadId = model.DownloadId,
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace Radarr.Api.V3.MovieFiles
|
|||
movieFile.Movie = movie;
|
||||
|
||||
var resource = movieFile.ToResource(movie, _qualityUpgradableSpecification);
|
||||
resource.CustomFormats = _formatCalculator.ParseCustomFormat(movieFile).ToResource();
|
||||
resource.CustomFormats = _formatCalculator.ParseCustomFormat(movieFile).ToResource(false);
|
||||
return resource;
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ namespace Radarr.Api.V3.MovieFiles
|
|||
|
||||
var resource = file.ToResource(movie, _qualityUpgradableSpecification);
|
||||
file.Movie = movie;
|
||||
resource.CustomFormats = _formatCalculator.ParseCustomFormat(file).ToResource();
|
||||
resource.CustomFormats = _formatCalculator.ParseCustomFormat(file).ToResource(false);
|
||||
|
||||
return new List<MovieFileResource> { resource };
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ using System.Collections.Generic;
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Download.Aggregation;
|
||||
using NzbDrone.Core.Parser;
|
||||
using Radarr.Api.V3.Movies;
|
||||
using Radarr.Http;
|
||||
|
@ -13,11 +14,15 @@ namespace Radarr.Api.V3.Parse
|
|||
{
|
||||
private readonly IParsingService _parsingService;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly IRemoteMovieAggregationService _aggregationService;
|
||||
|
||||
public ParseController(IParsingService parsingService, IConfigService configService)
|
||||
public ParseController(IParsingService parsingService,
|
||||
IConfigService configService,
|
||||
IRemoteMovieAggregationService aggregationService)
|
||||
{
|
||||
_parsingService = parsingService;
|
||||
_configService = configService;
|
||||
_aggregationService = aggregationService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
|
@ -40,6 +45,8 @@ namespace Radarr.Api.V3.Parse
|
|||
|
||||
var remoteMovie = _parsingService.Map(parsedMovieInfo, "");
|
||||
|
||||
_aggregationService.Augment(remoteMovie.RemoteMovie);
|
||||
|
||||
if (remoteMovie != null)
|
||||
{
|
||||
return new ParseResource
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace Radarr.Api.V3.Queue
|
|||
Movie = includeMovie && model.Movie != null ? model.Movie.ToResource(0) : null,
|
||||
Languages = model.Languages,
|
||||
Quality = model.Quality,
|
||||
CustomFormats = model.RemoteMovie?.CustomFormats?.ToResource(),
|
||||
CustomFormats = model.RemoteMovie?.CustomFormats?.ToResource(false),
|
||||
Size = model.Size,
|
||||
Title = model.Title,
|
||||
Sizeleft = model.Sizeleft,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue