Add upgrade allowed to language and profiles

pull/2789/head
Mark McDowall 6 years ago committed by Taloth Saldono
parent 853f25468c
commit f345977e3f

@ -66,7 +66,7 @@ namespace NzbDrone.Api.EpisodeFiles
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
};

@ -43,7 +43,7 @@ namespace NzbDrone.Api.History
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;

@ -29,7 +29,7 @@ namespace NzbDrone.Api.Indexers
if (decision.RemoteEpisode.Series != null)
{
release.QualityWeight = decision.RemoteEpisode.Series
.Profile.Value
.QualityProfile.Value
.Items.FindIndex(v => v.Quality == release.Quality.Quality) * 100;
}

@ -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 @@ namespace NzbDrone.Api.Profiles
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 @@ namespace NzbDrone.Api.Profiles
Id = model.Id,
Name = model.Name,
UpgradeAllowed = model.UpgradeAllowed,
Cutoff = cutoff,
// Flatten groups so things don't explode
@ -64,7 +66,7 @@ namespace NzbDrone.Api.Profiles
};
}
public static ProfileQualityItemResource ToResource(this ProfileQualityItem model)
public static ProfileQualityItemResource ToResource(this QualityProfileQualityItem model)
{
if (model == null) return null;
@ -75,32 +77,33 @@ namespace NzbDrone.Api.Profiles
};
}
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();
}

@ -23,10 +23,10 @@ namespace NzbDrone.Api.Profiles
{
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;

@ -16,7 +16,7 @@ namespace NzbDrone.Api.Series
//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 @@ namespace NzbDrone.Api.Series
Year = model.Year,
Path = model.Path,
ProfileId = model.ProfileId,
ProfileId = model.QualityProfileId,
LanguageProfileId = model.LanguageProfileId,
SeasonFolder = model.SeasonFolder,
@ -179,7 +179,7 @@ namespace NzbDrone.Api.Series
Year = resource.Year,
Path = resource.Path,
ProfileId = resource.ProfileId,
QualityProfileId = resource.ProfileId,
LanguageProfileId = resource.LanguageProfileId,
SeasonFolder = resource.SeasonFolder,

@ -20,7 +20,7 @@ namespace NzbDrone.Core.Test.Datastore
[SetUp]
public void Setup()
{
var profile = new Profile
var profile = new QualityProfile
{
Name = "Test",
Cutoff = Quality.WEBDL720p.Id,
@ -39,7 +39,7 @@ namespace NzbDrone.Core.Test.Datastore
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 @@ namespace NzbDrone.Core.Test.Datastore
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 @@ namespace NzbDrone.Core.Test.Datastore
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 @@ namespace NzbDrone.Core.Test.Datastore
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);
}
}

@ -19,7 +19,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[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(),

@ -53,7 +53,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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()
})

@ -35,7 +35,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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();
}

@ -33,13 +33,15 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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();
}
}
}

@ -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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[SetUp]
public void Setup()
{
_profile = Builder<Profile>.CreateNew()
_profile = Builder<QualityProfile>.CreateNew()
.Build();
_langProfile = Builder<LanguageProfile>.CreateNew()
@ -45,7 +45,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
.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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
.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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
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);
}

@ -55,7 +55,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
};
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();

@ -12,7 +12,6 @@ using NzbDrone.Core.Parser.Model;
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
};
_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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
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);

@ -38,7 +38,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
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

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using FizzWare.NBuilder;
using FluentAssertions;
@ -42,9 +42,19 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
_upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse();
}
}
}
}

@ -51,13 +51,15 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{
GivenAutoDownloadPropers(false);
var profile = new Profile
var profile = new QualityProfile
{
Items = Qualities.QualityFixture.GetDefaultQualities(),
};

@ -52,7 +52,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
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;

@ -23,7 +23,7 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
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 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
_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();

@ -23,7 +23,7 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
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 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
_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();

@ -24,7 +24,7 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
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 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
_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();

@ -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),

@ -57,7 +57,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
_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();

@ -26,7 +26,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
{
_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(),
})

