BacklogStatus added to individually control which series are included in backlog searches. Applies to Backlog and RecentBacklog jobs. Editable in Series/MassEdit and Series Edit.

pull/3113/head
Mark McDowall 13 years ago
parent fb17765d3a
commit 9eb022fdf4

@ -2,9 +2,11 @@
using System.Linq;
using FizzWare.NBuilder;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.Jobs;
using NzbDrone.Core.Model;
using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core;
@ -53,7 +55,15 @@ namespace NzbDrone.Core.Test.JobTests
//Setup
var notification = new ProgressNotification("Backlog Search Job Test");
var episodes = Builder<Episode>.CreateListOfSize(1).Build();
var series = Builder<Series>.CreateNew()
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Enable)
.Build();
var episodes = Builder<Episode>.CreateListOfSize(1)
.All()
.With(e => e.Series = series)
.Build();
WithStrictMocker();
WithEnableBacklogSearching();
@ -81,7 +91,15 @@ namespace NzbDrone.Core.Test.JobTests
//Setup
var notification = new ProgressNotification("Backlog Search Job Test");
var episodes = Builder<Episode>.CreateListOfSize(5).Build();
var series = Builder<Series>.CreateNew()
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Enable)
.Build();
var episodes = Builder<Episode>.CreateListOfSize(5)
.All()
.With(e => e.Series = series)
.Build();
WithStrictMocker();
WithEnableBacklogSearching();
@ -109,9 +127,14 @@ namespace NzbDrone.Core.Test.JobTests
//Setup
var notification = new ProgressNotification("Backlog Search Job Test");
var series = Builder<Series>.CreateNew()
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Enable)
.Build();
var episodes = Builder<Episode>.CreateListOfSize(5)
.All()
.With(e => e.SeriesId = 1)
.With(e => e.Series = series)
.With(e => e.SeasonNumber = 1)
.Build();
@ -144,9 +167,15 @@ namespace NzbDrone.Core.Test.JobTests
//Setup
var notification = new ProgressNotification("Backlog Search Job Test");
var series = Builder<Series>.CreateNew()
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Enable)
.Build();
var episodes = Builder<Episode>.CreateListOfSize(5)
.All()
.With(e => e.SeriesId = 1)
.With(e => e.Series = series)
.With(e => e.SeriesId = series.SeriesId)
.With(e => e.SeasonNumber = 1)
.Build();
@ -179,10 +208,23 @@ namespace NzbDrone.Core.Test.JobTests
//Setup
var notification = new ProgressNotification("Backlog Search Job Test");
var series = Builder<Series>.CreateNew()
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Enable)
.Build();
var series2 = Builder<Series>.CreateNew()
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Enable)
.Build();
var episodes = Builder<Episode>.CreateListOfSize(10)
.TheFirst(5)
.With(e => e.SeriesId = 1)
.With(e => e.Series = series)
.With(e => e.SeriesId = series.SeriesId)
.With(e => e.SeasonNumber = 1)
.TheNext(5)
.With(e => e.Series = series2)
.Build();
WithStrictMocker();
@ -210,5 +252,120 @@ namespace NzbDrone.Core.Test.JobTests
Mocker.GetMock<EpisodeSearchJob>().Verify(c => c.Start(notification, It.IsAny<int>(), 0),
Times.Exactly(5));
}
[Test]
public void GetMissingForEnabledSeries_should_only_return_episodes_for_monitored_series()
{
//Setup
var series = Builder<Series>.CreateListOfSize(2)
.TheFirst(1)
.With(s => s.Monitored = false)
.With(s => s.BacklogStatus = BacklogStatusType.Enable)
.TheNext(1)
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Enable)
.Build();
var episodes = Builder<Episode>.CreateListOfSize(11)
.TheFirst(5)
.With(e => e.Series = series[0])
.With(e => e.SeasonNumber = 1)
.TheLast(6)
.With(e => e.Series = series[1])
.Build();
WithEnableBacklogSearching();
Mocker.GetMock<EpisodeProvider>()
.Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes);
//Act
var result = Mocker.Resolve<BacklogSearchJob>().GetMissingForEnabledSeries();
//Assert
result.Should().NotBeEmpty();
result.Should().Contain(s => s.Series.Monitored);
result.Should().NotContain(s => !s.Series.Monitored);
}
[Test]
public void GetMissingForEnabledSeries_should_only_return_explicity_enabled_series_when_backlog_searching_is_ignored()
{
//Setup
var series = Builder<Series>.CreateListOfSize(3)
.TheFirst(1)
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Disable)
.TheNext(1)
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Enable)
.TheNext(1)
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Inherit)
.Build();
var episodes = Builder<Episode>.CreateListOfSize(12)
.TheFirst(3)
.With(e => e.Series = series[0])
.TheNext(4)
.With(e => e.Series = series[1])
.TheNext(5)
.With(e => e.Series = series[2])
.Build();
//WithEnableBacklogSearching();
Mocker.GetMock<EpisodeProvider>()
.Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes);
//Act
var result = Mocker.Resolve<BacklogSearchJob>().GetMissingForEnabledSeries();
//Assert
result.Should().NotBeEmpty();
result.Should().Contain(s => s.Series.BacklogStatus == BacklogStatusType.Enable);
result.Should().NotContain(s => s.Series.BacklogStatus == BacklogStatusType.Disable);
result.Should().NotContain(s => s.Series.BacklogStatus == BacklogStatusType.Inherit);
}
[Test]
public void GetMissingForEnabledSeries_should_return_explicity_enabled_and_inherit_series_when_backlog_searching_is_enabled()
{
//Setup
var series = Builder<Series>.CreateListOfSize(3)
.TheFirst(1)
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Disable)
.TheNext(1)
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Enable)
.TheNext(1)
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Inherit)
.Build();
var episodes = Builder<Episode>.CreateListOfSize(12)
.TheFirst(3)
.With(e => e.Series = series[0])
.TheNext(4)
.With(e => e.Series = series[1])
.TheNext(5)
.With(e => e.Series = series[2])
.Build();
WithEnableBacklogSearching();
Mocker.GetMock<EpisodeProvider>()
.Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes);
//Act
var result = Mocker.Resolve<BacklogSearchJob>().GetMissingForEnabledSeries();
//Assert
result.Should().NotBeEmpty();
result.Should().Contain(s => s.Series.BacklogStatus == BacklogStatusType.Enable);
result.Should().NotContain(s => s.Series.BacklogStatus == BacklogStatusType.Disable);
result.Should().Contain(s => s.Series.BacklogStatus == BacklogStatusType.Inherit);
}
}
}

