From c2b06d957d896fda6634f262d5f2b4c8289dd088 Mon Sep 17 00:00:00 2001 From: Taloth Saldono Date: Sat, 21 Jun 2014 00:27:53 +0200 Subject: [PATCH] New: Series Overview sorted by Next Airing now sorts all remaining items by their Last Aired date. --- src/NzbDrone.Api/Series/SeriesModule.cs | 1 + src/NzbDrone.Api/Series/SeriesResource.cs | 1 + .../SeriesStatisticsFixture.cs | 47 +++++++++++++++++++ .../SeriesStats/SeriesStatistics.cs | 13 +++++ .../SeriesStats/SeriesStatisticsRepository.cs | 3 +- src/UI/Series/SeriesCollection.js | 14 ++++-- 6 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/NzbDrone.Api/Series/SeriesModule.cs b/src/NzbDrone.Api/Series/SeriesModule.cs index 0439fdb27..8b26e5dd2 100644 --- a/src/NzbDrone.Api/Series/SeriesModule.cs +++ b/src/NzbDrone.Api/Series/SeriesModule.cs @@ -177,6 +177,7 @@ namespace NzbDrone.Api.Series resource.EpisodeCount = seriesStatistics.EpisodeCount; resource.EpisodeFileCount = seriesStatistics.EpisodeFileCount; resource.NextAiring = seriesStatistics.NextAiring; + resource.PreviousAiring = seriesStatistics.PreviousAiring; } public void Handle(EpisodeImportedEvent message) diff --git a/src/NzbDrone.Api/Series/SeriesResource.cs b/src/NzbDrone.Api/Series/SeriesResource.cs index 95069ad20..28a59fbfd 100644 --- a/src/NzbDrone.Api/Series/SeriesResource.cs +++ b/src/NzbDrone.Api/Series/SeriesResource.cs @@ -34,6 +34,7 @@ namespace NzbDrone.Api.Series public String QualityProfileName { get; set; } public String Overview { get; set; } public DateTime? NextAiring { get; set; } + public DateTime? PreviousAiring { get; set; } public String Network { get; set; } public String AirTime { get; set; } public List Images { get; set; } diff --git a/src/NzbDrone.Core.Test/SeriesStatsTests/SeriesStatisticsFixture.cs b/src/NzbDrone.Core.Test/SeriesStatsTests/SeriesStatisticsFixture.cs index 1b689c53c..1172daff2 100644 --- a/src/NzbDrone.Core.Test/SeriesStatsTests/SeriesStatisticsFixture.cs +++ b/src/NzbDrone.Core.Test/SeriesStatsTests/SeriesStatisticsFixture.cs @@ -39,6 +39,11 @@ namespace NzbDrone.Core.Test.SeriesStatsTests _episode.EpisodeFileId = 1; } + private void GivenOldEpisode() + { + _episode.AirDateUtc = DateTime.Now.AddSeconds(-10); + } + private void GivenMonitoredEpisode() { _episode.Monitored = true; @@ -59,6 +64,7 @@ namespace NzbDrone.Core.Test.SeriesStatsTests stats.Should().HaveCount(1); stats.First().NextAiring.Should().Be(_episode.AirDateUtc); + stats.First().PreviousAiring.Should().NotHaveValue(); } [Test] @@ -73,6 +79,47 @@ namespace NzbDrone.Core.Test.SeriesStatsTests stats.First().NextAiring.Should().NotHaveValue(); } + [Test] + public void should_have_previous_airing_for_old_episode_with_file() + { + GivenEpisodeWithFile(); + GivenOldEpisode(); + GivenFile(); + + var stats = Subject.SeriesStatistics(); + + stats.Should().HaveCount(1); + stats.First().NextAiring.Should().NotHaveValue(); + stats.First().PreviousAiring.Should().Be(_episode.AirDateUtc); + } + + [Test] + public void should_have_previous_airing_for_old_episode_without_file_monitored() + { + GivenMonitoredEpisode(); + GivenOldEpisode(); + GivenFile(); + + var stats = Subject.SeriesStatistics(); + + stats.Should().HaveCount(1); + stats.First().NextAiring.Should().NotHaveValue(); + stats.First().PreviousAiring.Should().Be(_episode.AirDateUtc); + } + + [Test] + public void should_not_have_previous_airing_for_old_episode_without_file_unmonitored() + { + GivenOldEpisode(); + GivenFile(); + + var stats = Subject.SeriesStatistics(); + + stats.Should().HaveCount(1); + stats.First().NextAiring.Should().NotHaveValue(); + stats.First().PreviousAiring.Should().NotHaveValue(); + } + [Test] public void should_not_include_unmonitored_episode_in_episode_count() { diff --git a/src/NzbDrone.Core/SeriesStats/SeriesStatistics.cs b/src/NzbDrone.Core/SeriesStats/SeriesStatistics.cs index 170985718..e43fb7c64 100644 --- a/src/NzbDrone.Core/SeriesStats/SeriesStatistics.cs +++ b/src/NzbDrone.Core/SeriesStats/SeriesStatistics.cs @@ -7,6 +7,7 @@ namespace NzbDrone.Core.SeriesStats { public int SeriesId { get; set; } public string NextAiringString { get; set; } + public string PreviousAiringString { get; set; } public int EpisodeFileCount { get; set; } public int EpisodeCount { get; set; } @@ -21,5 +22,17 @@ namespace NzbDrone.Core.SeriesStats return nextAiring; } } + + public DateTime? PreviousAiring + { + get + { + DateTime previousAiring; + + if (!DateTime.TryParse(PreviousAiringString, out previousAiring)) return null; + + return previousAiring; + } + } } } diff --git a/src/NzbDrone.Core/SeriesStats/SeriesStatisticsRepository.cs b/src/NzbDrone.Core/SeriesStats/SeriesStatisticsRepository.cs index 6bb4c63d3..683736f77 100644 --- a/src/NzbDrone.Core/SeriesStats/SeriesStatisticsRepository.cs +++ b/src/NzbDrone.Core/SeriesStats/SeriesStatisticsRepository.cs @@ -56,7 +56,8 @@ namespace NzbDrone.Core.SeriesStats SeriesId, SUM(CASE WHEN (Monitored = 1 AND AirdateUtc <= @currentDate) OR EpisodeFileId > 0 THEN 1 ELSE 0 END) AS EpisodeCount, SUM(CASE WHEN EpisodeFileId > 0 THEN 1 ELSE 0 END) AS EpisodeFileCount, - MIN(CASE WHEN AirDateUtc < @currentDate OR EpisodeFileId > 0 OR Monitored = 0 THEN NULL ELSE AirDateUtc END) AS NextAiringString + MIN(CASE WHEN AirDateUtc < @currentDate OR EpisodeFileId > 0 OR Monitored = 0 THEN NULL ELSE AirDateUtc END) AS NextAiringString, + MAX(CASE WHEN AirDateUtc >= @currentDate OR EpisodeFileId = 0 AND Monitored = 0 THEN NULL ELSE AirDateUtc END) AS PreviousAiringString FROM Episodes"; } diff --git a/src/UI/Series/SeriesCollection.js b/src/UI/Series/SeriesCollection.js index 8bc23630e..45fb8dc2b 100644 --- a/src/UI/Series/SeriesCollection.js +++ b/src/UI/Series/SeriesCollection.js @@ -59,12 +59,18 @@ define( //Sorters nextAiring: function (model, attr) { var nextAiring = model.get(attr); - - if (!nextAiring) { - return Number.MAX_VALUE; + + if (nextAiring) { + return Moment(nextAiring).unix(); + } + + var previousAiring = model.get(attr.replace('nextAiring', 'previousAiring')); + + if (previousAiring) { + return 10000000000 - Moment(previousAiring).unix(); } - return Moment(nextAiring).unix(); + return Number.MAX_VALUE; } });