From f345977e3f56eb6170d40296ad67d4dae6e6e9f4 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 28 Nov 2018 20:26:49 -0800 Subject: [PATCH] Add upgrade allowed to language and profiles --- .../EpisodeFiles/EpisodeFileResource.cs | 2 +- src/NzbDrone.Api/History/HistoryModule.cs | 2 +- .../Indexers/ReleaseModuleBase.cs | 2 +- src/NzbDrone.Api/Profiles/ProfileResource.cs | 17 ++-- .../Profiles/ProfileSchemaModule.cs | 4 +- src/NzbDrone.Api/Series/SeriesResource.cs | 6 +- .../Datastore/MarrDataLazyLoadingFixture.cs | 14 +-- .../CutoffSpecificationFixture.cs | 22 ++--- .../PrioritizeDownloadDecisionFixture.cs | 2 +- ...ityAllowedByProfileSpecificationFixture.cs | 6 +- .../QueueSpecificationFixture.cs | 99 +++++++++++++++++-- .../RssSync/DelaySpecificationFixture.cs | 16 +-- .../DeletedEpisodeFileSpecificationFixture.cs | 2 +- .../RssSync/HistorySpecificationFixture.cs | 25 +++-- .../RssSync/ProperSpecificationFixture.cs | 2 +- .../UpgradeDiskSpecificationFixture.cs | 20 +++- .../UpgradeSpecificationFixture.cs | 10 +- .../DownloadApprovedFixture.cs | 2 +- .../PendingReleaseServiceTests/AddFixture.cs | 14 +-- .../RemoveGrabbedFixture.cs | 14 +-- .../RemoveRejectedFixture.cs | 14 +-- .../HistoryTests/HistoryServiceFixture.cs | 8 +- .../ImportDecisionMakerFixture.cs | 2 +- .../UpgradeSpecificationFixture.cs | 2 +- .../ImportApprovedEpisodesFixture.cs | 19 +++- .../Profiles/ProfileRepositoryFixture.cs | 4 +- .../Profiles/ProfileServiceFixture.cs | 16 +-- .../Qualities/QualityFixture.cs | 4 +- .../Qualities/QualityModelComparerFixture.cs | 22 ++--- .../EpisodesWhereCutoffUnmetFixture.cs | 14 +-- .../SeriesRepositoryFixture.cs | 8 +- .../UpdateMultipleSeriesFixture.cs | 2 +- .../036_update_with_quality_converters.cs | 2 +- ...me_quality_profiles_add_upgrade_allowed.cs | 23 +++++ .../Migration/Framework/SqliteSyntaxReader.cs | 5 +- src/NzbDrone.Core/Datastore/TableMapping.cs | 6 +- .../DownloadDecisionComparer.cs | 2 +- .../Specifications/CutoffSpecification.cs | 2 +- .../QualityAllowedByProfileSpecification.cs | 2 +- .../Specifications/QueueSpecification.cs | 6 +- .../RssSync/DelaySpecification.cs | 4 +- .../RssSync/HistorySpecification.cs | 4 +- .../Specifications/UpgradableSpecification.cs | 27 ++--- .../UpgradeDiskSpecification.cs | 5 +- .../Download/Pending/PendingReleaseService.cs | 4 +- .../EpisodeImport/ImportApprovedEpisodes.cs | 2 +- .../Specifications/UpgradeSpecification.cs | 2 +- src/NzbDrone.Core/NzbDrone.Core.csproj | 11 ++- .../Profiles/Languages/LanguageProfile.cs | 3 +- .../Qualities/ProfileInUseException.cs | 13 --- .../Profiles/Qualities/ProfileRepository.cs | 23 ----- .../{Profile.cs => QualityProfile.cs} | 7 +- .../Qualities/QualityProfileInUseException.cs | 13 +++ ...tyItem.cs => QualityProfileQualityItem.cs} | 10 +- .../Qualities/QualityProfileRepository.cs | 23 +++++ ...ileService.cs => QualityProfileService.cs} | 40 ++++---- .../Qualities/QualityModelComparer.cs | 4 +- src/NzbDrone.Core/Tv/EpisodeRepository.cs | 2 +- src/NzbDrone.Core/Tv/Series.cs | 10 +- .../Validation/ProfileExistsValidator.cs | 2 +- .../EpisodeFiles/EpisodeFileResource.cs | 2 +- src/Sonarr.Api.V3/History/HistoryModule.cs | 2 +- .../Indexers/ReleaseModuleBase.cs | 2 +- .../Language/LanguageProfileResource.cs | 3 + .../Quality/QualityProfileResource.cs | 21 ++-- .../Series/SeriesEditorModule.cs | 2 +- src/Sonarr.Api.V3/Series/SeriesResource.cs | 7 +- 67 files changed, 426 insertions(+), 266 deletions(-) create mode 100644 src/NzbDrone.Core/Datastore/Migration/128_rename_quality_profiles_add_upgrade_allowed.cs delete mode 100644 src/NzbDrone.Core/Profiles/Qualities/ProfileInUseException.cs delete mode 100644 src/NzbDrone.Core/Profiles/Qualities/ProfileRepository.cs rename src/NzbDrone.Core/Profiles/Qualities/{Profile.cs => QualityProfile.cs} (89%) create mode 100644 src/NzbDrone.Core/Profiles/Qualities/QualityProfileInUseException.cs rename src/NzbDrone.Core/Profiles/Qualities/{ProfileQualityItem.cs => QualityProfileQualityItem.cs} (78%) create mode 100644 src/NzbDrone.Core/Profiles/Qualities/QualityProfileRepository.cs rename src/NzbDrone.Core/Profiles/Qualities/{ProfileService.cs => QualityProfileService.cs} (75%) diff --git a/src/NzbDrone.Api/EpisodeFiles/EpisodeFileResource.cs b/src/NzbDrone.Api/EpisodeFiles/EpisodeFileResource.cs index 38a9a611b..39a1c3893 100644 --- a/src/NzbDrone.Api/EpisodeFiles/EpisodeFileResource.cs +++ b/src/NzbDrone.Api/EpisodeFiles/EpisodeFileResource.cs @@ -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 }; diff --git a/src/NzbDrone.Api/History/HistoryModule.cs b/src/NzbDrone.Api/History/HistoryModule.cs index 4e41deee2..7eef7b483 100644 --- a/src/NzbDrone.Api/History/HistoryModule.cs +++ b/src/NzbDrone.Api/History/HistoryModule.cs @@ -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; diff --git a/src/NzbDrone.Api/Indexers/ReleaseModuleBase.cs b/src/NzbDrone.Api/Indexers/ReleaseModuleBase.cs index e5d0cca47..54297c066 100644 --- a/src/NzbDrone.Api/Indexers/ReleaseModuleBase.cs +++ b/src/NzbDrone.Api/Indexers/ReleaseModuleBase.cs @@ -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; } diff --git a/src/NzbDrone.Api/Profiles/ProfileResource.cs b/src/NzbDrone.Api/Profiles/ProfileResource.cs index 7c47a9a61..07a4b22fa 100644 --- a/src/NzbDrone.Api/Profiles/ProfileResource.cs +++ b/src/NzbDrone.Api/Profiles/ProfileResource.cs @@ -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 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 ToResource(this IEnumerable models) + public static List ToResource(this IEnumerable models) { return models.Select(ToResource).ToList(); } diff --git a/src/NzbDrone.Api/Profiles/ProfileSchemaModule.cs b/src/NzbDrone.Api/Profiles/ProfileSchemaModule.cs index 085d9fb97..a080a999d 100644 --- a/src/NzbDrone.Api/Profiles/ProfileSchemaModule.cs +++ b/src/NzbDrone.Api/Profiles/ProfileSchemaModule.cs @@ -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; diff --git a/src/NzbDrone.Api/Series/SeriesResource.cs b/src/NzbDrone.Api/Series/SeriesResource.cs index 755b201a3..2fd16ca2c 100644 --- a/src/NzbDrone.Api/Series/SeriesResource.cs +++ b/src/NzbDrone.Api/Series/SeriesResource.cs @@ -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, diff --git a/src/NzbDrone.Core.Test/Datastore/MarrDataLazyLoadingFixture.cs b/src/NzbDrone.Core.Test/Datastore/MarrDataLazyLoadingFixture.cs index 3c5cd7964..0459c9794 100644 --- a/src/NzbDrone.Core.Test/Datastore/MarrDataLazyLoadingFixture.cs +++ b/src/NzbDrone.Core.Test/Datastore/MarrDataLazyLoadingFixture.cs @@ -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.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() .Join(Marr.Data.QGen.JoinType.Inner, v => v.Series, (l, r) => l.SeriesId == r.Id) - .Join(Marr.Data.QGen.JoinType.Inner, v => v.Profile, (l, r) => l.ProfileId == r.Id) + .Join(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() .Join(Marr.Data.QGen.JoinType.Inner, v => v.Series, (l, r) => l.SeriesId == r.Id) - .Join(Marr.Data.QGen.JoinType.Inner, v => v.LanguageProfile, (l, r) => l.ProfileId == r.Id) + .Join(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); } } diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/CutoffSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/CutoffSpecificationFixture.cs index feffaf159..a6b1abacb 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/CutoffSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/CutoffSpecificationFixture.cs @@ -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(), diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/PrioritizeDownloadDecisionFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/PrioritizeDownloadDecisionFixture.cs index e9aa2f109..493b12af3 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/PrioritizeDownloadDecisionFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/PrioritizeDownloadDecisionFixture.cs @@ -53,7 +53,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests remoteEpisode.Release.DownloadProtocol = downloadProtocol; remoteEpisode.Series = Builder.CreateNew() - .With(e => e.Profile = new Profile + .With(e => e.QualityProfile = new QualityProfile { Items = Qualities.QualityFixture.GetDefaultQualities() }) diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/QualityAllowedByProfileSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/QualityAllowedByProfileSpecificationFixture.cs index 539222161..d45d58de5 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/QualityAllowedByProfileSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/QualityAllowedByProfileSpecificationFixture.cs @@ -35,7 +35,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests public void Setup() { var fakeSeries = Builder.CreateNew() - .With(c => c.Profile = (LazyLoaded)new Profile { Cutoff = Quality.Bluray1080p.Id }) + .With(c => c.QualityProfile = (LazyLoaded)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(); } diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/QueueSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/QueueSpecificationFixture.cs index 86cfd9d56..7dedad263 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/QueueSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/QueueSpecificationFixture.cs @@ -33,13 +33,15 @@ namespace NzbDrone.Core.Test.DecisionEngineTests Mocker.Resolve(); _series = Builder.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.CreateNew() + .With(r => r.Series = _series) + .With(r => r.Episodes = new List { _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 }); + + 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.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.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.CreateNew() + .With(r => r.Series = _series) + .With(r => r.Episodes = new List { _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 }); + 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.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.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.CreateNew() + .With(r => r.Series = _series) + .With(r => r.Episodes = new List { _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 }); + 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.CreateNew() + .With(r => r.Series = _series) + .With(r => r.Episodes = new List { _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 }); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); + } } } diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/DelaySpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/DelaySpecificationFixture.cs index 0a60e0ebf..56fee11e3 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/DelaySpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/DelaySpecificationFixture.cs @@ -26,7 +26,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync [TestFixture] public class DelaySpecificationFixture : CoreTest { - 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.CreateNew() + _profile = Builder.CreateNew() .Build(); _langProfile = Builder.CreateNew() @@ -45,7 +45,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync .Build(); var series = Builder.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(); - _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(); + _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() - .Setup(s => s.IsUpgradable(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(s => s.IsUpgradable(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns(true); } diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/DeletedEpisodeFileSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/DeletedEpisodeFileSpecificationFixture.cs index 842eb102b..22942ca92 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/DeletedEpisodeFileSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/DeletedEpisodeFileSpecificationFixture.cs @@ -55,7 +55,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync }; var fakeSeries = Builder.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(); diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/HistorySpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/HistorySpecificationFixture.cs index 59b65f6f0..00fd23463 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/HistorySpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/HistorySpecificationFixture.cs @@ -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.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(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(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(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(new QualityModel(Quality.WEBDL1080p, new Revision(version: 1)), Language.Spanish); diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/ProperSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/ProperSpecificationFixture.cs index 5479f73d1..cb8f3f663 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/ProperSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/ProperSpecificationFixture.cs @@ -38,7 +38,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync var doubleEpisodeList = new List { new Episode { EpisodeFile = _firstFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = _secondFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = null } }; var fakeSeries = Builder.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 diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs index ff2706d39..fd47ce3d8 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs @@ -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.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(); } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeSpecificationFixture.cs index 8a23f24bf..786df4a4f 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeSpecificationFixture.cs @@ -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(), }; diff --git a/src/NzbDrone.Core.Test/Download/DownloadApprovedReportsTests/DownloadApprovedFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadApprovedReportsTests/DownloadApprovedFixture.cs index 77a405d23..47f03c65c 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadApprovedReportsTests/DownloadApprovedFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadApprovedReportsTests/DownloadApprovedFixture.cs @@ -52,7 +52,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests remoteEpisode.Release.PublishDate = DateTime.UtcNow; remoteEpisode.Series = Builder.CreateNew() - .With(e => e.Profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities() }) + .With(e => e.QualityProfile = new QualityProfile { Items = Qualities.QualityFixture.GetDefaultQualities() }) .Build(); return remoteEpisode; diff --git a/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/AddFixture.cs b/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/AddFixture.cs index 8f280da4e..4070862dd 100644 --- a/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/AddFixture.cs +++ b/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/AddFixture.cs @@ -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.CreateNew() .Build(); - _profile = new Profile + _profile = new QualityProfile { Name = "Test", Cutoff = Quality.HDTV720p.Id, - Items = new List + Items = new List { - 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); + _series.QualityProfile = new LazyLoaded(_profile); _release = Builder.CreateNew().Build(); diff --git a/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/RemoveGrabbedFixture.cs b/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/RemoveGrabbedFixture.cs index c48361d19..474af4cbb 100644 --- a/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/RemoveGrabbedFixture.cs +++ b/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/RemoveGrabbedFixture.cs @@ -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.CreateNew() .Build(); - _profile = new Profile + _profile = new QualityProfile { Name = "Test", Cutoff = Quality.HDTV720p.Id, - Items = new List + Items = new List { - 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); + _series.QualityProfile = new LazyLoaded(_profile); _release = Builder.CreateNew().Build(); diff --git a/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/RemoveRejectedFixture.cs b/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/RemoveRejectedFixture.cs index 847ed6835..642568797 100644 --- a/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/RemoveRejectedFixture.cs +++ b/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/RemoveRejectedFixture.cs @@ -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.CreateNew() .Build(); - _profile = new Profile + _profile = new QualityProfile { Name = "Test", Cutoff = Quality.HDTV720p.Id, - Items = new List + Items = new List { - 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); + _series.QualityProfile = new LazyLoaded(_profile); _release = Builder.CreateNew().Build(); diff --git a/src/NzbDrone.Core.Test/HistoryTests/HistoryServiceFixture.cs b/src/NzbDrone.Core.Test/HistoryTests/HistoryServiceFixture.cs index c8abc87d6..0eebc8cd5 100644 --- a/src/NzbDrone.Core.Test/HistoryTests/HistoryServiceFixture.cs +++ b/src/NzbDrone.Core.Test/HistoryTests/HistoryServiceFixture.cs @@ -21,20 +21,20 @@ namespace NzbDrone.Core.Test.HistoryTests { public class HistoryServiceFixture : CoreTest { - 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), diff --git a/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/ImportDecisionMakerFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/ImportDecisionMakerFixture.cs index 511903467..fe24f2fba 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/ImportDecisionMakerFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/ImportDecisionMakerFixture.cs @@ -57,7 +57,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport _series = Builder.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(); diff --git a/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/Specifications/UpgradeSpecificationFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/Specifications/UpgradeSpecificationFixture.cs index 14f936eca..3119f5776 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/Specifications/UpgradeSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/Specifications/UpgradeSpecificationFixture.cs @@ -26,7 +26,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications { _series = Builder.CreateNew() .With(s => s.SeriesType = SeriesTypes.Standard) - .With(e => e.Profile = new Profile + .With(e => e.QualityProfile = new QualityProfile { Items = Qualities.QualityFixture.GetDefaultQualities(), }) diff --git a/src/NzbDrone.Core.Test/MediaFiles/ImportApprovedEpisodesFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/ImportApprovedEpisodesFixture.cs index 19e4392f1..a5f50c916 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/ImportApprovedEpisodesFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/ImportApprovedEpisodesFixture.cs @@ -40,7 +40,7 @@ namespace NzbDrone.Core.Test.MediaFiles var outputPath = @"C:\Test\Unsorted\TV\30.Rock.S01E01".AsOsAgnostic(); var series = Builder.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() + .Setup(s => s.GetFilesWithRelativePath(It.IsAny(), It.IsAny())) + .Returns(new List()); + } + [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(); 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(); 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 { _approvedDecisions.First() }, false); Mocker.GetMock() @@ -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(); diff --git a/src/NzbDrone.Core.Test/Profiles/ProfileRepositoryFixture.cs b/src/NzbDrone.Core.Test/Profiles/ProfileRepositoryFixture.cs index 02e53dcd4..275929863 100644 --- a/src/NzbDrone.Core.Test/Profiles/ProfileRepositoryFixture.cs +++ b/src/NzbDrone.Core.Test/Profiles/ProfileRepositoryFixture.cs @@ -7,12 +7,12 @@ using NzbDrone.Core.Test.Framework; namespace NzbDrone.Core.Test.Profiles { [TestFixture] - public class ProfileRepositoryFixture : DbTest + public class ProfileRepositoryFixture : DbTest { [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, diff --git a/src/NzbDrone.Core.Test/Profiles/ProfileServiceFixture.cs b/src/NzbDrone.Core.Test/Profiles/ProfileServiceFixture.cs index e0e68639b..8d0596180 100644 --- a/src/NzbDrone.Core.Test/Profiles/ProfileServiceFixture.cs +++ b/src/NzbDrone.Core.Test/Profiles/ProfileServiceFixture.cs @@ -10,7 +10,7 @@ using NzbDrone.Core.Tv; namespace NzbDrone.Core.Test.Profiles { [TestFixture] - public class ProfileServiceFixture : CoreTest + public class ProfileServiceFixture : CoreTest { [Test] public void init_should_add_default_profiles() @@ -18,7 +18,7 @@ namespace NzbDrone.Core.Test.Profiles Subject.Handle(new ApplicationStartedEvent()); Mocker.GetMock() - .Verify(v => v.Insert(It.IsAny()), Times.Exactly(6)); + .Verify(v => v.Insert(It.IsAny()), Times.Exactly(6)); } [Test] @@ -28,32 +28,32 @@ namespace NzbDrone.Core.Test.Profiles { Mocker.GetMock() .Setup(s => s.All()) - .Returns(Builder.CreateListOfSize(2).Build().ToList()); + .Returns(Builder.CreateListOfSize(2).Build().ToList()); Subject.Handle(new ApplicationStartedEvent()); Mocker.GetMock() - .Verify(v => v.Insert(It.IsAny()), Times.Never()); + .Verify(v => v.Insert(It.IsAny()), Times.Never()); } [Test] public void should_not_be_able_to_delete_profile_if_assigned_to_series() { - var profile = Builder.CreateNew() + var profile = Builder.CreateNew() .With(p => p.Id = 2) .Build(); var seriesList = Builder.CreateListOfSize(3) .Random(1) - .With(c => c.ProfileId = profile.Id) + .With(c => c.QualityProfileId = profile.Id) .Build().ToList(); Mocker.GetMock().Setup(c => c.GetAllSeries()).Returns(seriesList); Mocker.GetMock().Setup(c => c.Get(profile.Id)).Returns(profile); - Assert.Throws(() => Subject.Delete(profile.Id)); + Assert.Throws(() => Subject.Delete(profile.Id)); Mocker.GetMock().Verify(c => c.Delete(It.IsAny()), Times.Never()); @@ -65,7 +65,7 @@ namespace NzbDrone.Core.Test.Profiles { var seriesList = Builder.CreateListOfSize(3) .All() - .With(c => c.ProfileId = 2) + .With(c => c.QualityProfileId = 2) .Build().ToList(); diff --git a/src/NzbDrone.Core.Test/Qualities/QualityFixture.cs b/src/NzbDrone.Core.Test/Qualities/QualityFixture.cs index bbbfd3fbe..b8c48d88e 100644 --- a/src/NzbDrone.Core.Test/Qualities/QualityFixture.cs +++ b/src/NzbDrone.Core.Test/Qualities/QualityFixture.cs @@ -61,7 +61,7 @@ namespace NzbDrone.Core.Test.Qualities i.Should().Be(expected); } - public static List GetDefaultQualities(params Quality[] allowed) + public static List GetDefaultQualities(params Quality[] allowed) { var qualities = new List { @@ -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; } diff --git a/src/NzbDrone.Core.Test/Qualities/QualityModelComparerFixture.cs b/src/NzbDrone.Core.Test/Qualities/QualityModelComparerFixture.cs index 2182589c6..056da6fa6 100644 --- a/src/NzbDrone.Core.Test/Qualities/QualityModelComparerFixture.cs +++ b/src/NzbDrone.Core.Test/Qualities/QualityModelComparerFixture.cs @@ -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 + Items = new List { - 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 + Items = new List { - 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 diff --git a/src/NzbDrone.Core.Test/TvTests/EpisodeRepositoryTests/EpisodesWhereCutoffUnmetFixture.cs b/src/NzbDrone.Core.Test/TvTests/EpisodeRepositoryTests/EpisodesWhereCutoffUnmetFixture.cs index e43288255..41c2bdc2a 100644 --- a/src/NzbDrone.Core.Test/TvTests/EpisodeRepositoryTests/EpisodesWhereCutoffUnmetFixture.cs +++ b/src/NzbDrone.Core.Test/TvTests/EpisodeRepositoryTests/EpisodesWhereCutoffUnmetFixture.cs @@ -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 + Items = new List { - 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(); diff --git a/src/NzbDrone.Core.Test/TvTests/SeriesRepositoryTests/SeriesRepositoryFixture.cs b/src/NzbDrone.Core.Test/TvTests/SeriesRepositoryTests/SeriesRepositoryFixture.cs index 4d2b1bb2e..90f478292 100644 --- a/src/NzbDrone.Core.Test/TvTests/SeriesRepositoryTests/SeriesRepositoryFixture.cs +++ b/src/NzbDrone.Core.Test/TvTests/SeriesRepositoryTests/SeriesRepositoryFixture.cs @@ -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().Insert(profile); + Mocker.Resolve().Insert(profile); Mocker.Resolve().Insert(langProfile); var series = Builder.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(); diff --git a/src/NzbDrone.Core.Test/TvTests/SeriesServiceTests/UpdateMultipleSeriesFixture.cs b/src/NzbDrone.Core.Test/TvTests/SeriesServiceTests/UpdateMultipleSeriesFixture.cs index d8ad08ec6..a5f10f68f 100644 --- a/src/NzbDrone.Core.Test/TvTests/SeriesServiceTests/UpdateMultipleSeriesFixture.cs +++ b/src/NzbDrone.Core.Test/TvTests/SeriesServiceTests/UpdateMultipleSeriesFixture.cs @@ -23,7 +23,7 @@ namespace NzbDrone.Core.Test.TvTests.SeriesServiceTests { _series = Builder.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()) diff --git a/src/NzbDrone.Core/Datastore/Migration/036_update_with_quality_converters.cs b/src/NzbDrone.Core/Datastore/Migration/036_update_with_quality_converters.cs index 32fbdd842..0f2342530 100644 --- a/src/NzbDrone.Core/Datastore/Migration/036_update_with_quality_converters.cs +++ b/src/NzbDrone.Core/Datastore/Migration/036_update_with_quality_converters.cs @@ -42,7 +42,7 @@ namespace NzbDrone.Core.Datastore.Migration var allowed = Json.Deserialize>(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); diff --git a/src/NzbDrone.Core/Datastore/Migration/128_rename_quality_profiles_add_upgrade_allowed.cs b/src/NzbDrone.Core/Datastore/Migration/128_rename_quality_profiles_add_upgrade_allowed.cs new file mode 100644 index 000000000..91739863b --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/128_rename_quality_profiles_add_upgrade_allowed.cs @@ -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"); + } + } +} diff --git a/src/NzbDrone.Core/Datastore/Migration/Framework/SqliteSyntaxReader.cs b/src/NzbDrone.Core/Datastore/Migration/Framework/SqliteSyntaxReader.cs index e60ef4c70..703aff012 100644 --- a/src/NzbDrone.Core/Datastore/Migration/Framework/SqliteSyntaxReader.cs +++ b/src/NzbDrone.Core/Datastore/Migration/Framework/SqliteSyntaxReader.cs @@ -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; diff --git a/src/NzbDrone.Core/Datastore/TableMapping.cs b/src/NzbDrone.Core/Datastore/TableMapping.cs index 7b3abb56b..d71582831 100644 --- a/src/NzbDrone.Core/Datastore/TableMapping.cs +++ b/src/NzbDrone.Core/Datastore/TableMapping.cs @@ -84,7 +84,7 @@ namespace NzbDrone.Core.Datastore Mapper.Entity().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().RegisterModel("EpisodeFiles") @@ -106,7 +106,7 @@ namespace NzbDrone.Core.Datastore .Ignore(d => d.GroupName) .Ignore(d => d.Weight); - Mapper.Entity().RegisterModel("Profiles"); + Mapper.Entity().RegisterModel("QualityProfiles"); Mapper.Entity().RegisterModel("LanguageProfiles"); Mapper.Entity().RegisterModel("Logs"); Mapper.Entity().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), new EmbeddedDocumentConverter(new QualityIntConverter())); + MapRepository.Instance.RegisterTypeConverter(typeof(List), new EmbeddedDocumentConverter(new QualityIntConverter())); MapRepository.Instance.RegisterTypeConverter(typeof(QualityModel), new EmbeddedDocumentConverter(new QualityIntConverter())); MapRepository.Instance.RegisterTypeConverter(typeof(Dictionary), new EmbeddedDocumentConverter()); MapRepository.Instance.RegisterTypeConverter(typeof(List), new EmbeddedDocumentConverter()); diff --git a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs index 257a44038..5f57800c0 100644 --- a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs +++ b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs @@ -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)); } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/CutoffSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/CutoffSpecification.cs index dd8af73ff..0a5d7839f 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/CutoffSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/CutoffSpecification.cs @@ -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)) { diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/QualityAllowedByProfileSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/QualityAllowedByProfileSpecification.cs index b6a291e9d..a4739cfd1 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/QualityAllowedByProfileSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/QualityAllowedByProfileSpecification.cs @@ -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]; diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/QueueSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/QueueSpecification.cs index 374056111..dec8429c5 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/QueueSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/QueueSpecification.cs @@ -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, diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DelaySpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DelaySpecification.cs index 5f487d217..846b65510 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DelaySpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DelaySpecification.cs @@ -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(); } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs index f77169941..9b3129d36 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs @@ -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, diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs index cbb5486db..32905f114 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs @@ -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. diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeDiskSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeDiskSpecification.cs index a3d4e794c..caf4fbfdb 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeDiskSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeDiskSpecification.cs @@ -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); } } diff --git a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs index 9b3be9c00..a8474757e 100644 --- a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs +++ b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs @@ -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) { diff --git a/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs b/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs index 7b93486d0..b2b62d0e5 100644 --- a/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs +++ b/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs @@ -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) diff --git a/src/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/UpgradeSpecification.cs b/src/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/UpgradeSpecification.cs index 77d05e4e7..03bdca940 100644 --- a/src/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/UpgradeSpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/UpgradeSpecification.cs @@ -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)) diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 3010ae681..7cf0203eb 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -137,6 +137,7 @@ + @@ -1000,11 +1001,11 @@ - - - - - + + + + + diff --git a/src/NzbDrone.Core/Profiles/Languages/LanguageProfile.cs b/src/NzbDrone.Core/Profiles/Languages/LanguageProfile.cs index 102785577..b81ff7e1a 100644 --- a/src/NzbDrone.Core/Profiles/Languages/LanguageProfile.cs +++ b/src/NzbDrone.Core/Profiles/Languages/LanguageProfile.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 Languages { get; set; } + public bool UpgradeAllowed { get; set; } public Language Cutoff { get; set; } public Language LastAllowedLanguage() diff --git a/src/NzbDrone.Core/Profiles/Qualities/ProfileInUseException.cs b/src/NzbDrone.Core/Profiles/Qualities/ProfileInUseException.cs deleted file mode 100644 index 44e583a42..000000000 --- a/src/NzbDrone.Core/Profiles/Qualities/ProfileInUseException.cs +++ /dev/null @@ -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) - { - } - } -} diff --git a/src/NzbDrone.Core/Profiles/Qualities/ProfileRepository.cs b/src/NzbDrone.Core/Profiles/Qualities/ProfileRepository.cs deleted file mode 100644 index 638101b37..000000000 --- a/src/NzbDrone.Core/Profiles/Qualities/ProfileRepository.cs +++ /dev/null @@ -1,23 +0,0 @@ -using NzbDrone.Core.Datastore; -using NzbDrone.Core.Messaging.Events; - -namespace NzbDrone.Core.Profiles.Qualities -{ - public interface IProfileRepository : IBasicRepository - { - bool Exists(int id); - } - - public class ProfileRepository : BasicRepository, IProfileRepository - { - public ProfileRepository(IMainDatabase database, IEventAggregator eventAggregator) - : base(database, eventAggregator) - { - } - - public bool Exists(int id) - { - return DataMapper.Query().Where(p => p.Id == id).GetRowCount() == 1; - } - } -} diff --git a/src/NzbDrone.Core/Profiles/Qualities/Profile.cs b/src/NzbDrone.Core/Profiles/Qualities/QualityProfile.cs similarity index 89% rename from src/NzbDrone.Core/Profiles/Qualities/Profile.cs rename to src/NzbDrone.Core/Profiles/Qualities/QualityProfile.cs index 9749f17be..90e37ec13 100644 --- a/src/NzbDrone.Core/Profiles/Qualities/Profile.cs +++ b/src/NzbDrone.Core/Profiles/Qualities/QualityProfile.cs @@ -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 Items { get; set; } + public List Items { get; set; } public Quality LastAllowedQuality() { diff --git a/src/NzbDrone.Core/Profiles/Qualities/QualityProfileInUseException.cs b/src/NzbDrone.Core/Profiles/Qualities/QualityProfileInUseException.cs new file mode 100644 index 000000000..df198b49f --- /dev/null +++ b/src/NzbDrone.Core/Profiles/Qualities/QualityProfileInUseException.cs @@ -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) + { + } + } +} diff --git a/src/NzbDrone.Core/Profiles/Qualities/ProfileQualityItem.cs b/src/NzbDrone.Core/Profiles/Qualities/QualityProfileQualityItem.cs similarity index 78% rename from src/NzbDrone.Core/Profiles/Qualities/ProfileQualityItem.cs rename to src/NzbDrone.Core/Profiles/Qualities/QualityProfileQualityItem.cs index 5a5b256ea..9b94c69da 100644 --- a/src/NzbDrone.Core/Profiles/Qualities/ProfileQualityItem.cs +++ b/src/NzbDrone.Core/Profiles/Qualities/QualityProfileQualityItem.cs @@ -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 Items { get; set; } + public List Items { get; set; } public bool Allowed { get; set; } - public ProfileQualityItem() + public QualityProfileQualityItem() { - Items = new List(); + Items = new List(); } public List GetQualities() diff --git a/src/NzbDrone.Core/Profiles/Qualities/QualityProfileRepository.cs b/src/NzbDrone.Core/Profiles/Qualities/QualityProfileRepository.cs new file mode 100644 index 000000000..9f8bf9a0a --- /dev/null +++ b/src/NzbDrone.Core/Profiles/Qualities/QualityProfileRepository.cs @@ -0,0 +1,23 @@ +using NzbDrone.Core.Datastore; +using NzbDrone.Core.Messaging.Events; + +namespace NzbDrone.Core.Profiles.Qualities +{ + public interface IProfileRepository : IBasicRepository + { + bool Exists(int id); + } + + public class QualityProfileRepository : BasicRepository, IProfileRepository + { + public QualityProfileRepository(IMainDatabase database, IEventAggregator eventAggregator) + : base(database, eventAggregator) + { + } + + public bool Exists(int id) + { + return DataMapper.Query().Where(p => p.Id == id).GetRowCount() == 1; + } + } +} diff --git a/src/NzbDrone.Core/Profiles/Qualities/ProfileService.cs b/src/NzbDrone.Core/Profiles/Qualities/QualityProfileService.cs similarity index 75% rename from src/NzbDrone.Core/Profiles/Qualities/ProfileService.cs rename to src/NzbDrone.Core/Profiles/Qualities/QualityProfileService.cs index f7a12fa56..02cae433d 100644 --- a/src/NzbDrone.Core/Profiles/Qualities/ProfileService.cs +++ b/src/NzbDrone.Core/Profiles/Qualities/QualityProfileService.cs @@ -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 All(); - Profile Get(int id); + List 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 + public class QualityProfileService : IProfileService, IHandle { 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 All() + public List 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(); + var items = new List(); 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); diff --git a/src/NzbDrone.Core/Qualities/QualityModelComparer.cs b/src/NzbDrone.Core/Qualities/QualityModelComparer.cs index 303cfd008..45e3d7ff2 100644 --- a/src/NzbDrone.Core/Qualities/QualityModelComparer.cs +++ b/src/NzbDrone.Core/Qualities/QualityModelComparer.cs @@ -6,9 +6,9 @@ namespace NzbDrone.Core.Qualities { public class QualityModelComparer : IComparer, IComparer { - 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(); diff --git a/src/NzbDrone.Core/Tv/EpisodeRepository.cs b/src/NzbDrone.Core/Tv/EpisodeRepository.cs index ebda26c0a..0fdda27d1 100644 --- a/src/NzbDrone.Core/Tv/EpisodeRepository.cs +++ b/src/NzbDrone.Core/Tv/EpisodeRepository.cs @@ -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)); } } diff --git a/src/NzbDrone.Core/Tv/Series.cs b/src/NzbDrone.Core/Tv/Series.cs index c7c4b5d23..9de6a86ee 100644 --- a/src/NzbDrone.Core/Tv/Series.cs +++ b/src/NzbDrone.Core/Tv/Series.cs @@ -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 { get; set; } + public LazyLoaded QualityProfile { get; set; } public LazyLoaded LanguageProfile { get; set; } public List 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; } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core/Validation/ProfileExistsValidator.cs b/src/NzbDrone.Core/Validation/ProfileExistsValidator.cs index 0eb5293dd..d75c7cde8 100644 --- a/src/NzbDrone.Core/Validation/ProfileExistsValidator.cs +++ b/src/NzbDrone.Core/Validation/ProfileExistsValidator.cs @@ -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; } diff --git a/src/Sonarr.Api.V3/EpisodeFiles/EpisodeFileResource.cs b/src/Sonarr.Api.V3/EpisodeFiles/EpisodeFileResource.cs index 07a06f7eb..cfbc65b83 100644 --- a/src/Sonarr.Api.V3/EpisodeFiles/EpisodeFileResource.cs +++ b/src/Sonarr.Api.V3/EpisodeFiles/EpisodeFileResource.cs @@ -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) }; } diff --git a/src/Sonarr.Api.V3/History/HistoryModule.cs b/src/Sonarr.Api.V3/History/HistoryModule.cs index 9c46a28cc..4e24a39df 100644 --- a/src/Sonarr.Api.V3/History/HistoryModule.cs +++ b/src/Sonarr.Api.V3/History/HistoryModule.cs @@ -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); } diff --git a/src/Sonarr.Api.V3/Indexers/ReleaseModuleBase.cs b/src/Sonarr.Api.V3/Indexers/ReleaseModuleBase.cs index 5c4f117d8..0a487eb1e 100644 --- a/src/Sonarr.Api.V3/Indexers/ReleaseModuleBase.cs +++ b/src/Sonarr.Api.V3/Indexers/ReleaseModuleBase.cs @@ -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 diff --git a/src/Sonarr.Api.V3/Profiles/Language/LanguageProfileResource.cs b/src/Sonarr.Api.V3/Profiles/Language/LanguageProfileResource.cs index 4a7716202..cc4293172 100644 --- a/src/Sonarr.Api.V3/Profiles/Language/LanguageProfileResource.cs +++ b/src/Sonarr.Api.V3/Profiles/Language/LanguageProfileResource.cs @@ -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 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) }; diff --git a/src/Sonarr.Api.V3/Profiles/Quality/QualityProfileResource.cs b/src/Sonarr.Api.V3/Profiles/Quality/QualityProfileResource.cs index 674d84d1a..581bc23c2 100644 --- a/src/Sonarr.Api.V3/Profiles/Quality/QualityProfileResource.cs +++ b/src/Sonarr.Api.V3/Profiles/Quality/QualityProfileResource.cs @@ -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 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 ToResource(this IEnumerable models) + public static List ToResource(this IEnumerable models) { return models.Select(ToResource).ToList(); } } -} \ No newline at end of file +} diff --git a/src/Sonarr.Api.V3/Series/SeriesEditorModule.cs b/src/Sonarr.Api.V3/Series/SeriesEditorModule.cs index dec3f9267..2f47fbed5 100644 --- a/src/Sonarr.Api.V3/Series/SeriesEditorModule.cs +++ b/src/Sonarr.Api.V3/Series/SeriesEditorModule.cs @@ -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) diff --git a/src/Sonarr.Api.V3/Series/SeriesResource.cs b/src/Sonarr.Api.V3/Series/SeriesResource.cs index 725bf0fe4..40a8ff6b3 100644 --- a/src/Sonarr.Api.V3/Series/SeriesResource.cs +++ b/src/Sonarr.Api.V3/Series/SeriesResource.cs @@ -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,