Add upgrade allowed to language and profiles

This commit is contained in:
Mark McDowall 2018-11-28 20:26:49 -08:00 committed by Taloth Saldono
parent 853f25468c
commit f345977e3f
67 changed files with 426 additions and 266 deletions

View file

@ -66,7 +66,7 @@ public static EpisodeFileResource ToResource(this EpisodeFile model, Core.Tv.Ser
SceneName = model.SceneName,
Quality = model.Quality,
Language = model.Language,
QualityCutoffNotMet = upgradableSpecification.QualityCutoffNotMet(series.Profile.Value, model.Quality),
QualityCutoffNotMet = upgradableSpecification.QualityCutoffNotMet(series.QualityProfile.Value, model.Quality),
MediaInfo = model.MediaInfo.ToResource(model.SceneName),
OriginalFilePath = model.OriginalFilePath
};

View file

@ -43,7 +43,7 @@ protected HistoryResource MapToResource(Core.History.History model)
if (model.Series != null)
{
resource.QualityCutoffNotMet = _upgradableSpecification.QualityCutoffNotMet(model.Series.Profile.Value, model.Quality);
resource.QualityCutoffNotMet = _upgradableSpecification.QualityCutoffNotMet(model.Series.QualityProfile.Value, model.Quality);
}
return resource;

View file

