mirror of
https://github.com/Radarr/Radarr.git
synced 2024-11-07 03:22:37 +01:00
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.
This commit is contained in:
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 @@ public void individual_missing_episode()
|
||||
//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 @@ public void individual_missing_episodes_only()
|
||||
//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 @@ public void series_season_missing_episodes_only_mismatch_count()
|
||||
//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 @@ public void series_season_missing_episodes_only()
|
||||
//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 @@ public void multiple_missing_episodes()
|
||||
//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 @@ public void multiple_missing_episodes()
|
||||
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.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 @@ public void should_only_process_missing_episodes_from_the_last_30_days()
|
||||
{
|
||||
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 @@ public void should_only_process_missing_episodes_from_the_last_30_days()
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
15
NzbDrone.Core/Datastore/Migrations/Migration20120123.cs
Normal file
15
NzbDrone.Core/Datastore/Migrations/Migration20120123.cs
Normal file
@ -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 @@ public TimeSpan DefaultInterval
|
||||
|
||||
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 @@ public void Start(ProgressNotification notification, int targetId, int secondary
|
||||
_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,21 +38,36 @@ public TimeSpan DefaultInterval
|
||||
|
||||
public void Start(ProgressNotification notification, int targetId, int secondaryTargetId)
|
||||
{
|
||||
if (!_configProvider.EnableBacklogSearching)
|
||||
{
|
||||
Logger.Trace("Backlog searching is not enabled, aborting job.");
|
||||
return;
|
||||
}
|
||||
var missingEpisodes = GetMissingForEnabledSeries();
|
||||
|
||||
//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));
|
||||
|
||||
Logger.Debug("Processing missing episodes from the last 30 days");
|
||||
//Process the list of remaining episodes, 1 by 1
|
||||
Logger.Debug("Processing missing episodes from the last 30 days, count: {0}", missingEpisodes.Count);
|
||||
foreach (var episode in missingEpisodes)
|
||||
{
|
||||
_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.AirDate >= DateTime.Today.AddDays(-30) &&
|
||||
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.AirDate >= DateTime.Today.AddDays(-30) &&
|
||||
e.Series.BacklogStatus != BacklogStatusType.Disable &&
|
||||
e.Series.Monitored
|
||||
).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
NzbDrone.Core/Model/BacklogStatusType.cs
Normal file
9
NzbDrone.Core/Model/BacklogStatusType.cs
Normal file
@ -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.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 @@ public virtual IList<Series> GetAllSeriesWithEpisodeCount()
|
||||
{
|
||||
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 @@ FROM Series
|
||||
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 @@ public virtual void AddSeries(string path, int tvDbSeriesId, int qualityProfileI
|
||||
repoSeries.QualityProfileId = _configProvider.DefaultQualityProfile;
|
||||
|
||||
repoSeries.SeasonFolder = _configProvider.UseSeasonFolder;
|
||||
repoSeries.BacklogStatus = BacklogStatusType.Inherit;
|
||||
|
||||
_database.Insert(repoSeries);
|
||||
}
|
||||
@ -210,6 +212,7 @@ public virtual void UpdateFromMassEdit(IList<Series> editedSeries)
|
||||
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 @@ public class Series
|
||||
|
||||
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.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 @@ public ActionResult Index()
|
||||
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 @@ public ActionResult _AjaxSeriesGrid()
|
||||
|
||||
[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 @@ public ActionResult MassEdit()
|
||||
}, "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 @@ private List<SeriesModel> GetSeriesModels(IList<Series> seriesInDb)
|
||||
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 @@ public class SeriesModel
|
||||
[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…
Reference in New Issue
Block a user