@ -40,7 +40,7 @@ namespace NzbDrone.Core.Test.MediaFiles
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 @@ namespace NzbDrone.Core.Test.MediaFiles
_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 @@ namespace NzbDrone.Core.Test.MediaFiles
[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 @@ namespace NzbDrone.Core.Test.MediaFiles
[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 @@ namespace NzbDrone.Core.Test.MediaFiles
[Test]
public void should_not_move_existing_files()
{
GivenExistingFileOnDisk();
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, false);
Mocker.GetMock<IUpgradeMediaFiles>()
@ -217,6 +232,8 @@ namespace NzbDrone.Core.Test.MediaFiles
[Test]
public void should_import_larger_files_first()
{
GivenExistingFileOnDisk();
var fileDecision = _approvedDecisions.First();
fileDecision.LocalEpisode.Size = 1.Gigabytes();

@ -7,12 +7,12 @@ using NzbDrone.Core.Test.Framework;
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,

@ -10,7 +10,7 @@ using NzbDrone.Core.Tv;
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 @@ namespace NzbDrone.Core.Test.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 @@ namespace NzbDrone.Core.Test.Profiles
{
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 @@ namespace NzbDrone.Core.Test.Profiles
{
var seriesList = Builder<Series>.CreateListOfSize(3)
.All()
.With(c => c.ProfileId = 2)
.With(c => c.QualityProfileId = 2)
.Build().ToList();

@ -61,7 +61,7 @@ namespace NzbDrone.Core.Test.Qualities
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 @@ namespace NzbDrone.Core.Test.Qualities
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;
}

@ -14,48 +14,48 @@ namespace NzbDrone.Core.Test.Qualities
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

@ -28,15 +28,15 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
[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 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
.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 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
.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();

@ -18,7 +18,7 @@ namespace NzbDrone.Core.Test.TvTests.SeriesRepositoryTests
[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 @@ namespace NzbDrone.Core.Test.TvTests.SeriesRepositoryTests
};
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();

@ -23,7 +23,7 @@ namespace NzbDrone.Core.Test.TvTests.SeriesServiceTests
{
_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())

@ -42,7 +42,7 @@ namespace NzbDrone.Core.Datastore.Migration
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);

@ -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");
}
}
}

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
@ -148,7 +148,8 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
{
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;

@ -84,7 +84,7 @@ namespace NzbDrone.Core.Datastore
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 @@ namespace NzbDrone.Core.Datastore
.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 @@ namespace NzbDrone.Core.Datastore
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());

@ -59,7 +59,7 @@ namespace NzbDrone.Core.DecisionEngine
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));
}

@ -24,7 +24,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
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))
{

@ -21,7 +21,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
{
_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];

@ -31,7 +31,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
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 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
_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 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
_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,

@ -42,7 +42,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
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 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
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();
}

@ -58,7 +58,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
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 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
subject.PreferredWordScore);
var upgradeable = _upgradableSpecification.IsUpgradable(
subject.Series.Profile,
subject.Series.QualityProfile,
subject.Series.LanguageProfile,
mostRecent.Quality,
mostRecent.Language,

@ -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 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
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 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
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 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
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 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
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.

@ -34,8 +34,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
_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 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
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);
}
}

@ -216,7 +216,7 @@ namespace NzbDrone.Core.Download.Pending
{
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 @@ namespace NzbDrone.Core.Download.Pending
return;
}
var profile = remoteEpisode.Series.Profile.Value;
var profile = remoteEpisode.Series.QualityProfile.Value;
foreach (var existingReport in existingReports)
{

@ -50,7 +50,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
{
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)

@ -19,7 +19,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
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))

@ -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" />

@ -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 @@ namespace NzbDrone.Core.Profiles.Languages
{
public string Name { get; set; }
public List<LanguageProfileItem> Languages { get; set; }
public bool UpgradeAllowed { get; set; }
public Language Cutoff { get; set; }
public Language LastAllowedLanguage()

@ -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)
{
}
}
}

@ -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;
}
}
}

@ -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()
{

@ -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)
{
}
}
}

@ -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 @@ using NzbDrone.Core.Qualities;
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()

@ -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;
}
}
}