@ -29,7 +29,7 @@ protected virtual ReleaseResource MapDecision(DownloadDecision decision, int ini
if (decision.RemoteEpisode.Series != null)
{
release.QualityWeight = decision.RemoteEpisode.Series
.Profile.Value
.QualityProfile.Value
.Items.FindIndex(v => v.Quality == release.Quality.Quality) * 100;
}

View file

@ -10,6 +10,7 @@ namespace NzbDrone.Api.Profiles
public class ProfileResource : RestResource
{
public string Name { get; set; }
public bool UpgradeAllowed { get; set; }
public Quality Cutoff { get; set; }
public List<ProfileQualityItemResource> Items { get; set; }
}
@ -22,7 +23,7 @@ public class ProfileQualityItemResource : RestResource
public static class ProfileResourceMapper
{
public static ProfileResource ToResource(this Profile model)
public static ProfileResource ToResource(this QualityProfile model)
{
if (model == null) return null;
@ -44,6 +45,7 @@ public static ProfileResource ToResource(this Profile model)
Id = model.Id,
Name = model.Name,
UpgradeAllowed = model.UpgradeAllowed,
Cutoff = cutoff,
// Flatten groups so things don't explode
@ -64,7 +66,7 @@ public static ProfileResource ToResource(this Profile model)
};
}
public static ProfileQualityItemResource ToResource(this ProfileQualityItem model)
public static ProfileQualityItemResource ToResource(this QualityProfileQualityItem model)
{
if (model == null) return null;
@ -75,32 +77,33 @@ public static ProfileQualityItemResource ToResource(this ProfileQualityItem mode
};
}
public static Profile ToModel(this ProfileResource resource)
public static QualityProfile ToModel(this ProfileResource resource)
{
if (resource == null) return null;
return new Profile
return new QualityProfile
{
Id = resource.Id,
Name = resource.Name,
UpgradeAllowed = resource.UpgradeAllowed,
Cutoff = resource.Cutoff.Id,
Items = resource.Items.ConvertAll(ToModel)
};
}
public static ProfileQualityItem ToModel(this ProfileQualityItemResource resource)
public static QualityProfileQualityItem ToModel(this ProfileQualityItemResource resource)
{
if (resource == null) return null;
return new ProfileQualityItem
return new QualityProfileQualityItem
{
Quality = (Quality)resource.Quality.Id,
Allowed = resource.Allowed
};
}
public static List<ProfileResource> ToResource(this IEnumerable<Profile> models)
public static List<ProfileResource> ToResource(this IEnumerable<QualityProfile> models)
{
return models.Select(ToResource).ToList();
}

View file

@ -23,10 +23,10 @@ private List<ProfileResource> GetAll()
{
var items = _qualityDefinitionService.All()
.OrderBy(v => v.Weight)
.Select(v => new ProfileQualityItem { Quality = v.Quality, Allowed = false })
.Select(v => new QualityProfileQualityItem { Quality = v.Quality, Allowed = false })
.ToList();
var profile = new Profile();
var profile = new QualityProfile();
profile.Cutoff = Quality.Unknown.Id;
profile.Items = items;

View file

@ -16,7 +16,7 @@ public SeriesResource()
//Todo: Sorters should be done completely on the client
//Todo: Is there an easy way to keep IgnoreArticlesWhenSorting in sync between, Series, History, Missing?
//Todo: We should get the entire Profile instead of ID and Name separately
//Todo: We should get the entire QualityProfile instead of ID and Name separately
//View Only
public string Title { get; set; }
@ -124,7 +124,7 @@ public static SeriesResource ToResource(this Core.Tv.Series model, bool includeS
Year = model.Year,
Path = model.Path,
ProfileId = model.ProfileId,
ProfileId = model.QualityProfileId,
LanguageProfileId = model.LanguageProfileId,
SeasonFolder = model.SeasonFolder,
@ -179,7 +179,7 @@ public static Core.Tv.Series ToModel(this SeriesResource resource)
Year = resource.Year,
Path = resource.Path,
ProfileId = resource.ProfileId,
QualityProfileId = resource.ProfileId,
LanguageProfileId = resource.LanguageProfileId,
SeasonFolder = resource.SeasonFolder,

View file

@ -20,7 +20,7 @@ public class MarrDataLazyLoadingFixture : DbTest
[SetUp]
public void Setup()
{
var profile = new Profile
var profile = new QualityProfile
{
Name = "Test",
Cutoff = Quality.WEBDL720p.Id,
@ -39,7 +39,7 @@ public void Setup()
var series = Builder<Series>.CreateListOfSize(1)
.All()
.With(v => v.ProfileId = profile.Id)
.With(v => v.QualityProfileId = profile.Id)
.With(v => v.LanguageProfileId = languageProfile.Id)
.BuildListOfNew();
@ -76,7 +76,7 @@ public void should_lazy_load_profile_if_not_joined()
foreach (var episode in episodes)
{
Assert.IsNotNull(episode.Series);
Assert.IsFalse(episode.Series.Profile.IsLoaded);
Assert.IsFalse(episode.Series.QualityProfile.IsLoaded);
Assert.IsFalse(episode.Series.LanguageProfile.IsLoaded);
}
}
@ -106,13 +106,13 @@ public void should_explicit_load_profile_if_joined()
var episodes = DataMapper.Query<Episode>()
.Join<Episode, Series>(Marr.Data.QGen.JoinType.Inner, v => v.Series, (l, r) => l.SeriesId == r.Id)
.Join<Series, Profile>(Marr.Data.QGen.JoinType.Inner, v => v.Profile, (l, r) => l.ProfileId == r.Id)
.Join<Series, QualityProfile>(Marr.Data.QGen.JoinType.Inner, v => v.QualityProfile, (l, r) => l.QualityProfileId == r.Id)
.ToList();
foreach (var episode in episodes)
{
Assert.IsNotNull(episode.Series);
Assert.IsTrue(episode.Series.Profile.IsLoaded);
Assert.IsTrue(episode.Series.QualityProfile.IsLoaded);
Assert.IsFalse(episode.Series.LanguageProfile.IsLoaded);
}
}
@ -125,13 +125,13 @@ public void should_explicit_load_languageprofile_if_joined()
var episodes = DataMapper.Query<Episode>()
.Join<Episode, Series>(Marr.Data.QGen.JoinType.Inner, v => v.Series, (l, r) => l.SeriesId == r.Id)
.Join<Series, LanguageProfile>(Marr.Data.QGen.JoinType.Inner, v => v.LanguageProfile, (l, r) => l.ProfileId == r.Id)
.Join<Series, LanguageProfile>(Marr.Data.QGen.JoinType.Inner, v => v.LanguageProfile, (l, r) => l.QualityProfileId == r.Id)
.ToList();
foreach (var episode in episodes)
{
Assert.IsNotNull(episode.Series);
Assert.IsFalse(episode.Series.Profile.IsLoaded);
Assert.IsFalse(episode.Series.QualityProfile.IsLoaded);
Assert.IsTrue(episode.Series.LanguageProfile.IsLoaded);
}
}

View file

@ -19,7 +19,7 @@ public class CutoffSpecificationFixture : CoreTest<UpgradableSpecification>
public void should_return_true_if_current_episode_is_less_than_cutoff()
{
Subject.CutoffNotMet(
new Profile
new QualityProfile
{
Cutoff = Quality.Bluray1080p.Id,
Items = Qualities.QualityFixture.GetDefaultQualities()
@ -38,7 +38,7 @@ public void should_return_true_if_current_episode_is_less_than_cutoff()
public void should_return_false_if_current_episode_is_equal_to_cutoff()
{
Subject.CutoffNotMet(
new Profile
new QualityProfile
{
Cutoff = Quality.HDTV720p.Id,
Items = Qualities.QualityFixture.GetDefaultQualities()
@ -57,7 +57,7 @@ public void should_return_false_if_current_episode_is_equal_to_cutoff()
public void should_return_false_if_current_episode_is_greater_than_cutoff()
{
Subject.CutoffNotMet(
new Profile
new QualityProfile
{
Cutoff = Quality.HDTV720p.Id,
Items = Qualities.QualityFixture.GetDefaultQualities()
@ -76,7 +76,7 @@ public void should_return_false_if_current_episode_is_greater_than_cutoff()
public void should_return_true_when_new_episode_is_proper_but_existing_is_not()
{
Subject.CutoffNotMet(
new Profile
new QualityProfile
{
Cutoff = Quality.HDTV720p.Id,
Items = Qualities.QualityFixture.GetDefaultQualities()
@ -97,7 +97,7 @@ public void should_return_true_when_new_episode_is_proper_but_existing_is_not()
public void should_return_false_if_cutoff_is_met_and_quality_is_higher()
{
Subject.CutoffNotMet(
new Profile
new QualityProfile
{
Cutoff = Quality.HDTV720p.Id,
Items = Qualities.QualityFixture.GetDefaultQualities()
@ -117,7 +117,7 @@ public void should_return_false_if_cutoff_is_met_and_quality_is_higher()
[Test]
public void should_return_true_if_quality_cutoff_is_met_and_quality_is_higher_but_language_is_not_met()
{
Profile _profile = new Profile
QualityProfile _profile = new QualityProfile
{
Cutoff = Quality.HDTV720p.Id,
Items = Qualities.QualityFixture.GetDefaultQualities(),
@ -141,7 +141,7 @@ public void should_return_true_if_quality_cutoff_is_met_and_quality_is_higher_bu
[Test]
public void should_return_false_if_cutoff_is_met_and_quality_is_higher_and_language_is_met()
{
Profile _profile = new Profile
QualityProfile _profile = new QualityProfile
{
Cutoff = Quality.HDTV720p.Id,
Items = Qualities.QualityFixture.GetDefaultQualities(),
@ -166,7 +166,7 @@ public void should_return_false_if_cutoff_is_met_and_quality_is_higher_and_langu
[Test]
public void should_return_false_if_cutoff_is_met_and_quality_is_higher_and_language_is_higher()
{
Profile _profile = new Profile
QualityProfile _profile = new QualityProfile
{
Cutoff = Quality.HDTV720p.Id,
Items = Qualities.QualityFixture.GetDefaultQualities(),
@ -191,7 +191,7 @@ public void should_return_false_if_cutoff_is_met_and_quality_is_higher_and_langu
[Test]
public void should_return_true_if_cutoff_is_not_met_and_new_quality_is_higher_and_language_is_higher()
{
Profile _profile = new Profile
QualityProfile _profile = new QualityProfile
{
Cutoff = Quality.HDTV720p.Id,
Items = Qualities.QualityFixture.GetDefaultQualities(),
@ -216,7 +216,7 @@ public void should_return_true_if_cutoff_is_not_met_and_new_quality_is_higher_an
[Test]
public void should_return_true_if_cutoff_is_not_met_and_language_is_higher()
{
Profile _profile = new Profile
QualityProfile _profile = new QualityProfile
{
Cutoff = Quality.HDTV720p.Id,
Items = Qualities.QualityFixture.GetDefaultQualities(),
@ -239,7 +239,7 @@ public void should_return_true_if_cutoff_is_not_met_and_language_is_higher()
[Test]
public void should_return_true_if_cutoffs_are_met_and_score_is_higher()
{
Profile _profile = new Profile
QualityProfile _profile = new QualityProfile
{
Cutoff = Quality.HDTV720p.Id,
Items = Qualities.QualityFixture.GetDefaultQualities(),

View file

@ -53,7 +53,7 @@ private RemoteEpisode GivenRemoteEpisode(List<Episode> episodes, QualityModel qu
remoteEpisode.Release.DownloadProtocol = downloadProtocol;
remoteEpisode.Series = Builder<Series>.CreateNew()
.With(e => e.Profile = new Profile
.With(e => e.QualityProfile = new QualityProfile
{
Items = Qualities.QualityFixture.GetDefaultQualities()
})

View file

@ -35,7 +35,7 @@ public class QualityAllowedByProfileSpecificationFixture : CoreTest<QualityAllow
public void Setup()
{
var fakeSeries = Builder<Series>.CreateNew()
.With(c => c.Profile = (LazyLoaded<Profile>)new Profile { Cutoff = Quality.Bluray1080p.Id })
.With(c => c.QualityProfile = (LazyLoaded<QualityProfile>)new QualityProfile { Cutoff = Quality.Bluray1080p.Id })
.Build();
remoteEpisode = new RemoteEpisode
@ -49,7 +49,7 @@ public void Setup()
public void should_allow_if_quality_is_defined_in_profile(Quality qualityType)
{
remoteEpisode.ParsedEpisodeInfo.Quality.Quality = qualityType;
remoteEpisode.Series.Profile.Value.Items = Qualities.QualityFixture.GetDefaultQualities(Quality.DVD, Quality.HDTV720p, Quality.Bluray1080p);
remoteEpisode.Series.QualityProfile.Value.Items = Qualities.QualityFixture.GetDefaultQualities(Quality.DVD, Quality.HDTV720p, Quality.Bluray1080p);
Subject.IsSatisfiedBy(remoteEpisode, null).Accepted.Should().BeTrue();
}
@ -58,7 +58,7 @@ public void should_allow_if_quality_is_defined_in_profile(Quality qualityType)
public void should_not_allow_if_quality_is_not_defined_in_profile(Quality qualityType)
{
remoteEpisode.ParsedEpisodeInfo.Quality.Quality = qualityType;
remoteEpisode.Series.Profile.Value.Items = Qualities.QualityFixture.GetDefaultQualities(Quality.DVD, Quality.HDTV720p, Quality.Bluray1080p);
remoteEpisode.Series.QualityProfile.Value.Items = Qualities.QualityFixture.GetDefaultQualities(Quality.DVD, Quality.HDTV720p, Quality.Bluray1080p);
Subject.IsSatisfiedBy(remoteEpisode, null).Accepted.Should().BeFalse();
}

View file

@ -33,13 +33,15 @@ public void Setup()
Mocker.Resolve<UpgradableSpecification>();
_series = Builder<Series>.CreateNew()
.With(e => e.Profile = new Profile
{
Items = Qualities.QualityFixture.GetDefaultQualities(),
.With(e => e.QualityProfile = new QualityProfile
{
UpgradeAllowed = true,
Items = Qualities.QualityFixture.GetDefaultQualities()
})
.With(l => l.LanguageProfile = new LanguageProfile
{
Languages = Languages.LanguageFixture.GetDefaultLanguages(),
UpgradeAllowed = true,
Cutoff = Language.Spanish
})
.Build();
@ -109,10 +111,31 @@ public void should_return_true_when_series_doesnt_match()
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
}
[Test]
public void should_return_false_if_everything_is_the_same()
{
_series.QualityProfile.Value.Cutoff = Quality.Bluray1080p.Id;
var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
.With(r => r.Series = _series)
.With(r => r.Episodes = new List<Episode> { _episode })
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
{
Quality = new QualityModel(Quality.DVD),
Language = Language.Spanish
})
.With(r => r.Release = _releaseInfo)
.Build();
GivenQueue(new List<RemoteEpisode> { remoteEpisode });
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse();
}
[Test]
public void should_return_true_when_quality_in_queue_is_lower()
{
_series.Profile.Value.Cutoff = Quality.Bluray1080p.Id;
_series.QualityProfile.Value.Cutoff = Quality.Bluray1080p.Id;
_series.LanguageProfile.Value.Cutoff = Language.Spanish;
var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
@ -133,7 +156,7 @@ public void should_return_true_when_quality_in_queue_is_lower()
[Test]
public void should_return_true_when_quality_in_queue_is_lower_but_language_is_higher()
{
_series.Profile.Value.Cutoff = Quality.Bluray1080p.Id;
_series.QualityProfile.Value.Cutoff = Quality.Bluray1080p.Id;
_series.LanguageProfile.Value.Cutoff = Language.Spanish;
var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
@ -224,10 +247,31 @@ public void should_return_true_when_qualities_are_the_same_but_language_is_bette
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
}
[Test]
public void should_return_true_when_quality_is_better_language_is_better_and_upgrade_allowed_is_false_for_quality_profile()
{
_series.QualityProfile.Value.Cutoff = Quality.Bluray1080p.Id;
_series.QualityProfile.Value.UpgradeAllowed = false;
var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
.With(r => r.Series = _series)
.With(r => r.Episodes = new List<Episode> { _episode })
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
{
Quality = new QualityModel(Quality.SDTV),
Language = Language.English
})
.With(r => r.Release = _releaseInfo)
.Build();
GivenQueue(new List<RemoteEpisode> { remoteEpisode });
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
}
[Test]
public void should_return_false_when_quality_in_queue_is_better()
{
_series.Profile.Value.Cutoff = Quality.Bluray1080p.Id;
_series.QualityProfile.Value.Cutoff = Quality.Bluray1080p.Id;
var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
.With(r => r.Series = _series)
@ -330,7 +374,7 @@ public void should_return_false_if_multi_part_episode_has_two_episodes_in_queue(
[Test]
public void should_return_false_if_quality_and_language_in_queue_meets_cutoff()
{
_series.Profile.Value.Cutoff = _remoteEpisode.ParsedEpisodeInfo.Quality.Quality.Id;
_series.QualityProfile.Value.Cutoff = _remoteEpisode.ParsedEpisodeInfo.Quality.Quality.Id;
var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
.With(r => r.Series = _series)
@ -347,5 +391,46 @@ public void should_return_false_if_quality_and_language_in_queue_meets_cutoff()
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse();
}
[Test]
public void should_return_false_when_quality_are_the_same_language_is_better_and_upgrade_allowed_is_false_for_language_profile()
{
_series.LanguageProfile.Value.UpgradeAllowed = false;
var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
.With(r => r.Series = _series)
.With(r => r.Episodes = new List<Episode> { _episode })
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
{
Quality = new QualityModel(Quality.DVD),
Language = Language.English
})
.With(r => r.Release = _releaseInfo)
.Build();
GivenQueue(new List<RemoteEpisode> { remoteEpisode });
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse();
}
[Test]
public void should_return_false_when_quality_is_better_languages_are_the_same_and_upgrade_allowed_is_false_for_quality_profile()
{
_series.QualityProfile.Value.Cutoff = Quality.Bluray1080p.Id;
_series.QualityProfile.Value.UpgradeAllowed = false;
var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
.With(r => r.Series = _series)
.With(r => r.Episodes = new List<Episode> { _episode })
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
{
Quality = new QualityModel(Quality.Bluray1080p),
Language = Language.Spanish
})
.With(r => r.Release = _releaseInfo)
.Build();
GivenQueue(new List<RemoteEpisode> { remoteEpisode });
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse();
}
}
}

View file

@ -26,7 +26,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[TestFixture]
public class DelaySpecificationFixture : CoreTest<DelaySpecification>
{
private Profile _profile;
private QualityProfile _profile;
private LanguageProfile _langProfile;
private DelayProfile _delayProfile;
private RemoteEpisode _remoteEpisode;
@ -34,7 +34,7 @@ public class DelaySpecificationFixture : CoreTest<DelaySpecification>
[SetUp]
public void Setup()
{
_profile = Builder<Profile>.CreateNew()
_profile = Builder<QualityProfile>.CreateNew()
.Build();
_langProfile = Builder<LanguageProfile>.CreateNew()
@ -45,7 +45,7 @@ public void Setup()
.Build();
var series = Builder<Series>.CreateNew()
.With(s => s.Profile = _profile)
.With(s => s.QualityProfile = _profile)
.With(s => s.LanguageProfile = _langProfile)
.Build();
@ -53,10 +53,10 @@ public void Setup()
.With(r => r.Series = series)
.Build();
_profile.Items = new List<ProfileQualityItem>();
_profile.Items.Add(new ProfileQualityItem { Allowed = true, Quality = Quality.HDTV720p });
_profile.Items.Add(new ProfileQualityItem { Allowed = true, Quality = Quality.WEBDL720p });
_profile.Items.Add(new ProfileQualityItem { Allowed = true, Quality = Quality.Bluray720p });
_profile.Items = new List<QualityProfileQualityItem>();
_profile.Items.Add(new QualityProfileQualityItem { Allowed = true, Quality = Quality.HDTV720p });
_profile.Items.Add(new QualityProfileQualityItem { Allowed = true, Quality = Quality.WEBDL720p });
_profile.Items.Add(new QualityProfileQualityItem { Allowed = true, Quality = Quality.Bluray720p });
_profile.Cutoff = Quality.WEBDL720p.Id;
@ -94,7 +94,7 @@ private void GivenExistingFile(QualityModel quality, Language language)
private void GivenUpgradeForExistingFile()
{
Mocker.GetMock<IUpgradableSpecification>()
.Setup(s => s.IsUpgradable(It.IsAny<Profile>(), It.IsAny<LanguageProfile>(), It.IsAny<QualityModel>(), It.IsAny<Language>(), It.IsAny<int>(), It.IsAny<QualityModel>(), It.IsAny<Language>(), It.IsAny<int>()))
.Setup(s => s.IsUpgradable(It.IsAny<QualityProfile>(), It.IsAny<LanguageProfile>(), It.IsAny<QualityModel>(), It.IsAny<Language>(), It.IsAny<int>(), It.IsAny<QualityModel>(), It.IsAny<Language>(), It.IsAny<int>()))
.Returns(true);
}

View file

@ -55,7 +55,7 @@ public void Setup()
};
var fakeSeries = Builder<Series>.CreateNew()
.With(c => c.Profile = new Profile { Cutoff = Quality.Bluray1080p.Id })
.With(c => c.QualityProfile = new QualityProfile { Cutoff = Quality.Bluray1080p.Id })
.With(c => c.Path = @"C:\Series\My.Series".AsOsAgnostic())
.Build();

View file

@ -12,7 +12,6 @@
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Profiles.Qualities;
using NzbDrone.Core.Profiles.Languages;
@ -48,9 +47,19 @@ public void Setup()
};
_fakeSeries = Builder<Series>.CreateNew()
.With(c => c.Profile = new Profile { Cutoff = Quality.Bluray1080p.Id, Items = Qualities.QualityFixture.GetDefaultQualities() })
.With(l => l.LanguageProfile = new LanguageProfile { Cutoff = Language.Spanish, Languages = LanguageFixture.GetDefaultLanguages() })
.Build();
.With(c => c.QualityProfile = new QualityProfile
{
UpgradeAllowed = true,
Cutoff = Quality.Bluray1080p.Id,
Items = Qualities.QualityFixture.GetDefaultQualities()
})
.With(l => l.LanguageProfile = new LanguageProfile
{
UpgradeAllowed = true,
Cutoff = Language.Spanish,
Languages = LanguageFixture.GetDefaultLanguages()
})
.Build();
_parseResultMulti = new RemoteEpisode
{
@ -164,7 +173,7 @@ public void should_be_not_upgradable_if_only_second_episodes_is_upgradable()
[Test]
public void should_not_be_upgradable_if_episode_is_of_same_quality_as_existing()
{
_fakeSeries.Profile = new Profile { Cutoff = Quality.Bluray1080p.Id, Items = Qualities.QualityFixture.GetDefaultQualities() };
_fakeSeries.QualityProfile = new QualityProfile { Cutoff = Quality.Bluray1080p.Id, Items = Qualities.QualityFixture.GetDefaultQualities() };
_parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.WEBDL1080p, new Revision(version: 1));
_upgradableQuality = new Tuple<QualityModel, Language>(new QualityModel(Quality.WEBDL1080p, new Revision(version: 1)), Language.English);
@ -176,7 +185,7 @@ public void should_not_be_upgradable_if_episode_is_of_same_quality_as_existing()
[Test]
public void should_be_upgradable_if_episode_is_of_same_quality_as_existing_but_new_has_better_language()
{
_fakeSeries.Profile = new Profile { Cutoff = Quality.WEBDL1080p.Id, Items = Qualities.QualityFixture.GetDefaultQualities() };
_fakeSeries.QualityProfile = new QualityProfile { Cutoff = Quality.WEBDL1080p.Id, Items = Qualities.QualityFixture.GetDefaultQualities() };
_parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.WEBDL1080p, new Revision(version: 1));
_parseResultSingle.ParsedEpisodeInfo.Language = Language.Spanish;
_upgradableQuality = new Tuple<QualityModel, Language>(new QualityModel(Quality.WEBDL1080p, new Revision(version: 1)), Language.English);
@ -189,7 +198,7 @@ public void should_be_upgradable_if_episode_is_of_same_quality_as_existing_but_n
[Test]
public void should_not_be_upgradable_if_cutoff_already_met()
{
_fakeSeries.Profile = new Profile { Cutoff = Quality.WEBDL1080p.Id, Items = Qualities.QualityFixture.GetDefaultQualities() };
_fakeSeries.QualityProfile = new QualityProfile { Cutoff = Quality.WEBDL1080p.Id, Items = Qualities.QualityFixture.GetDefaultQualities() };
_parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.WEBDL1080p, new Revision(version: 1));
_upgradableQuality = new Tuple<QualityModel, Language>(new QualityModel(Quality.WEBDL1080p, new Revision(version: 1)), Language.Spanish);
@ -217,7 +226,7 @@ public void should_return_false_if_latest_history_has_a_download_id_and_cdh_is_d
public void should_return_false_if_cutoff_already_met_and_cdh_is_disabled()
{
GivenCdhDisabled();
_fakeSeries.Profile = new Profile { Cutoff = Quality.WEBDL1080p.Id, Items = Qualities.QualityFixture.GetDefaultQualities() };
_fakeSeries.QualityProfile = new QualityProfile { Cutoff = Quality.WEBDL1080p.Id, Items = Qualities.QualityFixture.GetDefaultQualities() };
_parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.Bluray1080p, new Revision(version: 1));
_upgradableQuality = new Tuple<QualityModel, Language>(new QualityModel(Quality.WEBDL1080p, new Revision(version: 1)), Language.Spanish);

View file

@ -38,7 +38,7 @@ public void Setup()
var doubleEpisodeList = new List<Episode> { new Episode { EpisodeFile = _firstFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = _secondFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = null } };
var fakeSeries = Builder<Series>.CreateNew()
.With(c => c.Profile = new Profile { Cutoff = Quality.Bluray1080p.Id })
.With(c => c.QualityProfile = new QualityProfile { Cutoff = Quality.Bluray1080p.Id })
.Build();
_parseResultMulti = new RemoteEpisode

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using FizzWare.NBuilder;
using FluentAssertions;
@ -42,9 +42,19 @@ public void Setup()
var languages = Languages.LanguageFixture.GetDefaultLanguages(Language.English, Language.Spanish);
var fakeSeries = Builder<Series>.CreateNew()
.With(c => c.Profile = new Profile { Cutoff = Quality.Bluray1080p.Id, Items = Qualities.QualityFixture.GetDefaultQualities()})
.With(l => l.LanguageProfile = new LanguageProfile { Cutoff = Language.Spanish, Languages = languages })
.Build();
.With(c => c.QualityProfile = new QualityProfile
{
UpgradeAllowed = true,
Cutoff = Quality.Bluray1080p.Id,
Items = Qualities.QualityFixture.GetDefaultQualities()
})
.With(l => l.LanguageProfile = new LanguageProfile
{
UpgradeAllowed = true,
Cutoff = Language.Spanish,
Languages = languages
})
.Build();
_parseResultMulti = new RemoteEpisode
{
@ -129,4 +139,4 @@ public void should_not_be_upgradable_if_qualities_are_the_same()
_upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse();
}
}
}
}

View file

@ -51,13 +51,15 @@ public void IsUpgradeTest(Quality current, int currentVersion, Quality newQualit
GivenAutoDownloadPropers(true);
var profile = new Profile
var profile = new QualityProfile
{
UpgradeAllowed = true,
Items = Qualities.QualityFixture.GetDefaultQualities()
};
var langProfile = new LanguageProfile
{
UpgradeAllowed = true,
Languages = LanguageFixture.GetDefaultLanguages(),
Cutoff = Language.English
};
@ -79,14 +81,16 @@ public void IsUpgradeTestLanguage(Quality current, int currentVersion, Language
{
GivenAutoDownloadPropers(true);
var profile = new Profile
var profile = new QualityProfile
{
UpgradeAllowed = true,
Items = Qualities.QualityFixture.GetDefaultQualities(),
Cutoff = cutoff.Id,
};
var langProfile = new LanguageProfile
{
UpgradeAllowed = true,
Languages = LanguageFixture.GetDefaultLanguages(),
Cutoff = languageCutoff
};
@ -108,7 +112,7 @@ public void should_return_false_if_proper_and_autoDownloadPropers_is_false()
{
GivenAutoDownloadPropers(false);
var profile = new Profile
var profile = new QualityProfile
{
Items = Qualities.QualityFixture.GetDefaultQualities(),
};

View file

@ -52,7 +52,7 @@ private RemoteEpisode GetRemoteEpisode(List<Episode> episodes, QualityModel qual
remoteEpisode.Release.PublishDate = DateTime.UtcNow;
remoteEpisode.Series = Builder<Series>.CreateNew()
.With(e => e.Profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities() })
.With(e => e.QualityProfile = new QualityProfile { Items = Qualities.QualityFixture.GetDefaultQualities() })
.Build();
return remoteEpisode;

View file

@ -23,7 +23,7 @@ public class AddFixture : CoreTest<PendingReleaseService>
private DownloadDecision _temporarilyRejected;
private Series _series;
private Episode _episode;
private Profile _profile;
private QualityProfile _profile;
private ReleaseInfo _release;
private ParsedEpisodeInfo _parsedEpisodeInfo;
private RemoteEpisode _remoteEpisode;
@ -38,19 +38,19 @@ public void Setup()
_episode = Builder<Episode>.CreateNew()
.Build();
_profile = new Profile
_profile = new QualityProfile
{
Name = "Test",
Cutoff = Quality.HDTV720p.Id,
Items = new List<ProfileQualityItem>
Items = new List<QualityProfileQualityItem>
{
new ProfileQualityItem { Allowed = true, Quality = Quality.HDTV720p },
new ProfileQualityItem { Allowed = true, Quality = Quality.WEBDL720p },
new ProfileQualityItem { Allowed = true, Quality = Quality.Bluray720p }
new QualityProfileQualityItem { Allowed = true, Quality = Quality.HDTV720p },
new QualityProfileQualityItem { Allowed = true, Quality = Quality.WEBDL720p },
new QualityProfileQualityItem { Allowed = true, Quality = Quality.Bluray720p }
},
};
_series.Profile = new LazyLoaded<Profile>(_profile);
_series.QualityProfile = new LazyLoaded<QualityProfile>(_profile);
_release = Builder<ReleaseInfo>.CreateNew().Build();

View file

@ -23,7 +23,7 @@ public class RemoveGrabbedFixture : CoreTest<PendingReleaseService>
private DownloadDecision _temporarilyRejected;
private Series _series;
private Episode _episode;
private Profile _profile;
private QualityProfile _profile;
private ReleaseInfo _release;
private ParsedEpisodeInfo _parsedEpisodeInfo;
private RemoteEpisode _remoteEpisode;
@ -38,19 +38,19 @@ public void Setup()
_episode = Builder<Episode>.CreateNew()
.Build();
_profile = new Profile
_profile = new QualityProfile
{
Name = "Test",
Cutoff = Quality.HDTV720p.Id,
Items = new List<ProfileQualityItem>
Items = new List<QualityProfileQualityItem>
{
new ProfileQualityItem { Allowed = true, Quality = Quality.HDTV720p },
new ProfileQualityItem { Allowed = true, Quality = Quality.WEBDL720p },
new ProfileQualityItem { Allowed = true, Quality = Quality.Bluray720p }
new QualityProfileQualityItem { Allowed = true, Quality = Quality.HDTV720p },
new QualityProfileQualityItem { Allowed = true, Quality = Quality.WEBDL720p },
new QualityProfileQualityItem { Allowed = true, Quality = Quality.Bluray720p }
},
};
_series.Profile = new LazyLoaded<Profile>(_profile);
_series.QualityProfile = new LazyLoaded<QualityProfile>(_profile);
_release = Builder<ReleaseInfo>.CreateNew().Build();

View file

@ -24,7 +24,7 @@ public class RemoveRejectedFixture : CoreTest<PendingReleaseService>
private DownloadDecision _temporarilyRejected;
private Series _series;
private Episode _episode;
private Profile _profile;
private QualityProfile _profile;
private ReleaseInfo _release;
private ParsedEpisodeInfo _parsedEpisodeInfo;
private RemoteEpisode _remoteEpisode;
@ -38,19 +38,19 @@ public void Setup()
_episode = Builder<Episode>.CreateNew()
.Build();
_profile = new Profile
_profile = new QualityProfile
{
Name = "Test",
Cutoff = Quality.HDTV720p.Id,
Items = new List<ProfileQualityItem>
Items = new List<QualityProfileQualityItem>
{
new ProfileQualityItem { Allowed = true, Quality = Quality.HDTV720p },
new ProfileQualityItem { Allowed = true, Quality = Quality.WEBDL720p },
new ProfileQualityItem { Allowed = true, Quality = Quality.Bluray720p }
new QualityProfileQualityItem { Allowed = true, Quality = Quality.HDTV720p },
new QualityProfileQualityItem { Allowed = true, Quality = Quality.WEBDL720p },
new QualityProfileQualityItem { Allowed = true, Quality = Quality.Bluray720p }
},
};
_series.Profile = new LazyLoaded<Profile>(_profile);
_series.QualityProfile = new LazyLoaded<QualityProfile>(_profile);
_release = Builder<ReleaseInfo>.CreateNew().Build();

View file

@ -21,20 +21,20 @@ namespace NzbDrone.Core.Test.HistoryTests
{
public class HistoryServiceFixture : CoreTest<HistoryService>
{
private Profile _profile;
private Profile _profileCustom;
private QualityProfile _profile;
private QualityProfile _profileCustom;
private LanguageProfile _languageProfile;
[SetUp]
public void Setup()
{
_profile = new Profile
_profile = new QualityProfile
{
Cutoff = Quality.WEBDL720p.Id,
Items = QualityFixture.GetDefaultQualities(),
};
_profileCustom = new Profile
_profileCustom = new QualityProfile
{
Cutoff = Quality.WEBDL720p.Id,
Items = QualityFixture.GetDefaultQualities(Quality.DVD),

View file

@ -57,7 +57,7 @@ public void Setup()
_series = Builder<Series>.CreateNew()
.With(e => e.Path = @"C:\Test\Series".AsOsAgnostic())
.With(e => e.Profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities() })
.With(e => e.QualityProfile = new QualityProfile { Items = Qualities.QualityFixture.GetDefaultQualities() })
.With(e => e.LanguageProfile = new LanguageProfile { Languages = Languages.LanguageFixture.GetDefaultLanguages() })
.Build();

View file

@ -26,7 +26,7 @@ public void Setup()
{
_series = Builder<Series>.CreateNew()
.With(s => s.SeriesType = SeriesTypes.Standard)
.With(e => e.Profile = new Profile
.With(e => e.QualityProfile = new QualityProfile
{
Items = Qualities.QualityFixture.GetDefaultQualities(),
})

View file

@ -40,7 +40,7 @@ public void Setup()
var outputPath = @"C:\Test\Unsorted\TV\30.Rock.S01E01".AsOsAgnostic();
var series = Builder<Series>.CreateNew()
.With(e => e.Profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities() })
.With(e => e.QualityProfile = new QualityProfile { Items = Qualities.QualityFixture.GetDefaultQualities() })
.With(l => l.LanguageProfile = new LanguageProfile
{
Cutoff = Language.Spanish,
@ -86,6 +86,13 @@ private void GivenNewDownload()
_approvedDecisions.ForEach(a => a.LocalEpisode.Path = Path.Combine(_downloadClientItem.OutputPath.ToString(), Path.GetFileName(a.LocalEpisode.Path)));
}
private void GivenExistingFileOnDisk()
{
Mocker.GetMock<IMediaFileService>()
.Setup(s => s.GetFilesWithRelativePath(It.IsAny<int>(), It.IsAny<string>()))
.Returns(new List<EpisodeFile>());
}
[Test]
public void should_not_import_any_if_there_are_no_approved_decisions()
{
@ -97,12 +104,16 @@ public void should_not_import_any_if_there_are_no_approved_decisions()
[Test]
public void should_import_each_approved()
{
GivenExistingFileOnDisk();
Subject.Import(_approvedDecisions, false).Should().HaveCount(5);
}
[Test]
public void should_only_import_approved()
{
GivenExistingFileOnDisk();
var all = new List<ImportDecision>();
all.AddRange(_rejectedDecisions);
all.AddRange(_approvedDecisions);
@ -116,6 +127,8 @@ public void should_only_import_approved()
[Test]
public void should_only_import_each_episode_once()
{
GivenExistingFileOnDisk();
var all = new List<ImportDecision>();
all.AddRange(_approvedDecisions);
all.Add(new ImportDecision(_approvedDecisions.First().LocalEpisode));
@ -147,6 +160,8 @@ public void should_publish_EpisodeImportedEvent_for_new_downloads()
[Test]
public void should_not_move_existing_files()
{
GivenExistingFileOnDisk();
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, false);
Mocker.GetMock<IUpgradeMediaFiles>()
@ -217,6 +232,8 @@ public void should_not_use_file_name_as_scenename_if_it_doesnt_looks_like_scenen
[Test]
public void should_import_larger_files_first()
{
GivenExistingFileOnDisk();
var fileDecision = _approvedDecisions.First();
fileDecision.LocalEpisode.Size = 1.Gigabytes();

View file

@ -7,12 +7,12 @@
namespace NzbDrone.Core.Test.Profiles
{
[TestFixture]
public class ProfileRepositoryFixture : DbTest<ProfileRepository, Profile>
public class ProfileRepositoryFixture : DbTest<QualityProfileRepository, QualityProfile>
{
[Test]
public void should_be_able_to_read_and_write()
{
var profile = new Profile
var profile = new QualityProfile
{
Items = Qualities.QualityFixture.GetDefaultQualities(Quality.Bluray1080p, Quality.DVD, Quality.HDTV720p),
Cutoff = Quality.Bluray1080p.Id,

View file

@ -10,7 +10,7 @@
namespace NzbDrone.Core.Test.Profiles
{
[TestFixture]
public class ProfileServiceFixture : CoreTest<ProfileService>
public class ProfileServiceFixture : CoreTest<QualityProfileService>
{
[Test]
public void init_should_add_default_profiles()
@ -18,7 +18,7 @@ public void init_should_add_default_profiles()
Subject.Handle(new ApplicationStartedEvent());
Mocker.GetMock<IProfileRepository>()
.Verify(v => v.Insert(It.IsAny<Profile>()), Times.Exactly(6));
.Verify(v => v.Insert(It.IsAny<QualityProfile>()), Times.Exactly(6));
}
[Test]
@ -28,32 +28,32 @@ public void Init_should_skip_if_any_profiles_already_exist()
{
Mocker.GetMock<IProfileRepository>()
.Setup(s => s.All())
.Returns(Builder<Profile>.CreateListOfSize(2).Build().ToList());
.Returns(Builder<QualityProfile>.CreateListOfSize(2).Build().ToList());
Subject.Handle(new ApplicationStartedEvent());
Mocker.GetMock<IProfileRepository>()
.Verify(v => v.Insert(It.IsAny<Profile>()), Times.Never());
.Verify(v => v.Insert(It.IsAny<QualityProfile>()), Times.Never());
}
[Test]
public void should_not_be_able_to_delete_profile_if_assigned_to_series()
{
var profile = Builder<Profile>.CreateNew()
var profile = Builder<QualityProfile>.CreateNew()
.With(p => p.Id = 2)
.Build();
var seriesList = Builder<Series>.CreateListOfSize(3)
.Random(1)
.With(c => c.ProfileId = profile.Id)
.With(c => c.QualityProfileId = profile.Id)
.Build().ToList();
Mocker.GetMock<ISeriesService>().Setup(c => c.GetAllSeries()).Returns(seriesList);
Mocker.GetMock<IProfileRepository>().Setup(c => c.Get(profile.Id)).Returns(profile);
Assert.Throws<ProfileInUseException>(() => Subject.Delete(profile.Id));
Assert.Throws<QualityProfileInUseException>(() => Subject.Delete(profile.Id));
Mocker.GetMock<IProfileRepository>().Verify(c => c.Delete(It.IsAny<int>()), Times.Never());
@ -65,7 +65,7 @@ public void should_delete_profile_if_not_assigned_to_series()
{
var seriesList = Builder<Series>.CreateListOfSize(3)
.All()
.With(c => c.ProfileId = 2)
.With(c => c.QualityProfileId = 2)
.Build().ToList();

View file

@ -61,7 +61,7 @@ public void should_be_able_to_convert_qualityTypes_to_int(Quality source, int ex
i.Should().Be(expected);
}
public static List<ProfileQualityItem> GetDefaultQualities(params Quality[] allowed)
public static List<QualityProfileQualityItem> GetDefaultQualities(params Quality[] allowed)
{
var qualities = new List<Quality>
{
@ -87,7 +87,7 @@ public static List<ProfileQualityItem> GetDefaultQualities(params Quality[] allo
var items = qualities
.Except(allowed)
.Concat(allowed)
.Select(v => new ProfileQualityItem { Quality = v, Allowed = allowed.Contains(v) }).ToList();
.Select(v => new QualityProfileQualityItem { Quality = v, Allowed = allowed.Contains(v) }).ToList();
return items;
}

View file

@ -14,48 +14,48 @@ public class QualityModelComparerFixture : CoreTest
private void GivenDefaultProfile()
{
Subject = new QualityModelComparer(new Profile { Items = QualityFixture.GetDefaultQualities() });
Subject = new QualityModelComparer(new QualityProfile { Items = QualityFixture.GetDefaultQualities() });
}
private void GivenCustomProfile()
{
Subject = new QualityModelComparer(new Profile { Items = QualityFixture.GetDefaultQualities(Quality.Bluray720p, Quality.DVD) });
Subject = new QualityModelComparer(new QualityProfile { Items = QualityFixture.GetDefaultQualities(Quality.Bluray720p, Quality.DVD) });
}
private void GivenGroupedProfile()
{
var profile = new Profile
var profile = new QualityProfile
{
Items = new List<ProfileQualityItem>
Items = new List<QualityProfileQualityItem>
{
new ProfileQualityItem
new QualityProfileQualityItem
{
Allowed = false,
Quality = Quality.SDTV
},
new ProfileQualityItem
new QualityProfileQualityItem
{
Allowed = false,
Quality = Quality.DVD
},
new ProfileQualityItem
new QualityProfileQualityItem
{
Allowed = true,
Items = new List<ProfileQualityItem>
Items = new List<QualityProfileQualityItem>
{
new ProfileQualityItem
new QualityProfileQualityItem
{
Allowed = true,
Quality = Quality.HDTV720p
},
new ProfileQualityItem
new QualityProfileQualityItem
{
Allowed = true,
Quality = Quality.WEBDL720p
}
}
},
new ProfileQualityItem
new QualityProfileQualityItem
{
Allowed = true,
Quality = Quality.Bluray720p

View file

@ -28,15 +28,15 @@ public class EpisodesWhereCutoffUnmetFixture : DbTest<EpisodeRepository, Episode
[SetUp]
public void Setup()
{
var profile = new Profile
var profile = new QualityProfile
{
Id = 1,
Cutoff = Quality.WEBDL480p.Id,
Items = new List<ProfileQualityItem>
Items = new List<QualityProfileQualityItem>
{
new ProfileQualityItem { Allowed = true, Quality = Quality.SDTV },
new ProfileQualityItem { Allowed = true, Quality = Quality.WEBDL480p },
new ProfileQualityItem { Allowed = true, Quality = Quality.RAWHD }
new QualityProfileQualityItem { Allowed = true, Quality = Quality.SDTV },
new QualityProfileQualityItem { Allowed = true, Quality = Quality.WEBDL480p },
new QualityProfileQualityItem { Allowed = true, Quality = Quality.RAWHD }
}
};
@ -52,7 +52,7 @@ public void Setup()
.With(s => s.Runtime = 30)
.With(s => s.Monitored = true)
.With(s => s.TitleSlug = "Title3")
.With(s => s.ProfileId = profile.Id)
.With(s => s.QualityProfileId = profile.Id)
.With(s => s.LanguageProfileId = langProfile.Id)
.BuildNew();
@ -61,7 +61,7 @@ public void Setup()
.With(s => s.Runtime = 30)
.With(s => s.Monitored = false)
.With(s => s.TitleSlug = "Title2")
.With(s => s.ProfileId = profile.Id)
.With(s => s.QualityProfileId = profile.Id)
.With(s => s.LanguageProfileId = langProfile.Id)
.BuildNew();

View file

@ -18,7 +18,7 @@ public class SeriesRepositoryFixture : DbTest<SeriesRepository, Series>
[Test]
public void should_lazyload_quality_profile()
{
var profile = new Profile
var profile = new QualityProfile
{
Items = Qualities.QualityFixture.GetDefaultQualities(Quality.Bluray1080p, Quality.DVD, Quality.HDTV720p),
@ -34,17 +34,17 @@ public void should_lazyload_quality_profile()
};
Mocker.Resolve<ProfileRepository>().Insert(profile);
Mocker.Resolve<QualityProfileRepository>().Insert(profile);
Mocker.Resolve<LanguageProfileRepository>().Insert(langProfile);
var series = Builder<Series>.CreateNew().BuildNew();
series.ProfileId = profile.Id;
series.QualityProfileId = profile.Id;
series.LanguageProfileId = langProfile.Id;
Subject.Insert(series);
StoredModel.Profile.Should().NotBeNull();
StoredModel.QualityProfile.Should().NotBeNull();
StoredModel.LanguageProfile.Should().NotBeNull();

View file

@ -23,7 +23,7 @@ public void Setup()
{
_series = Builder<Series>.CreateListOfSize(5)
.All()
.With(s => s.ProfileId = 1)
.With(s => s.QualityProfileId = 1)
.With(s => s.Monitored)
.With(s => s.SeasonFolder)
.With(s => s.Path = @"C:\Test\name".AsOsAgnostic())

View file

@ -42,7 +42,7 @@ private void ConvertQualityProfiles(IDbConnection conn, IDbTransaction tran)
var allowed = Json.Deserialize<List<Quality>>(allowedJson);
var items = Quality.DefaultQualityDefinitions.OrderBy(v => v.Weight).Select(v => new ProfileQualityItem { Quality = v.Quality, Allowed = allowed.Contains(v.Quality) }).ToList();
var items = Quality.DefaultQualityDefinitions.OrderBy(v => v.Weight).Select(v => new QualityProfileQualityItem { Quality = v.Quality, Allowed = allowed.Contains(v.Quality) }).ToList();
var allowedNewJson = qualityProfileItemConverter.ToDB(items);

View file

@ -0,0 +1,23 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(128)]
public class rename_quality_profiles_add_upgrade_allowed : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Rename.Table("Profiles").To("QualityProfiles");
Alter.Table("QualityProfiles").AddColumn("UpgradeAllowed").AsInt32().Nullable();
Alter.Table("LanguageProfiles").AddColumn("UpgradeAllowed").AsInt32().Nullable();
// Set upgrade allowed for existing profiles (default will be false for new profiles)
Update.Table("QualityProfiles").Set(new { UpgradeAllowed = true }).AllRows();
Update.Table("LanguageProfiles").Set(new { UpgradeAllowed = true }).AllRows();
Rename.Column("ProfileId").OnTable("Series").To("QualityProfileId");
}
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
@ -148,7 +148,8 @@ public TokenType Read()
{
var start = Index;
var end = start + 1;
while (end < Buffer.Length && (char.IsLetter(Buffer[end]) || Buffer[end] == '_')) end++;
while (end < Buffer.Length && (char.IsLetter(Buffer[end]) || char.IsNumber(Buffer[end]) || Buffer[end] == '_' || Buffer[end] == '(')) end++;
if (end >= Buffer.Length || Buffer[end] == ',' || Buffer[end] == ')' || char.IsWhiteSpace(Buffer[end]))
{
Index = end;

View file

@ -84,7 +84,7 @@ public static void Map()
Mapper.Entity<Series>().RegisterModel("Series")
.Ignore(s => s.RootFolderPath)
.Relationship()
.HasOne(s => s.Profile, s => s.ProfileId)
.HasOne(s => s.QualityProfile, s => s.QualityProfileId)
.HasOne(s => s.LanguageProfile, s => s.LanguageProfileId);
Mapper.Entity<EpisodeFile>().RegisterModel("EpisodeFiles")
@ -106,7 +106,7 @@ public static void Map()
.Ignore(d => d.GroupName)
.Ignore(d => d.Weight);
Mapper.Entity<Profile>().RegisterModel("Profiles");
Mapper.Entity<QualityProfile>().RegisterModel("QualityProfiles");
Mapper.Entity<LanguageProfile>().RegisterModel("LanguageProfiles");
Mapper.Entity<Log>().RegisterModel("Logs");
Mapper.Entity<NamingConfig>().RegisterModel("NamingConfig");
@ -145,7 +145,7 @@ private static void RegisterMappers()
MapRepository.Instance.RegisterTypeConverter(typeof(bool), new BooleanIntConverter());
MapRepository.Instance.RegisterTypeConverter(typeof(Enum), new EnumIntConverter());
MapRepository.Instance.RegisterTypeConverter(typeof(Quality), new QualityIntConverter());
MapRepository.Instance.RegisterTypeConverter(typeof(List<ProfileQualityItem>), new EmbeddedDocumentConverter(new QualityIntConverter()));
MapRepository.Instance.RegisterTypeConverter(typeof(List<QualityProfileQualityItem>), new EmbeddedDocumentConverter(new QualityIntConverter()));
MapRepository.Instance.RegisterTypeConverter(typeof(QualityModel), new EmbeddedDocumentConverter(new QualityIntConverter()));
MapRepository.Instance.RegisterTypeConverter(typeof(Dictionary<string, string>), new EmbeddedDocumentConverter());
MapRepository.Instance.RegisterTypeConverter(typeof(List<int>), new EmbeddedDocumentConverter());

View file

@ -59,7 +59,7 @@ private int CompareAll(params int[] comparers)
private int CompareQuality(DownloadDecision x, DownloadDecision y)
{
return CompareAll(CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.Series.Profile.Value.GetIndex(remoteEpisode.ParsedEpisodeInfo.Quality.Quality)),
return CompareAll(CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.Series.QualityProfile.Value.GetIndex(remoteEpisode.ParsedEpisodeInfo.Quality.Quality)),
CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.ParsedEpisodeInfo.Quality.Revision.Real),
CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.ParsedEpisodeInfo.Quality.Revision.Version));
}

View file

@ -24,7 +24,7 @@ public CutoffSpecification(UpgradableSpecification upgradableSpecification, IPre
public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
{
var profile = subject.Series.Profile.Value;
var profile = subject.Series.QualityProfile.Value;
foreach (var file in subject.Episodes.Where(c => c.EpisodeFileId != 0).Select(c => c.EpisodeFile.Value))
{

View file

@ -21,7 +21,7 @@ public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase
{
_logger.Debug("Checking if report meets quality requirements. {0}", subject.ParsedEpisodeInfo.Quality);
var profile = subject.Series.Profile.Value;
var profile = subject.Series.QualityProfile.Value;
var qualityIndex = profile.GetIndex(subject.ParsedEpisodeInfo.Quality.Quality);
var qualityOrGroup = profile.Items[qualityIndex.Index];

View file

@ -31,7 +31,7 @@ public QueueSpecification(IQueueService queueService,
public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
{
var queue = _queueService.GetQueue();
var matchingSeries = queue.Where(q => q.Series.Id == subject.Series.Id);
var matchingSeries = queue.Where(q => q.RemoteEpisode.Series.Id == subject.Series.Id);
var matchingEpisode = matchingSeries.Where(q => q.RemoteEpisode.Episodes.Select(e => e.Id).Intersect(subject.Episodes.Select(e => e.Id)).Any());
foreach (var queueItem in matchingEpisode)
@ -41,7 +41,7 @@ public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCr
_logger.Debug("Checking if existing release in queue meets cutoff. Queued quality is: {0} - {1}", remoteEpisode.ParsedEpisodeInfo.Quality, remoteEpisode.ParsedEpisodeInfo.Language);
var queuedItemPreferredWordScore = _preferredWordServiceCalculator.Calculate(subject.Series, queueItem.Title);
if (!_upgradableSpecification.CutoffNotMet(subject.Series.Profile,
if (!_upgradableSpecification.CutoffNotMet(subject.Series.QualityProfile,
subject.Series.LanguageProfile,
remoteEpisode.ParsedEpisodeInfo.Quality,
remoteEpisode.ParsedEpisodeInfo.Language,
@ -54,7 +54,7 @@ public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCr
_logger.Debug("Checking if release is higher quality than queued release. Queued quality is: {0} - {1}", remoteEpisode.ParsedEpisodeInfo.Quality, remoteEpisode.ParsedEpisodeInfo.Language);
if (!_upgradableSpecification.IsUpgradable(subject.Series.Profile,
if (!_upgradableSpecification.IsUpgradable(subject.Series.QualityProfile,
subject.Series.LanguageProfile,
remoteEpisode.ParsedEpisodeInfo.Quality,
remoteEpisode.ParsedEpisodeInfo.Language,

View file

@ -42,7 +42,7 @@ public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase
return Decision.Accept();
}
var profile = subject.Series.Profile.Value;
var profile = subject.Series.QualityProfile.Value;
var languageProfile = subject.Series.LanguageProfile.Value;
var delayProfile = _delayProfileService.BestForTags(subject.Series.Tags);
var delay = delayProfile.GetProtocolDelay(subject.Release.DownloadProtocol);
@ -50,7 +50,7 @@ public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase
if (delay == 0)
{
_logger.Debug("Profile does not require a waiting period before download for {0}.", subject.Release.DownloadProtocol);
_logger.Debug("QualityProfile does not require a waiting period before download for {0}.", subject.Release.DownloadProtocol);
return Decision.Accept();
}

View file

@ -58,7 +58,7 @@ public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase
var preferredWordScore = _preferredWordServiceCalculator.Calculate(subject.Series, mostRecent.SourceTitle);
var cutoffUnmet = _upgradableSpecification.CutoffNotMet(
subject.Series.Profile,
subject.Series.QualityProfile,
subject.Series.LanguageProfile,
mostRecent.Quality,
mostRecent.Language,
@ -67,7 +67,7 @@ public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase
subject.PreferredWordScore);
var upgradeable = _upgradableSpecification.IsUpgradable(
subject.Series.Profile,
subject.Series.QualityProfile,
subject.Series.LanguageProfile,
mostRecent.Quality,
mostRecent.Language,

View file

@ -8,10 +8,10 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
{
public interface IUpgradableSpecification
{
bool IsUpgradable(Profile profile, LanguageProfile languageProfile, QualityModel currentQuality, Language currentLanguage, int currentScore, QualityModel newQuality, Language newLanguage, int newScore);
bool QualityCutoffNotMet(Profile profile, QualityModel currentQuality, QualityModel newQuality = null);
bool IsUpgradable(QualityProfile profile, LanguageProfile languageProfile, QualityModel currentQuality, Language currentLanguage, int currentScore, QualityModel newQuality, Language newLanguage, int newScore);
bool QualityCutoffNotMet(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null);
bool LanguageCutoffNotMet(LanguageProfile languageProfile, Language currentLanguage);
bool CutoffNotMet(Profile profile, LanguageProfile languageProfile, QualityModel currentQuality, Language currentLanguage, int currentScore, QualityModel newQuality = null, int newScore = 0);
bool CutoffNotMet(QualityProfile profile, LanguageProfile languageProfile, QualityModel currentQuality, Language currentLanguage, int currentScore, QualityModel newQuality = null, int newScore = 0);
bool IsRevisionUpgrade(QualityModel currentQuality, QualityModel newQuality);
}
@ -37,14 +37,15 @@ private bool IsLanguageUpgradable(LanguageProfile profile, Language currentLangu
return true;
}
private bool IsQualityUpgradable(Profile profile, QualityModel currentQuality, QualityModel newQuality = null)
private bool IsQualityUpgradable(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null)
{
if (newQuality != null)
{
var compare = new QualityModelComparer(profile).Compare(newQuality, currentQuality);
if (compare <= 0)
{
_logger.Debug("existing item has better quality. skipping");
_logger.Debug("Existing item has better quality, skipping");
return false;
}
}
@ -56,25 +57,25 @@ private bool IsPreferredWordUpgradable(int currentScore, int newScore)
return newScore > currentScore;
}
public bool IsUpgradable(Profile profile, LanguageProfile languageProfile, QualityModel currentQuality, Language currentLanguage, int currentScore, QualityModel newQuality, Language newLanguage, int newScore)
public bool IsUpgradable(QualityProfile qualityProfile, LanguageProfile languageProfile, QualityModel currentQuality, Language currentLanguage, int currentScore, QualityModel newQuality, Language newLanguage, int newScore)
{
if (IsQualityUpgradable(profile, currentQuality, newQuality))
if (IsQualityUpgradable(qualityProfile, currentQuality, newQuality) && qualityProfile.UpgradeAllowed)
{
return true;
}
if (new QualityModelComparer(profile).Compare(newQuality, currentQuality) != 0)
if (new QualityModelComparer(qualityProfile).Compare(newQuality, currentQuality) < 0)
{
_logger.Debug("Existing item has better qualitys, skipping");
_logger.Debug("Existing item has better quality, skipping");
return false;
}
if (IsLanguageUpgradable(languageProfile, currentLanguage, newLanguage))
if (IsLanguageUpgradable(languageProfile, currentLanguage, newLanguage) && languageProfile.UpgradeAllowed)
{
return true;
}
if (new LanguageComparer(languageProfile).Compare(newLanguage, currentLanguage) != 0)
if (new LanguageComparer(languageProfile).Compare(newLanguage, currentLanguage) < 0)
{
_logger.Debug("Existing item has better language, skipping");
return false;
@ -89,7 +90,7 @@ public bool IsUpgradable(Profile profile, LanguageProfile languageProfile, Quali
return true;
}
public bool QualityCutoffNotMet(Profile profile, QualityModel currentQuality, QualityModel newQuality = null)
public bool QualityCutoffNotMet(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null)
{
var qualityCompare = new QualityModelComparer(profile).Compare(currentQuality.Quality.Id, profile.Cutoff);
@ -113,7 +114,7 @@ public bool LanguageCutoffNotMet(LanguageProfile languageProfile, Language curre
return languageCompare < 0;
}
public bool CutoffNotMet(Profile profile, LanguageProfile languageProfile, QualityModel currentQuality, Language currentLanguage, int currentScore, QualityModel newQuality = null, int newScore = 0)
public bool CutoffNotMet(QualityProfile profile, LanguageProfile languageProfile, QualityModel currentQuality, Language currentLanguage, int currentScore, QualityModel newQuality = null, int newScore = 0)
{
// If we can upgrade the language (it is not the cutoff) then the quality doesn't
// matter as we can always get same quality with prefered language.

View file

@ -34,8 +34,7 @@ public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase
_logger.Debug("Comparing file quality and language with report. Existing file is {0} - {1}", file.Quality, file.Language);
if (!_upgradableSpecification.IsUpgradable(subject.Series.Profile,
if (!_upgradableSpecification.IsUpgradable(subject.Series.QualityProfile,
subject.Series.LanguageProfile,
file.Quality,
file.Language,
@ -44,7 +43,7 @@ public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase
subject.ParsedEpisodeInfo.Language,
subject.PreferredWordScore))
{
return Decision.Reject("Quality for existing file on disk is of equal or higher preference: {0} - {1}", file.Quality, file.Language);
return Decision.Reject("Existing file on disk is of equal or higher preference: {0} - {1}", file.Quality, file.Language);
}
}

View file

@ -216,7 +216,7 @@ public List<RemoteEpisode> GetPendingRemoteEpisodes(int seriesId)
{
var series = g.First().Series;
return g.OrderByDescending(e => e.Quality, new QualityModelComparer(series.Profile))
return g.OrderByDescending(e => e.Quality, new QualityModelComparer(series.QualityProfile))
.ThenBy(q => PrioritizeDownloadProtocol(q.Series, q.Protocol))
.First();
});
@ -375,7 +375,7 @@ private void RemoveGrabbed(RemoteEpisode remoteEpisode)
return;
}
var profile = remoteEpisode.Series.Profile.Value;
var profile = remoteEpisode.Series.QualityProfile.Value;
foreach (var existingReport in existingReports)
{

View file

@ -50,7 +50,7 @@ public List<ImportResult> Import(List<ImportDecision> decisions, bool newDownloa
{
var qualifiedImports = decisions.Where(c => c.Approved)
.GroupBy(c => c.LocalEpisode.Series.Id, (i, s) => s
.OrderByDescending(c => c.LocalEpisode.Quality, new QualityModelComparer(s.First().LocalEpisode.Series.Profile))
.OrderByDescending(c => c.LocalEpisode.Quality, new QualityModelComparer(s.First().LocalEpisode.Series.QualityProfile))
.ThenByDescending(c => c.LocalEpisode.Language, new LanguageComparer(s.First().LocalEpisode.Series.LanguageProfile))
.ThenByDescending(c => c.LocalEpisode.Size))
.SelectMany(c => c)

View file

@ -19,7 +19,7 @@ public UpgradeSpecification(Logger logger)
public Decision IsSatisfiedBy(LocalEpisode localEpisode, DownloadClientItem downloadClientItem)
{
var qualityComparer = new QualityModelComparer(localEpisode.Series.Profile);
var qualityComparer = new QualityModelComparer(localEpisode.Series.QualityProfile);
var languageComparer = new LanguageComparer(localEpisode.Series.LanguageProfile);
if (localEpisode.Episodes.Any(e => e.EpisodeFileId != 0 && qualityComparer.Compare(e.EpisodeFile.Value.Quality, localEpisode.Quality) > 0))

View file

@ -137,6 +137,7 @@
<Compile Include="Configuration\ResetApiKeyCommand.cs" />
<Compile Include="Datastore\Migration\130_episode_last_searched_time.cs" />
<Compile Include="Datastore\Migration\129_add_relative_original_path_to_episode_file.cs" />
<Compile Include="Datastore\Migration\128_rename_quality_profiles_add_upgrade_allowed.cs" />
<Compile Include="DecisionEngine\Specifications\AlreadyImportedSpecification.cs" />
<Compile Include="CustomFilters\CustomFilter.cs" />
<Compile Include="CustomFilters\CustomFilterRepository.cs" />
@ -1000,11 +1001,11 @@
<Compile Include="Profiles\Delay\DelayProfileTagInUseValidator.cs" />
<Compile Include="Profiles\Languages\LanguageProfileItem.cs" />
<Compile Include="Profiles\Languages\LanguageProfileRepository.cs" />
<Compile Include="Profiles\Qualities\Profile.cs" />
<Compile Include="Profiles\Qualities\ProfileInUseException.cs" />
<Compile Include="Profiles\Qualities\ProfileQualityItem.cs" />
<Compile Include="Profiles\Qualities\ProfileRepository.cs" />
<Compile Include="Profiles\Qualities\ProfileService.cs" />
<Compile Include="Profiles\Qualities\QualityProfile.cs" />
<Compile Include="Profiles\Qualities\QualityProfileInUseException.cs" />
<Compile Include="Profiles\Qualities\QualityProfileQualityItem.cs" />
<Compile Include="Profiles\Qualities\QualityProfileRepository.cs" />
<Compile Include="Profiles\Qualities\QualityProfileService.cs" />
<Compile Include="Profiles\Qualities\QualityIndex.cs" />
<Compile Include="Profiles\Releases\PreferredWordService.cs" />
<Compile Include="ProgressMessaging\ProgressMessageContext.cs" />

View file

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Languages;
@ -9,6 +9,7 @@ public class LanguageProfile : ModelBase
{
public string Name { get; set; }
public List<LanguageProfileItem> Languages { get; set; }
public bool UpgradeAllowed { get; set; }
public Language Cutoff { get; set; }
public Language LastAllowedLanguage()

View file

@ -1,13 +0,0 @@
using System.Net;
using NzbDrone.Core.Exceptions;
namespace NzbDrone.Core.Profiles.Qualities
{
public class ProfileInUseException : NzbDroneClientException
{
public ProfileInUseException(string name)
: base(HttpStatusCode.BadRequest, "Profile [{0}] is in use.", name)
{
}
}
}

View file

@ -1,23 +0,0 @@
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging.Events;
namespace NzbDrone.Core.Profiles.Qualities
{
public interface IProfileRepository : IBasicRepository<Profile>
{
bool Exists(int id);
}
public class ProfileRepository : BasicRepository<Profile>, IProfileRepository
{
public ProfileRepository(IMainDatabase database, IEventAggregator eventAggregator)
: base(database, eventAggregator)
{
}
public bool Exists(int id)
{
return DataMapper.Query<Profile>().Where(p => p.Id == id).GetRowCount() == 1;
}
}
}

View file

@ -1,15 +1,16 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Qualities;
namespace NzbDrone.Core.Profiles.Qualities
{
public class Profile : ModelBase
public class QualityProfile : ModelBase
{
public string Name { get; set; }
public bool UpgradeAllowed { get; set; }
public int Cutoff { get; set; }
public List<ProfileQualityItem> Items { get; set; }
public List<QualityProfileQualityItem> Items { get; set; }
public Quality LastAllowedQuality()
{

View file

@ -0,0 +1,13 @@
using System.Net;
using NzbDrone.Core.Exceptions;
namespace NzbDrone.Core.Profiles.Qualities
{
public class QualityProfileInUseException : NzbDroneClientException
{
public QualityProfileInUseException(string name)
: base(HttpStatusCode.BadRequest, "QualityProfile [{0}] is in use.", name)
{
}
}
}

View file

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using NzbDrone.Common.Extensions;
@ -7,19 +7,19 @@
namespace NzbDrone.Core.Profiles.Qualities
{
public class ProfileQualityItem : IEmbeddedDocument
public class QualityProfileQualityItem : IEmbeddedDocument
{
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public int Id { get; set; }
public string Name { get; set; }
public Quality Quality { get; set; }
public List<ProfileQualityItem> Items { get; set; }
public List<QualityProfileQualityItem> Items { get; set; }
public bool Allowed { get; set; }
public ProfileQualityItem()
public QualityProfileQualityItem()
{
Items = new List<ProfileQualityItem>();
Items = new List<QualityProfileQualityItem>();
}
public List<Quality> GetQualities()

View file

@ -0,0 +1,23 @@
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging.Events;
namespace NzbDrone.Core.Profiles.Qualities
{
public interface IProfileRepository : IBasicRepository<QualityProfile>
{
bool Exists(int id);
}
public class QualityProfileRepository : BasicRepository<QualityProfile>, IProfileRepository
{
public QualityProfileRepository(IMainDatabase database, IEventAggregator eventAggregator)
: base(database, eventAggregator)
{
}
public bool Exists(int id)
{
return DataMapper.Query<QualityProfile>().Where(p => p.Id == id).GetRowCount() == 1;
}
}
}

View file

@ -10,55 +10,55 @@ namespace NzbDrone.Core.Profiles.Qualities
{
public interface IProfileService
{
Profile Add(Profile profile);
void Update(Profile profile);
QualityProfile Add(QualityProfile profile);
void Update(QualityProfile profile);
void Delete(int id);
List<Profile> All();
Profile Get(int id);
List<QualityProfile> All();
QualityProfile Get(int id);
bool Exists(int id);
Profile GetDefaultProfile(string name, Quality cutoff = null, params Quality[] allowed);
QualityProfile GetDefaultProfile(string name, Quality cutoff = null, params Quality[] allowed);
}
public class ProfileService : IProfileService, IHandle<ApplicationStartedEvent>
public class QualityProfileService : IProfileService, IHandle<ApplicationStartedEvent>
{
private readonly IProfileRepository _profileRepository;
private readonly ISeriesService _seriesService;
private readonly Logger _logger;
public ProfileService(IProfileRepository profileRepository, ISeriesService seriesService, Logger logger)
public QualityProfileService(IProfileRepository profileRepository, ISeriesService seriesService, Logger logger)
{
_profileRepository = profileRepository;
_seriesService = seriesService;
_logger = logger;
}
public Profile Add(Profile profile)
public QualityProfile Add(QualityProfile profile)
{
return _profileRepository.Insert(profile);
}
public void Update(Profile profile)
public void Update(QualityProfile profile)
{
_profileRepository.Update(profile);
}
public void Delete(int id)
{
if (_seriesService.GetAllSeries().Any(c => c.ProfileId == id))
if (_seriesService.GetAllSeries().Any(c => c.QualityProfileId == id))
{
var profile = _profileRepository.Get(id);
throw new ProfileInUseException(profile.Name);
throw new QualityProfileInUseException(profile.Name);
}
_profileRepository.Delete(id);
}
public List<Profile> All()
public List<QualityProfile> All()
{
return _profileRepository.All().ToList();
}
public Profile Get(int id)
public QualityProfile Get(int id)
{
return _profileRepository.Get(id);
}
@ -123,10 +123,10 @@ public void Handle(ApplicationStartedEvent message)
Quality.Bluray1080p);
}
public Profile GetDefaultProfile(string name, Quality cutoff = null, params Quality[] allowed)
public QualityProfile GetDefaultProfile(string name, Quality cutoff = null, params Quality[] allowed)
{
var groupedQualites = Quality.DefaultQualityDefinitions.GroupBy(q => q.Weight);
var items = new List<ProfileQualityItem>();
var items = new List<QualityProfileQualityItem>();
var groupId = 1000;
var profileCutoff = cutoff == null ? Quality.Unknown.Id : cutoff.Id;
@ -136,17 +136,17 @@ public Profile GetDefaultProfile(string name, Quality cutoff = null, params Qual
{
var quality = group.First().Quality;
items.Add(new ProfileQualityItem { Quality = group.First().Quality, Allowed = allowed.Contains(quality) });
items.Add(new QualityProfileQualityItem { Quality = group.First().Quality, Allowed = allowed.Contains(quality) });
continue;
}
var groupAllowed = group.Any(g => allowed.Contains(g.Quality));
items.Add(new ProfileQualityItem
items.Add(new QualityProfileQualityItem
{
Id = groupId,
Name = group.First().GroupName,
Items = group.Select(g => new ProfileQualityItem
Items = group.Select(g => new QualityProfileQualityItem
{
Quality = g.Quality,
Allowed = groupAllowed
@ -162,7 +162,7 @@ public Profile GetDefaultProfile(string name, Quality cutoff = null, params Qual
groupId++;
}
var qualityProfile = new Profile
var qualityProfile = new QualityProfile
{
Name = name,
Cutoff = profileCutoff,
@ -172,7 +172,7 @@ public Profile GetDefaultProfile(string name, Quality cutoff = null, params Qual
return qualityProfile;
}
private Profile AddDefaultProfile(string name, Quality cutoff, params Quality[] allowed)
private QualityProfile AddDefaultProfile(string name, Quality cutoff, params Quality[] allowed)
{
var profile = GetDefaultProfile(name, cutoff, allowed);

View file

@ -6,9 +6,9 @@ namespace NzbDrone.Core.Qualities
{
public class QualityModelComparer : IComparer<Quality>, IComparer<QualityModel>
{
private readonly Profile _profile;
private readonly QualityProfile _profile;
public QualityModelComparer(Profile profile)
public QualityModelComparer(QualityProfile profile)
{
Ensure.That(profile, () => profile).IsNotNull();
Ensure.That(profile.Items, () => profile.Items).HasItems();

View file

@ -262,7 +262,7 @@ private string BuildQualityCutoffWhereClause(List<QualitiesBelowCutoff> qualitie
{
foreach (var belowCutoff in profile.QualityIds)
{
clauses.Add(string.Format("([t1].[ProfileId] = {0} AND [t2].[Quality] LIKE '%_quality_: {1},%')", profile.ProfileId, belowCutoff));
clauses.Add(string.Format("([t1].[QualityProfileId] = {0} AND [t2].[Quality] LIKE '%_quality_: {1},%')", profile.ProfileId, belowCutoff));
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using Marr.Data;
using NzbDrone.Common.Extensions;
@ -30,7 +30,7 @@ public Series()
public string Overview { get; set; }
public string AirTime { get; set; }
public bool Monitored { get; set; }
public int ProfileId { get; set; }
public int QualityProfileId { get; set; }
public int LanguageProfileId { get; set; }
public bool SeasonFolder { get; set; }
public DateTime? LastInfoSync { get; set; }
@ -49,7 +49,7 @@ public Series()
public string RootFolderPath { get; set; }
public DateTime Added { get; set; }
public DateTime? FirstAired { get; set; }
public LazyLoaded<Profile> Profile { get; set; }
public LazyLoaded<QualityProfile> QualityProfile { get; set; }
public LazyLoaded<LanguageProfile> LanguageProfile { get; set; }
public List<Season> Seasons { get; set; }
@ -67,7 +67,7 @@ public void ApplyChanges(Series otherSeries)
Seasons = otherSeries.Seasons;
Path = otherSeries.Path;
ProfileId = otherSeries.ProfileId;
QualityProfileId = otherSeries.QualityProfileId;
LanguageProfileId = otherSeries.LanguageProfileId;
SeasonFolder = otherSeries.SeasonFolder;
@ -79,4 +79,4 @@ public void ApplyChanges(Series otherSeries)
AddOptions = otherSeries.AddOptions;
}
}
}
}

View file

@ -8,7 +8,7 @@ public class ProfileExistsValidator : PropertyValidator
private readonly IProfileService _profileService;
public ProfileExistsValidator(IProfileService profileService)
: base("Profile does not exist")
: base("QualityProfile does not exist")
{
_profileService = profileService;
}

View file

@ -69,7 +69,7 @@ public static EpisodeFileResource ToResource(this EpisodeFile model, NzbDrone.Co
Language = model.Language,
Quality = model.Quality,
MediaInfo = model.MediaInfo.ToResource(model.SceneName),
QualityCutoffNotMet = upgradableSpecification.QualityCutoffNotMet(series.Profile.Value, model.Quality),
QualityCutoffNotMet = upgradableSpecification.QualityCutoffNotMet(series.QualityProfile.Value, model.Quality),
LanguageCutoffNotMet = upgradableSpecification.LanguageCutoffNotMet(series.LanguageProfile.Value, model.Language)
};
}

View file

@ -51,7 +51,7 @@ protected HistoryResource MapToResource(NzbDrone.Core.History.History model, boo
if (model.Series != null)
{
resource.QualityCutoffNotMet = _upgradableSpecification.QualityCutoffNotMet(model.Series.Profile.Value, model.Quality);
resource.QualityCutoffNotMet = _upgradableSpecification.QualityCutoffNotMet(model.Series.QualityProfile.Value, model.Quality);
resource.LanguageCutoffNotMet = _upgradableSpecification.LanguageCutoffNotMet(model.Series.LanguageProfile, model.Language);
}

View file

@ -30,7 +30,7 @@ protected virtual ReleaseResource MapDecision(DownloadDecision decision, int ini
{
release.QualityWeight = decision.RemoteEpisode
.Series
.Profile.Value
.QualityProfile.Value
.Items.FindIndex(v => v.Quality == release.Quality.Quality) * 100;
release.LanguageWeight = decision.RemoteEpisode

View file

@ -8,6 +8,7 @@ namespace Sonarr.Api.V3.Profiles.Language
public class LanguageProfileResource : RestResource
{
public string Name { get; set; }
public bool UpgradeAllowed { get; set; }
public NzbDrone.Core.Languages.Language Cutoff { get; set; }
public List<LanguageProfileItemResource> Languages { get; set; }
}
@ -28,6 +29,7 @@ public static LanguageProfileResource ToResource(this LanguageProfile model)
{
Id = model.Id,
Name = model.Name,
UpgradeAllowed = model.UpgradeAllowed,
Cutoff = model.Cutoff,
Languages = model.Languages.ConvertAll(ToResource)
};
@ -52,6 +54,7 @@ public static LanguageProfile ToModel(this LanguageProfileResource resource)
{
Id = resource.Id,
Name = resource.Name,
UpgradeAllowed = resource.UpgradeAllowed,
Cutoff = (NzbDrone.Core.Languages.Language)resource.Cutoff.Id,
Languages = resource.Languages.ConvertAll(ToModel)
};

View file

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Profiles.Qualities;
using Sonarr.Http.REST;
@ -8,6 +8,7 @@ namespace Sonarr.Api.V3.Profiles.Quality
public class QualityProfileResource : RestResource
{
public string Name { get; set; }
public bool UpgradeAllowed { get; set; }
public int Cutoff { get; set; }
public List<QualityProfileQualityItemResource> Items { get; set; }
}
@ -27,7 +28,7 @@ public QualityProfileQualityItemResource()
public static class ProfileResourceMapper
{
public static QualityProfileResource ToResource(this Profile model)
public static QualityProfileResource ToResource(this QualityProfile model)
{
if (model == null) return null;
@ -35,12 +36,13 @@ public static QualityProfileResource ToResource(this Profile model)
{
Id = model.Id,
Name = model.Name,
UpgradeAllowed = model.UpgradeAllowed,
Cutoff = model.Cutoff,
Items = model.Items.ConvertAll(ToResource),
};
}
public static QualityProfileQualityItemResource ToResource(this ProfileQualityItem model)
public static QualityProfileQualityItemResource ToResource(this QualityProfileQualityItem model)
{
if (model == null) return null;
@ -54,24 +56,25 @@ public static QualityProfileQualityItemResource ToResource(this ProfileQualityIt
};
}
public static Profile ToModel(this QualityProfileResource resource)
public static QualityProfile ToModel(this QualityProfileResource resource)
{
if (resource == null) return null;
return new Profile
return new QualityProfile
{
Id = resource.Id,
Name = resource.Name,
UpgradeAllowed = resource.UpgradeAllowed,
Cutoff = resource.Cutoff,
Items = resource.Items.ConvertAll(ToModel)
};
}
public static ProfileQualityItem ToModel(this QualityProfileQualityItemResource resource)
public static QualityProfileQualityItem ToModel(this QualityProfileQualityItemResource resource)
{
if (resource == null) return null;
return new ProfileQualityItem
return new QualityProfileQualityItem
{
Id = resource.Id,
Name = resource.Name,
@ -81,9 +84,9 @@ public static ProfileQualityItem ToModel(this QualityProfileQualityItemResource
};
}
public static List<QualityProfileResource> ToResource(this IEnumerable<Profile> models)
public static List<QualityProfileResource> ToResource(this IEnumerable<QualityProfile> models)
{
return models.Select(ToResource).ToList();
}
}
}
}

View file

@ -38,7 +38,7 @@ private Response SaveAll()
if (resource.QualityProfileId.HasValue)
{
series.ProfileId = resource.QualityProfileId.Value;
series.QualityProfileId = resource.QualityProfileId.Value;
}
if (resource.LanguageProfileId.HasValue)

View file

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Tv;
using Sonarr.Http.REST;
@ -12,7 +11,7 @@ public class SeriesResource : RestResource
{
//Todo: Sorters should be done completely on the client
//Todo: Is there an easy way to keep IgnoreArticlesWhenSorting in sync between, Series, History, Missing?
//Todo: We should get the entire Profile instead of ID and Name separately
//Todo: We should get the entire QualityProfile instead of ID and Name separately
//View Only
public string Title { get; set; }
@ -97,7 +96,7 @@ public static SeriesResource ToResource(this NzbDrone.Core.Tv.Series model, bool
Year = model.Year,
Path = model.Path,
QualityProfileId = model.ProfileId,
QualityProfileId = model.QualityProfileId,
LanguageProfileId = model.LanguageProfileId,
SeasonFolder = model.SeasonFolder,
@ -155,7 +154,7 @@ public static NzbDrone.Core.Tv.Series ToModel(this SeriesResource resource)
Year = resource.Year,
Path = resource.Path,
ProfileId = resource.QualityProfileId,
QualityProfileId = resource.QualityProfileId,
LanguageProfileId = resource.LanguageProfileId,
SeasonFolder = resource.SeasonFolder,