@ -3,9 +3,11 @@ using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.Jobs;
using NzbDrone.Core.Model;
using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core;
@ -51,8 +53,15 @@ namespace NzbDrone.Core.Test.JobTests
{
WithEnableBacklogSearching();
var series = Builder<Series>.CreateNew()
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Enable)
.Build();
//Setup
var episodes = Builder<Episode>.CreateListOfSize(50)
.All()
.With(e => e.Series = series)
.TheFirst(5)
.With(e => e.AirDate = DateTime.Today)
.TheNext(5)
@ -87,5 +96,121 @@ namespace NzbDrone.Core.Test.JobTests
Mocker.GetMock<EpisodeSearchJob>().Verify(c => c.Start(It.IsAny<ProgressNotification>(), It.IsAny<int>(), 0),
Times.Exactly(40));
}
[Test]
public void GetMissingForEnabledSeries_should_only_return_episodes_for_monitored_series()
{
//Setup
var series = Builder<Series>.CreateListOfSize(2)
.TheFirst(1)
.With(s => s.Monitored = false)
.With(s => s.BacklogStatus = BacklogStatusType.Enable)
.TheNext(1)
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Enable)
.Build();
var episodes = Builder<Episode>.CreateListOfSize(11)
.TheFirst(5)
.With(e => e.Series = series[0])
.With(e => e.SeasonNumber = 1)
.TheLast(6)
.With(e => e.Series = series[1])
.Build();
WithEnableBacklogSearching();
Mocker.GetMock<EpisodeProvider>()
.Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes);
//Act
var result = Mocker.Resolve<RecentBacklogSearchJob>().GetMissingForEnabledSeries();
//Assert
result.Should().NotBeEmpty();
result.Should().Contain(s => s.Series.Monitored);
result.Should().NotContain(s => !s.Series.Monitored);
}
[Test]
public void GetMissingForEnabledSeries_should_only_return_explicity_enabled_series_when_backlog_searching_is_ignored()
{
//Setup
var series = Builder<Series>.CreateListOfSize(3)
.TheFirst(1)
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Disable)
.TheNext(1)
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Enable)
.TheNext(1)
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Inherit)
.Build();
var episodes = Builder<Episode>.CreateListOfSize(12)
.TheFirst(3)
.With(e => e.Series = series[0])
.TheNext(4)
.With(e => e.Series = series[1])
.TheNext(5)
.With(e => e.Series = series[2])
.Build();
//WithEnableBacklogSearching();
Mocker.GetMock<EpisodeProvider>()
.Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes);
//Act
var result = Mocker.Resolve<RecentBacklogSearchJob>().GetMissingForEnabledSeries();
//Assert
result.Should().NotBeEmpty();
result.Should().Contain(s => s.Series.BacklogStatus == BacklogStatusType.Enable);
result.Should().NotContain(s => s.Series.BacklogStatus == BacklogStatusType.Disable);
result.Should().NotContain(s => s.Series.BacklogStatus == BacklogStatusType.Inherit);
}
[Test]
public void GetMissingForEnabledSeries_should_return_explicity_enabled_and_inherit_series_when_backlog_searching_is_enabled()
{
//Setup
var series = Builder<Series>.CreateListOfSize(3)
.TheFirst(1)
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Disable)
.TheNext(1)
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Enable)
.TheNext(1)
.With(s => s.Monitored = true)
.With(s => s.BacklogStatus = BacklogStatusType.Inherit)
.Build();
var episodes = Builder<Episode>.CreateListOfSize(12)
.TheFirst(3)
.With(e => e.Series = series[0])
.TheNext(4)
.With(e => e.Series = series[1])
.TheNext(5)
.With(e => e.Series = series[2])
.Build();
WithEnableBacklogSearching();
Mocker.GetMock<EpisodeProvider>()
.Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes);
//Act
var result = Mocker.Resolve<RecentBacklogSearchJob>().GetMissingForEnabledSeries();
//Assert
result.Should().NotBeEmpty();
result.Should().Contain(s => s.Series.BacklogStatus == BacklogStatusType.Enable);
result.Should().NotContain(s => s.Series.BacklogStatus == BacklogStatusType.Disable);
result.Should().Contain(s => s.Series.BacklogStatus == BacklogStatusType.Inherit);
}
}
}

