Last Season and Recent Episodes
New: Added option to only monitor recent episodes Fixed: Last Season always monitors the whole season Closes #6175
This commit is contained in:
parent
ade40b72bc
commit
5d86329c18
|
@ -26,14 +26,24 @@ function SeriesMonitoringOptionsPopoverContent() {
|
||||||
data={translate('MonitorExistingEpisodesDescription')}
|
data={translate('MonitorExistingEpisodesDescription')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<DescriptionListItem
|
||||||
|
title={translate('MonitorRecentEpisodes')}
|
||||||
|
data={translate('MonitorRecentEpisodesDescription')}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<DescriptionListItem
|
||||||
|
title={translate('MonitorPilotEpisode')}
|
||||||
|
data={translate('MonitorPilotEpisodeDescription')}
|
||||||
|
/>
|
||||||
|
|
||||||
<DescriptionListItem
|
<DescriptionListItem
|
||||||
title={translate('MonitorFirstSeason')}
|
title={translate('MonitorFirstSeason')}
|
||||||
data={translate('MonitorFirstSeasonDescription')}
|
data={translate('MonitorFirstSeasonDescription')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<DescriptionListItem
|
<DescriptionListItem
|
||||||
title={translate('MonitorLatestSeason')}
|
title={translate('MonitorLastSeason')}
|
||||||
data={translate('MonitorLatestSeasonDescription')}
|
data={translate('MonitorLastSeasonDescription')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<DescriptionListItem
|
<DescriptionListItem
|
||||||
|
|
|
@ -25,6 +25,12 @@ const monitorOptions = [
|
||||||
return translate('MonitorExistingEpisodes');
|
return translate('MonitorExistingEpisodes');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'recent',
|
||||||
|
get value() {
|
||||||
|
return translate('MonitorRecentEpisodes');
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'pilot',
|
key: 'pilot',
|
||||||
get value() {
|
get value() {
|
||||||
|
@ -38,9 +44,9 @@ const monitorOptions = [
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'latestSeason',
|
key: 'lastSeason',
|
||||||
get value() {
|
get value() {
|
||||||
return translate('MonitorLatestSeason');
|
return translate('MonitorLastSeason');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -202,7 +202,7 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeMonitoredServiceTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_monitor_season_when_all_episodes_are_monitored_except_latest_season()
|
public void should_not_monitor_season_when_all_episodes_are_monitored_except_last_season()
|
||||||
{
|
{
|
||||||
_series.Seasons = Builder<Season>.CreateListOfSize(2)
|
_series.Seasons = Builder<Season>.CreateListOfSize(2)
|
||||||
.All()
|
.All()
|
||||||
|
@ -226,7 +226,7 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeMonitoredServiceTests
|
||||||
|
|
||||||
var monitoringOptions = new MonitoringOptions
|
var monitoringOptions = new MonitoringOptions
|
||||||
{
|
{
|
||||||
Monitor = MonitorTypes.LatestSeason
|
Monitor = MonitorTypes.LastSeason
|
||||||
};
|
};
|
||||||
|
|
||||||
Subject.SetEpisodeMonitoredStatus(_series, monitoringOptions);
|
Subject.SetEpisodeMonitoredStatus(_series, monitoringOptions);
|
||||||
|
@ -264,13 +264,47 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeMonitoredServiceTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_monitor_latest_season_if_all_episodes_aired_more_than_90_days_ago()
|
public void should_monitor_last_season_if_all_episodes_aired_more_than_90_days_ago()
|
||||||
|
{
|
||||||
|
_series.Seasons = Builder<Season>.CreateListOfSize(2)
|
||||||
|
.All()
|
||||||
|
.With(n => n.Monitored = true)
|
||||||
|
.Build()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
_episodes = Builder<Episode>.CreateListOfSize(5)
|
||||||
|
.All()
|
||||||
|
.With(e => e.SeasonNumber = 1)
|
||||||
|
.With(e => e.EpisodeFileId = 0)
|
||||||
|
.With(e => e.AirDateUtc = DateTime.UtcNow.AddDays(-200))
|
||||||
|
.TheLast(2)
|
||||||
|
.With(e => e.SeasonNumber = 2)
|
||||||
|
.With(e => e.AirDateUtc = DateTime.UtcNow.AddDays(-100))
|
||||||
|
.Build()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var monitoringOptions = new MonitoringOptions
|
||||||
|
{
|
||||||
|
Monitor = MonitorTypes.LastSeason
|
||||||
|
};
|
||||||
|
|
||||||
|
Subject.SetEpisodeMonitoredStatus(_series, monitoringOptions);
|
||||||
|
|
||||||
|
VerifySeasonMonitored(n => n.SeasonNumber == 2);
|
||||||
|
VerifyMonitored(n => n.SeasonNumber == 2);
|
||||||
|
|
||||||
|
VerifySeasonNotMonitored(n => n.SeasonNumber == 1);
|
||||||
|
VerifyNotMonitored(n => n.SeasonNumber == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_monitor_any_recent_episodes_if_all_episodes_aired_more_than_90_days_ago()
|
||||||
{
|
{
|
||||||
_episodes.ForEach(e => e.AirDateUtc = DateTime.UtcNow.AddDays(-100));
|
_episodes.ForEach(e => e.AirDateUtc = DateTime.UtcNow.AddDays(-100));
|
||||||
|
|
||||||
var monitoringOptions = new MonitoringOptions
|
var monitoringOptions = new MonitoringOptions
|
||||||
{
|
{
|
||||||
Monitor = MonitorTypes.LatestSeason
|
Monitor = MonitorTypes.Recent
|
||||||
};
|
};
|
||||||
|
|
||||||
Subject.SetEpisodeMonitoredStatus(_series, monitoringOptions);
|
Subject.SetEpisodeMonitoredStatus(_series, monitoringOptions);
|
||||||
|
@ -279,6 +313,43 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeMonitoredServiceTests
|
||||||
.Verify(v => v.UpdateEpisodes(It.Is<List<Episode>>(l => l.All(e => !e.Monitored))));
|
.Verify(v => v.UpdateEpisodes(It.Is<List<Episode>>(l => l.All(e => !e.Monitored))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_monitor_any_recent_and_future_episodes_if_all_episodes_aired_within_90_days()
|
||||||
|
{
|
||||||
|
_series.Seasons = Builder<Season>.CreateListOfSize(1)
|
||||||
|
.All()
|
||||||
|
.With(n => n.Monitored = true)
|
||||||
|
.Build()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
_episodes = Builder<Episode>.CreateListOfSize(5)
|
||||||
|
.All()
|
||||||
|
.With(e => e.SeasonNumber = 1)
|
||||||
|
.With(e => e.EpisodeFileId = 0)
|
||||||
|
.With(e => e.AirDateUtc = DateTime.UtcNow.AddDays(-200))
|
||||||
|
.TheLast(3)
|
||||||
|
.With(e => e.AirDateUtc = DateTime.UtcNow.AddDays(-5))
|
||||||
|
.TheLast(1)
|
||||||
|
.With(e => e.AirDateUtc = DateTime.UtcNow.AddDays(30))
|
||||||
|
.Build()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
Mocker.GetMock<IEpisodeService>()
|
||||||
|
.Setup(s => s.GetEpisodeBySeries(It.IsAny<int>()))
|
||||||
|
.Returns(_episodes);
|
||||||
|
|
||||||
|
var monitoringOptions = new MonitoringOptions
|
||||||
|
{
|
||||||
|
Monitor = MonitorTypes.Recent
|
||||||
|
};
|
||||||
|
|
||||||
|
Subject.SetEpisodeMonitoredStatus(_series, monitoringOptions);
|
||||||
|
|
||||||
|
VerifySeasonMonitored(n => n.SeasonNumber == 1);
|
||||||
|
VerifyNotMonitored(n => n.AirDateUtc.HasValue && n.AirDateUtc.Value.Before(DateTime.UtcNow.AddDays(-90)));
|
||||||
|
VerifyMonitored(n => n.AirDateUtc.HasValue && n.AirDateUtc.Value.After(DateTime.UtcNow.AddDays(-90)));
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_monitor_latest_season_if_some_episodes_have_aired()
|
public void should_monitor_latest_season_if_some_episodes_have_aired()
|
||||||
{
|
{
|
||||||
|
@ -302,7 +373,7 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeMonitoredServiceTests
|
||||||
|
|
||||||
var monitoringOptions = new MonitoringOptions
|
var monitoringOptions = new MonitoringOptions
|
||||||
{
|
{
|
||||||
Monitor = MonitorTypes.LatestSeason
|
Monitor = MonitorTypes.LastSeason
|
||||||
};
|
};
|
||||||
|
|
||||||
Subject.SetEpisodeMonitoredStatus(_series, monitoringOptions);
|
Subject.SetEpisodeMonitoredStatus(_series, monitoringOptions);
|
||||||
|
|
|
@ -984,8 +984,8 @@
|
||||||
"MonitorFirstSeasonDescription": "Monitor all episodes of the first season. All other seasons will be ignored",
|
"MonitorFirstSeasonDescription": "Monitor all episodes of the first season. All other seasons will be ignored",
|
||||||
"MonitorFutureEpisodes": "Future Episodes",
|
"MonitorFutureEpisodes": "Future Episodes",
|
||||||
"MonitorFutureEpisodesDescription": "Monitor episodes that have not aired yet",
|
"MonitorFutureEpisodesDescription": "Monitor episodes that have not aired yet",
|
||||||
"MonitorLatestSeason": "Latest Season",
|
"MonitorLastSeason": "Last Season",
|
||||||
"MonitorLatestSeasonDescription": "Monitor all episodes of the latest season that aired within the last 90 days and all future seasons",
|
"MonitorLastSeasonDescription": "Monitor all episodes of the last season",
|
||||||
"MonitorMissingEpisodes": "Missing Episodes",
|
"MonitorMissingEpisodes": "Missing Episodes",
|
||||||
"MonitorMissingEpisodesDescription": "Monitor episodes that do not have files or have not aired yet",
|
"MonitorMissingEpisodesDescription": "Monitor episodes that do not have files or have not aired yet",
|
||||||
"MonitorNewSeasons": "Monitor New Seasons",
|
"MonitorNewSeasons": "Monitor New Seasons",
|
||||||
|
@ -994,6 +994,9 @@
|
||||||
"MonitorNone": "None",
|
"MonitorNone": "None",
|
||||||
"MonitorNoneDescription": "No episodes will be monitored",
|
"MonitorNoneDescription": "No episodes will be monitored",
|
||||||
"MonitorPilotEpisode": "Pilot Episode",
|
"MonitorPilotEpisode": "Pilot Episode",
|
||||||
|
"MonitorPilotEpisodeDescription": "Only monitor the first episode of the first season",
|
||||||
|
"MonitorRecentEpisodes": "Recent Episodes",
|
||||||
|
"MonitorRecentEpisodesDescription": "Monitor episodes aired within the last 90 days and future episodes",
|
||||||
"MonitorSelected": "Monitor Selected",
|
"MonitorSelected": "Monitor Selected",
|
||||||
"MonitorSeries": "Monitor Series",
|
"MonitorSeries": "Monitor Series",
|
||||||
"MonitorSpecials": "Monitor Specials",
|
"MonitorSpecials": "Monitor Specials",
|
||||||
|
|
|
@ -83,23 +83,27 @@ namespace NzbDrone.Core.Tv
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MonitorTypes.LastSeason:
|
||||||
|
#pragma warning disable CS0612
|
||||||
case MonitorTypes.LatestSeason:
|
case MonitorTypes.LatestSeason:
|
||||||
if (episodes.Where(e => e.SeasonNumber == lastSeason)
|
#pragma warning restore CS0612
|
||||||
.All(e => e.AirDateUtc.HasValue &&
|
|
||||||
e.AirDateUtc.Value.Before(DateTime.UtcNow) &&
|
|
||||||
!e.AirDateUtc.Value.InLastDays(90)))
|
|
||||||
{
|
|
||||||
_logger.Debug("[{0}] Unmonitoring all episodes because latest season aired more than 90 days ago", series.Title);
|
|
||||||
ToggleEpisodesMonitoredState(episodes, e => false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.Debug("[{0}] Monitoring latest season episodes", series.Title);
|
_logger.Debug("[{0}] Monitoring latest season episodes", series.Title);
|
||||||
|
|
||||||
ToggleEpisodesMonitoredState(episodes, e => e.SeasonNumber > 0 && e.SeasonNumber == lastSeason);
|
ToggleEpisodesMonitoredState(episodes, e => e.SeasonNumber > 0 && e.SeasonNumber == lastSeason);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MonitorTypes.Recent:
|
||||||
|
_logger.Debug("[{0}] Monitoring recent and future episodes", series.Title);
|
||||||
|
|
||||||
|
ToggleEpisodesMonitoredState(episodes, e => e.SeasonNumber > 0 &&
|
||||||
|
(!e.AirDateUtc.HasValue || (
|
||||||
|
e.AirDateUtc.Value.Before(DateTime.UtcNow) &&
|
||||||
|
e.AirDateUtc.Value.InLastDays(90))
|
||||||
|
|| e.AirDateUtc.Value.After(DateTime.UtcNow)));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case MonitorTypes.MonitorSpecials:
|
case MonitorTypes.MonitorSpecials:
|
||||||
_logger.Debug("[{0}] Monitoring special episodes", series.Title);
|
_logger.Debug("[{0}] Monitoring special episodes", series.Title);
|
||||||
ToggleEpisodesMonitoredState(episodes.Where(e => e.SeasonNumber == 0), true);
|
ToggleEpisodesMonitoredState(episodes.Where(e => e.SeasonNumber == 0), true);
|
||||||
|
@ -128,15 +132,14 @@ namespace NzbDrone.Core.Tv
|
||||||
{
|
{
|
||||||
var seasonNumber = season.SeasonNumber;
|
var seasonNumber = season.SeasonNumber;
|
||||||
|
|
||||||
// Monitor the season when:
|
// Monitor the last season when:
|
||||||
// - Not specials
|
// - Not specials
|
||||||
// - The latest season
|
// - The latest season
|
||||||
// - Not only supposed to monitor the first season
|
// - Set to monitor all or future episodes
|
||||||
if (seasonNumber > 0 &&
|
if (seasonNumber > 0 &&
|
||||||
seasonNumber == lastSeason &&
|
seasonNumber == lastSeason &&
|
||||||
monitoringOptions.Monitor != MonitorTypes.FirstSeason &&
|
(monitoringOptions.Monitor == MonitorTypes.All ||
|
||||||
monitoringOptions.Monitor != MonitorTypes.Pilot &&
|
monitoringOptions.Monitor == MonitorTypes.Future))
|
||||||
monitoringOptions.Monitor != MonitorTypes.None)
|
|
||||||
{
|
{
|
||||||
season.Monitored = true;
|
season.Monitored = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Tv
|
namespace NzbDrone.Core.Tv
|
||||||
|
@ -17,8 +18,13 @@ namespace NzbDrone.Core.Tv
|
||||||
Missing,
|
Missing,
|
||||||
Existing,
|
Existing,
|
||||||
FirstSeason,
|
FirstSeason,
|
||||||
|
LastSeason,
|
||||||
|
|
||||||
|
[Obsolete]
|
||||||
LatestSeason,
|
LatestSeason,
|
||||||
|
|
||||||
Pilot,
|
Pilot,
|
||||||
|
Recent,
|
||||||
MonitorSpecials,
|
MonitorSpecials,
|
||||||
UnmonitorSpecials,
|
UnmonitorSpecials,
|
||||||
None
|
None
|
||||||
|
|
|
@ -139,7 +139,6 @@ namespace NzbDrone.Core.Tv
|
||||||
{
|
{
|
||||||
var existingSeason = series.Seasons.FirstOrDefault(s => s.SeasonNumber == season.SeasonNumber);
|
var existingSeason = series.Seasons.FirstOrDefault(s => s.SeasonNumber == season.SeasonNumber);
|
||||||
|
|
||||||
// Todo: Should this should use the previous season's monitored state?
|
|
||||||
if (existingSeason == null)
|
if (existingSeason == null)
|
||||||
{
|
{
|
||||||
if (season.SeasonNumber == 0)
|
if (season.SeasonNumber == 0)
|
||||||
|
@ -149,8 +148,10 @@ namespace NzbDrone.Core.Tv
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Debug("New season ({0}) for series: [{1}] {2}, setting monitored to {3}", season.SeasonNumber, series.TvdbId, series.Title, series.Monitored.ToString().ToLowerInvariant());
|
var monitorNewSeasons = series.MonitorNewItems == NewItemMonitorTypes.All;
|
||||||
season.Monitored = series.Monitored;
|
|
||||||
|
_logger.Debug("New season ({0}) for series: [{1}] {2}, setting monitored to {3}", season.SeasonNumber, series.TvdbId, series.Title, monitorNewSeasons.ToString().ToLowerInvariant());
|
||||||
|
season.Monitored = monitorNewSeasons;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue