diff --git a/NzbDrone.Core.Test/ProviderTests/SeriesProviderTest.cs b/NzbDrone.Core.Test/ProviderTests/SeriesProviderTest.cs index 379421e06..6fcea99d9 100644 --- a/NzbDrone.Core.Test/ProviderTests/SeriesProviderTest.cs +++ b/NzbDrone.Core.Test/ProviderTests/SeriesProviderTest.cs @@ -706,5 +706,80 @@ public void SearchForSeries_should_return_results_when_query_has_special_charact //Assert series.Should().HaveCount(1); } + + [Test] + public void UpdateFromMassEdit_should_only_update_certain_values() + { + WithRealDb(); + var newQualityProfileId = 10; + var newMonitored = false; + var newSeasonFolder = false; + + var fakeQuality = Builder.CreateNew().Build(); + var fakeSeries = Builder.CreateListOfSize(1) + .All() + .With(e => e.QualityProfileId = fakeQuality.QualityProfileId) + .With(e => e.Monitored = true) + .With(e => e.SeasonFolder = true) + .With(s => s.Title = "It's Always Sunny") + .Build(); + + Db.InsertMany(fakeSeries); + Db.Insert(fakeQuality); + + fakeSeries[0].QualityProfileId = newQualityProfileId; + fakeSeries[0].Monitored = newMonitored; + fakeSeries[0].SeasonFolder = newSeasonFolder; + + //Act + Mocker.Resolve().UpdateFromMassEdit(fakeSeries); + + //Assert + var result = Db.Fetch(); + result.Count.Should().Be(1); + result.First().QualityProfileId.Should().Be(newQualityProfileId); + result.First().Monitored.Should().Be(newMonitored); + result.First().SeasonFolder.Should().Be(newSeasonFolder); + } + + [Test] + public void UpdateFromMassEdit_should_only_update_changed_values() + { + WithRealDb(); + var newQualityProfileId = 10; + var newMonitored = false; + var newSeasonFolder = false; + var monitored = true; + var seasonFolder = true; + + var fakeQuality = Builder.CreateNew().Build(); + var fakeSeries = Builder.CreateListOfSize(2) + .All() + .With(e => e.QualityProfileId = fakeQuality.QualityProfileId) + .With(e => e.Monitored = monitored) + .With(e => e.SeasonFolder = seasonFolder) + .With(s => s.Title = "It's Always Sunny") + .Build(); + + Db.InsertMany(fakeSeries); + Db.Insert(fakeQuality); + + fakeSeries[0].QualityProfileId = newQualityProfileId; + fakeSeries[0].Monitored = newMonitored; + fakeSeries[0].SeasonFolder = newSeasonFolder; + + //Act + Mocker.Resolve().UpdateFromMassEdit(fakeSeries); + + //Assert + var result = Db.Fetch(); + result.Count.Should().Be(2); + result.First().QualityProfileId.Should().Be(newQualityProfileId); + result.First().Monitored.Should().Be(newMonitored); + result.First().SeasonFolder.Should().Be(newSeasonFolder); + result.Last().QualityProfileId.Should().Be(fakeQuality.QualityProfileId); + result.Last().Monitored.Should().Be(monitored); + result.Last().SeasonFolder.Should().Be(seasonFolder); + } } } \ No newline at end of file diff --git a/NzbDrone.Core/Providers/SeriesProvider.cs b/NzbDrone.Core/Providers/SeriesProvider.cs index 69a029755..fc1a0a619 100644 --- a/NzbDrone.Core/Providers/SeriesProvider.cs +++ b/NzbDrone.Core/Providers/SeriesProvider.cs @@ -198,6 +198,23 @@ public virtual List SearchForSeries(string title) return series; } + public virtual void UpdateFromMassEdit(IList editedSeries) + { + var allSeries = GetAllSeries(); + + foreach(var series in allSeries) + { + //Only update parameters that can be changed in MassEdit + var edited = editedSeries.Single(s => s.SeriesId == series.SeriesId); + series.QualityProfileId = edited.QualityProfileId; + series.Monitored = edited.Monitored; + series.SeasonFolder = edited.SeasonFolder; + series.Path = edited.Path; + } + + _database.UpdateMany(allSeries); + } + /// /// Cleans up the AirsTime Component from TheTVDB since it can be garbage that comes in. /// diff --git a/NzbDrone.Web/Controllers/SeriesController.cs b/NzbDrone.Web/Controllers/SeriesController.cs index 42f53b241..cac6ae160 100644 --- a/NzbDrone.Web/Controllers/SeriesController.cs +++ b/NzbDrone.Web/Controllers/SeriesController.cs @@ -9,6 +9,7 @@ using NzbDrone.Core.Jobs; using NzbDrone.Core.Providers; using NzbDrone.Core.Repository; +using NzbDrone.Core.Repository.Quality; using NzbDrone.Web.Models; using Telerik.Web.Mvc; @@ -148,6 +149,40 @@ public ActionResult Details(int seriesId) return View(model); } + public ActionResult MassEdit() + { + var profiles = _qualityProvider.All(); + ViewData["QualityProfiles"] = profiles; + + //Create the select lists + var masterProfiles = profiles.ToList(); + masterProfiles.Insert(0, new QualityProfile {QualityProfileId = -10, Name = "Unchanged"}); + ViewData["MasterProfileSelectList"] = new SelectList(masterProfiles, "QualityProfileId", "Name"); + + ViewData["BoolSelectList"] = new SelectList(new List> + { + new KeyValuePair(-10, "Unchanged"), + new KeyValuePair(1, "True"), + new KeyValuePair(0, "False") + }, "Key", "Value" + ); + + var series = _seriesProvider.GetAllSeries().OrderBy(o => SortHelper.SkipArticles(o.Title)); + + return View(series); + } + + [HttpPost] + public JsonResult SaveMassEdit(List series) + { + //Save edits + if (series == null || series.Count == 0) + return JsonNotificationResult.Opps("Invalid post data"); + + _seriesProvider.UpdateFromMassEdit(series); + return JsonNotificationResult.Info("Series Mass Edit Saved"); + } + private List GetSeriesModels(IList seriesInDb) { var series = seriesInDb.Select(s => new SeriesModel diff --git a/NzbDrone.Web/NzbDrone.Web.csproj b/NzbDrone.Web/NzbDrone.Web.csproj index 253dd378e..cdc12b345 100644 --- a/NzbDrone.Web/NzbDrone.Web.csproj +++ b/NzbDrone.Web/NzbDrone.Web.csproj @@ -523,6 +523,12 @@ + + + + + +