@ -0,0 +1,15 @@
using System.Data;
using Migrator.Framework;
namespace NzbDrone.Core.Datastore.Migrations
{
[Migration(20120123)]
public class Migration20120123 : NzbDroneMigration
{
protected override void MainDbUpgrade()
{
Database.AddColumn("Series", "BacklogStatus", DbType.Int32, ColumnProperty.Null);
Database.ExecuteNonQuery("UPDATE Series SET BacklogStatus = 2");
}
}
}

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Core.Model;
using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core;
@ -39,14 +40,7 @@ namespace NzbDrone.Core.Jobs
public void Start(ProgressNotification notification, int targetId, int secondaryTargetId)
{
if (!_configProvider.EnableBacklogSearching)
{
Logger.Trace("Backlog searching is not enabled, aborting job.");
return;
}
var missingEpisodes = _episodeProvider.EpisodesWithoutFiles(true)
.GroupBy(e => new { e.SeriesId, e.SeasonNumber });
var missingEpisodes = GetMissingForEnabledSeries().GroupBy(e => new { e.SeriesId, e.SeasonNumber });
var individualEpisodes = new List<Episode>();
@ -91,5 +85,26 @@ namespace NzbDrone.Core.Jobs
_episodeSearchJob.Start(notification, episode.EpisodeId, 0);
}
}
public List<Episode> GetMissingForEnabledSeries()
{
if (!_configProvider.EnableBacklogSearching)
{
Logger.Trace("Backlog searching is not enabled, only running for explicitly enabled series.");
return _episodeProvider.EpisodesWithoutFiles(true).Where(e =>
e.Series.BacklogStatus == BacklogStatusType.Enable &&
e.Series.Monitored
).ToList();
}
else
{
Logger.Trace("Backlog searching is enabled, skipping explicity disabled series.");
return _episodeProvider.EpisodesWithoutFiles(true).Where(e =>
e.Series.BacklogStatus != BacklogStatusType.Disable &&
e.Series.Monitored
).ToList();
}
}
}
}

@ -1,9 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Core.Model;
using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Repository;
namespace NzbDrone.Core.Jobs
{
@ -35,20 +38,35 @@ namespace NzbDrone.Core.Jobs
public void Start(ProgressNotification notification, int targetId, int secondaryTargetId)
{
if (!_configProvider.EnableBacklogSearching)
var missingEpisodes = GetMissingForEnabledSeries();
Logger.Debug("Processing missing episodes from the last 30 days, count: {0}", missingEpisodes.Count);
foreach (var episode in missingEpisodes)
{
Logger.Trace("Backlog searching is not enabled, aborting job.");
return;
_episodeSearchJob.Start(notification, episode.EpisodeId, 0);
}
}
//Get episodes that are considered missing and aired in the last 30 days
var missingEpisodes = _episodeProvider.EpisodesWithoutFiles(true).Where(e => e.AirDate >= DateTime.Today.AddDays(-30));
public List<Episode> GetMissingForEnabledSeries()
{
if (!_configProvider.EnableBacklogSearching)
{
Logger.Trace("Backlog searching is not enabled, only running for explicitly enabled series.");
return _episodeProvider.EpisodesWithoutFiles(true).Where(e =>
e.AirDate >= DateTime.Today.AddDays(-30) &&
e.Series.BacklogStatus == BacklogStatusType.Enable &&
e.Series.Monitored
).ToList();
}
Logger.Debug("Processing missing episodes from the last 30 days");
//Process the list of remaining episodes, 1 by 1
foreach (var episode in missingEpisodes)
else
{
_episodeSearchJob.Start(notification, episode.EpisodeId, 0);
Logger.Trace("Backlog searching is enabled, skipping explicity disabled series.");
return _episodeProvider.EpisodesWithoutFiles(true).Where(e =>
e.AirDate >= DateTime.Today.AddDays(-30) &&
e.Series.BacklogStatus != BacklogStatusType.Disable &&
e.Series.Monitored
).ToList();
}
}
}

@ -0,0 +1,9 @@
namespace NzbDrone.Core.Model
{
public enum BacklogStatusType
{
Disable = 0,
Enable = 1,
Inherit = 2
}
}

@ -208,6 +208,7 @@
<Compile Include="Datastore\MigrationLogger.cs" />
<Compile Include="Datastore\MigrationsHelper.cs" />
<Compile Include="Datastore\CustomeMapper.cs" />
<Compile Include="Datastore\Migrations\Migration20120123.cs" />
<Compile Include="Datastore\Migrations\Migration20120118.cs" />
<Compile Include="Datastore\Migrations\Migration20111125.cs" />
<Compile Include="Datastore\Migrations\Migration20111112.cs" />
@ -228,6 +229,7 @@
<Compile Include="Datastore\PetaPoco\PetaPoco.cs" />
<Compile Include="Model\AtomicParsleyTitleType.cs" />
<Compile Include="Model\ConnectionInfoModel.cs" />
<Compile Include="Model\BacklogStatusType.cs" />
<Compile Include="Model\PostDownloadStatusType.cs" />
<Compile Include="Model\JobQueueItem.cs" />
<Compile Include="Model\LanguageType.cs" />

@ -4,6 +4,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using NLog;
using NzbDrone.Common;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Quality;
@ -45,7 +46,7 @@ namespace NzbDrone.Core.Providers
{
var series = _database
.Fetch<Series, QualityProfile>(@"SELECT Series.SeriesId, Series.Title, Series.CleanTitle, Series.Status, Series.Overview, Series.AirsDayOfWeek,Series.AirTimes,
Series.Language, Series.Path, Series.Monitored, Series.QualityProfileId, Series.SeasonFolder,
Series.Language, Series.Path, Series.Monitored, Series.QualityProfileId, Series.SeasonFolder, Series.BacklogStatus,
SUM(CASE WHEN Ignored = 0 AND Airdate <= @0 THEN 1 ELSE 0 END) AS EpisodeCount,
SUM(CASE WHEN Episodes.Ignored = 0 AND Episodes.EpisodeFileId > 0 AND Episodes.AirDate <= @0 THEN 1 ELSE 0 END) as EpisodeFileCount,
MAX(Episodes.SeasonNumber) as SeasonCount, MIN(CASE WHEN AirDate < @0 OR Ignored = 1 THEN NULL ELSE AirDate END) as NextAiring,
@ -55,7 +56,7 @@ namespace NzbDrone.Core.Providers
LEFT JOIN Episodes ON Series.SeriesId = Episodes.SeriesId
WHERE Series.LastInfoSync IS NOT NULL
GROUP BY Series.SeriesId, Series.Title, Series.CleanTitle, Series.Status, Series.Overview, Series.AirsDayOfWeek,Series.AirTimes,
Series.Language, Series.Path, Series.Monitored, Series.QualityProfileId, Series.SeasonFolder,
Series.Language, Series.Path, Series.Monitored, Series.QualityProfileId, Series.SeasonFolder, Series.BacklogStatus,
QualityProfiles.QualityProfileId, QualityProfiles.Name, QualityProfiles.Cutoff, QualityProfiles.SonicAllowed", DateTime.Today);
return series;
@ -119,6 +120,7 @@ namespace NzbDrone.Core.Providers
repoSeries.QualityProfileId = _configProvider.DefaultQualityProfile;
repoSeries.SeasonFolder = _configProvider.UseSeasonFolder;
repoSeries.BacklogStatus = BacklogStatusType.Inherit;
_database.Insert(repoSeries);
}
@ -210,6 +212,7 @@ namespace NzbDrone.Core.Providers
series.QualityProfileId = edited.QualityProfileId;
series.Monitored = edited.Monitored;
series.SeasonFolder = edited.SeasonFolder;
series.BacklogStatus = edited.BacklogStatus;
series.Path = edited.Path;
}

@ -1,5 +1,6 @@
using System;
using System.ComponentModel;
using NzbDrone.Core.Model;
using NzbDrone.Core.Repository.Quality;
using PetaPoco;
@ -43,6 +44,8 @@ namespace NzbDrone.Core.Repository
public bool IsDaily { get; set; }
public BacklogStatusType BacklogStatus { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this <see cref="Series"/> is hidden.
/// </summary>

@ -4,9 +4,11 @@ using System.IO;
using System.Linq;
using System.Web.Mvc;
using MvcMiniProfiler;
using NzbDrone.Common.Model;
using NzbDrone.Core;
using NzbDrone.Core.Helpers;
using NzbDrone.Core.Jobs;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Quality;
@ -47,6 +49,15 @@ namespace NzbDrone.Web.Controllers
var profiles = _qualityProvider.All();
ViewData["SelectList"] = new SelectList(profiles, "QualityProfileId", "Name");
var backlogStatusTypes = new List<KeyValuePair<int, string>>();
foreach (BacklogStatusType backlogStatusType in Enum.GetValues(typeof(BacklogStatusType)))
{
backlogStatusTypes.Add(new KeyValuePair<int, string>((int)backlogStatusType, backlogStatusType.ToString()));
}
ViewData["BacklogStatusSelectList"] = new SelectList(backlogStatusTypes, "Key", "Value");
return View();
}
@ -59,13 +70,14 @@ namespace NzbDrone.Web.Controllers
[AcceptVerbs(HttpVerbs.Post)]
[GridAction]
public ActionResult _SaveAjaxSeriesEditing(int id, string path, bool monitored, bool seasonFolder, int qualityProfileId)
public ActionResult _SaveAjaxSeriesEditing(int id, string path, bool monitored, bool seasonFolder, int qualityProfileId, int backlogStatus)
{
var oldSeries = _seriesProvider.GetSeries(id);
oldSeries.Monitored = monitored;
oldSeries.SeasonFolder = seasonFolder;
oldSeries.QualityProfileId = qualityProfileId;
oldSeries.Path = path;
oldSeries.BacklogStatus = (BacklogStatusType)backlogStatus;
_seriesProvider.UpdateSeries(oldSeries);
@ -167,6 +179,19 @@ namespace NzbDrone.Web.Controllers
}, "Key", "Value"
);
var backlogStatusTypes = new List<KeyValuePair<int, string>>();
foreach (BacklogStatusType backlogStatusType in Enum.GetValues(typeof(BacklogStatusType)))
{
backlogStatusTypes.Add(new KeyValuePair<int, string>((int)backlogStatusType, backlogStatusType.ToString()));
}
ViewData["BacklogStatusTypes"] = backlogStatusTypes;
var masterBacklogList = backlogStatusTypes.ToList();
masterBacklogList.Insert(0, new KeyValuePair<int, string>(-10, "Unchanged"));
ViewData["MasterBacklogStatusSelectList"] = new SelectList(masterBacklogList, "Key", "Value");
var series = _seriesProvider.GetAllSeries().OrderBy(o => SortHelper.SkipArticles(o.Title));
return View(series);
@ -196,6 +221,7 @@ namespace NzbDrone.Web.Controllers
QualityProfileId = s.QualityProfileId,
QualityProfileName = s.QualityProfile.Name,
SeasonFolder = s.SeasonFolder,
BacklogStatus = (int)s.BacklogStatus,
Status = s.Status,
SeasonsCount = s.SeasonCount,
EpisodeCount = s.EpisodeCount,

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Web;
using NzbDrone.Core.Model;
using NzbDrone.Core.Repository;
namespace NzbDrone.Web.Models
@ -42,5 +43,9 @@ namespace NzbDrone.Web.Models
[DisplayName("Monitored")]
[Description("Should NzbDrone download episodes for this series?")]
public bool Monitored { get; set; }
[DisplayName("Backlog Status")]
[Description("Should NzbDrone download past missing episodes?")]
public int BacklogStatus { get; set; }
}
}

@ -30,5 +30,9 @@
<span class="small">@Html.DescriptionFor(m => m.Path)</span>
</label>
@Html.TextBoxFor(m => m.Path, new { @class = "inputClass" })
<label class="labelClass">@Html.LabelFor(m => m.BacklogStatus)
<span class="small">@Html.DescriptionFor(m => m.BacklogStatus)</span>
</label>
@Html.DropDownListFor(m => m.BacklogStatus, (SelectList)ViewData["BacklogStatusSelectList"], new { @class = "inputClass" })
</div>
</div>

@ -30,6 +30,10 @@
width: 300px;
}
td .backlogStatus {
width: 90px;
}
table {
width: 100%;
border-width: 1px;
@ -67,6 +71,7 @@
<th width="210px">Quality</th>
<th class="checkboxColumn">Monitored</th>
<th class="checkboxColumn">Season Folder</th>
<th width="100px">Backlog Status</th>
<th width="310px">Path</th>
</tr>
@ -91,6 +96,10 @@
<span class="small">Should downloaded episodes be stored in season folders?</span>
</label>
@Html.DropDownList("masterSeasonFolder", (SelectList)ViewData["BoolSelectList"], new { @class = "inputClass" })
<label class="labelClass">Backlog Status
<span class="small">Should NzbDrone perform backlog searches for this series?</span>
</label>
@Html.DropDownList("masterBacklogStatus", (SelectList)ViewData["MasterBacklogStatusSelectList"], new { @class = "inputClass" })
</div>
</div>
</div>
@ -118,6 +127,7 @@
var profileId = $('#masterQualitySelector').val();
var monitored = $('#masterMonitored').val();
var seasonFolder = $('#masterSeasonFolder').val();
var backlogStatus = $('#masterBacklogStatus').val();
var selected = $('.editToggle:checked');
@ -141,6 +151,10 @@
$(this).parent('td').parent('.seriesEditRow').find('.seasonFolder').prop('checked', seasonFolderBool);
}
if (backlogStatus != -10) {
$(this).parent('td').parent('.seriesEditRow').find('.backlogStatus').val(backlogStatus);
}
});
});

@ -1,4 +1,5 @@
@model NzbDrone.Core.Repository.Series
@using NzbDrone.Core.Model
@using NzbDrone.Core.Repository.Quality
@using NzbDrone.Web.Helpers
@ -18,6 +19,7 @@
<td>@Html.DropDownListFor(m => m.QualityProfileId, new SelectList((List<QualityProfile>)ViewData["QualityProfiles"], "QualityProfileId", "Name", Model.QualityProfileId), new { @class = "quality" })</td>
<td class="checkboxColumn">@Html.CheckBoxFor(m => m.Monitored, new {@class = "seriesCheckbox monitored"})</td>
<td class="checkboxColumn">@Html.CheckBoxFor(m => m.SeasonFolder, new {@class = "seriesCheckbox seasonFolder"})</td>
<td>@Html.DropDownListFor(m => m.BacklogStatus, new SelectList((List<KeyValuePair<int, string>>)ViewData["BacklogStatusTypes"], "Key", "Value", (int)Model.BacklogStatus), new { @class = "backlogStatus" })</td>
<td>@Html.TextBoxFor(m => m.Path, new { @class = "path" })</td>
</tr>
}
Loading…
Cancel
Save