@ -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 @@ namespace NzbDrone.Core.Profiles.Qualities
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 @@ namespace NzbDrone.Core.Profiles.Qualities
{
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 @@ namespace NzbDrone.Core.Profiles.Qualities
groupId++;
}
var qualityProfile = new Profile
var qualityProfile = new QualityProfile
{
Name = name,
Cutoff = profileCutoff,
@ -172,7 +172,7 @@ namespace NzbDrone.Core.Profiles.Qualities
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);

@ -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();

@ -262,7 +262,7 @@ namespace NzbDrone.Core.Tv
{
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));
}
}

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using Marr.Data;
using NzbDrone.Common.Extensions;
@ -30,7 +30,7 @@ namespace NzbDrone.Core.Tv
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 @@ namespace NzbDrone.Core.Tv
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 @@ namespace NzbDrone.Core.Tv
Seasons = otherSeries.Seasons;
Path = otherSeries.Path;
ProfileId = otherSeries.ProfileId;
QualityProfileId = otherSeries.QualityProfileId;
LanguageProfileId = otherSeries.LanguageProfileId;
SeasonFolder = otherSeries.SeasonFolder;
@ -79,4 +79,4 @@ namespace NzbDrone.Core.Tv
AddOptions = otherSeries.AddOptions;
}
}
}
}

@ -8,7 +8,7 @@ namespace NzbDrone.Core.Validation
private readonly IProfileService _profileService;
public ProfileExistsValidator(IProfileService profileService)
: base("Profile does not exist")
: base("QualityProfile does not exist")
{
_profileService = profileService;
}

@ -69,7 +69,7 @@ namespace Sonarr.Api.V3.EpisodeFiles
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)
};
}

@ -51,7 +51,7 @@ namespace Sonarr.Api.V3.History
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);
}

@ -30,7 +30,7 @@ namespace Sonarr.Api.V3.Indexers
{
release.QualityWeight = decision.RemoteEpisode
.Series
.Profile.Value
.QualityProfile.Value
.Items.FindIndex(v => v.Quality == release.Quality.Quality) * 100;
release.LanguageWeight = decision.RemoteEpisode

@ -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 @@ namespace Sonarr.Api.V3.Profiles.Language
{
Id = model.Id,
Name = model.Name,
UpgradeAllowed = model.UpgradeAllowed,
Cutoff = model.Cutoff,
Languages = model.Languages.ConvertAll(ToResource)
};
@ -52,6 +54,7 @@ namespace Sonarr.Api.V3.Profiles.Language
{
Id = resource.Id,
Name = resource.Name,
UpgradeAllowed = resource.UpgradeAllowed,
Cutoff = (NzbDrone.Core.Languages.Language)resource.Cutoff.Id,
Languages = resource.Languages.ConvertAll(ToModel)
};

@ -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 @@ namespace Sonarr.Api.V3.Profiles.Quality
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 @@ namespace Sonarr.Api.V3.Profiles.Quality
{
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 @@ namespace Sonarr.Api.V3.Profiles.Quality
};
}
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 @@ namespace Sonarr.Api.V3.Profiles.Quality
};
}
public static List<QualityProfileResource> ToResource(this IEnumerable<Profile> models)
public static List<QualityProfileResource> ToResource(this IEnumerable<QualityProfile> models)
{
return models.Select(ToResource).ToList();
}
}
}
}

@ -38,7 +38,7 @@ namespace Sonarr.Api.V3.Series
if (resource.QualityProfileId.HasValue)
{
series.ProfileId = resource.QualityProfileId.Value;
series.QualityProfileId = resource.QualityProfileId.Value;
}
if (resource.LanguageProfileId.HasValue)

@ -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 @@ namespace Sonarr.Api.V3.Series
{
//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 @@ namespace Sonarr.Api.V3.Series
Year = model.Year,
Path = model.Path,
QualityProfileId = model.ProfileId,
QualityProfileId = model.QualityProfileId,
LanguageProfileId = model.LanguageProfileId,
SeasonFolder = model.SeasonFolder,
@ -155,7 +154,7 @@ namespace Sonarr.Api.V3.Series
Year = resource.Year,
Path = resource.Path,
ProfileId = resource.QualityProfileId,
QualityProfileId = resource.QualityProfileId,
LanguageProfileId = resource.LanguageProfileId,
SeasonFolder = resource.SeasonFolder,

Loading…
Cancel
Save