From 807ed7df1a18c6dc043a349d983ab06729c0dd19 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 16 Aug 2014 23:43:50 -0700 Subject: [PATCH] New: Show disk space used by series on series details --- src/NzbDrone.Api/Series/SeriesModule.cs | 1 + src/NzbDrone.Api/Series/SeriesResource.cs | 1 + .../SeriesStatisticsFixture.cs | 60 +++++++++++++++---- .../MediaFiles/MediaFileService.cs | 1 + .../SeriesStats/SeriesStatistics.cs | 11 ++-- .../SeriesStats/SeriesStatisticsRepository.cs | 28 ++++++--- src/UI/Series/Details/InfoViewTemplate.html | 1 + 7 files changed, 77 insertions(+), 26 deletions(-) diff --git a/src/NzbDrone.Api/Series/SeriesModule.cs b/src/NzbDrone.Api/Series/SeriesModule.cs index 78c4a2e80..add57172e 100644 --- a/src/NzbDrone.Api/Series/SeriesModule.cs +++ b/src/NzbDrone.Api/Series/SeriesModule.cs @@ -160,6 +160,7 @@ private void LinkSeriesStatistics(SeriesResource resource, SeriesStatistics seri resource.EpisodeFileCount = seriesStatistics.EpisodeFileCount; resource.NextAiring = seriesStatistics.NextAiring; resource.PreviousAiring = seriesStatistics.PreviousAiring; + resource.SizeOnDisk = seriesStatistics.SizeOnDisk; } private void PopulateAlternateTitles(List resources) diff --git a/src/NzbDrone.Api/Series/SeriesResource.cs b/src/NzbDrone.Api/Series/SeriesResource.cs index 39ee26e0a..596714983 100644 --- a/src/NzbDrone.Api/Series/SeriesResource.cs +++ b/src/NzbDrone.Api/Series/SeriesResource.cs @@ -31,6 +31,7 @@ public Int32 SeasonCount public Int32 EpisodeCount { get; set; } public Int32 EpisodeFileCount { get; set; } + public Int64 SizeOnDisk { get; set; } public SeriesStatusType Status { get; set; } public String ProfileName { get; set; } public String Overview { get; set; } diff --git a/src/NzbDrone.Core.Test/SeriesStatsTests/SeriesStatisticsFixture.cs b/src/NzbDrone.Core.Test/SeriesStatsTests/SeriesStatisticsFixture.cs index 1172daff2..c8a321bc6 100644 --- a/src/NzbDrone.Core.Test/SeriesStatsTests/SeriesStatisticsFixture.cs +++ b/src/NzbDrone.Core.Test/SeriesStatsTests/SeriesStatisticsFixture.cs @@ -3,6 +3,8 @@ using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; +using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.Qualities; using NzbDrone.Core.SeriesStats; using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Tv; @@ -14,24 +16,29 @@ public class SeriesStatisticsFixture : DbTest.CreateNew() - .With(s => s.Id = 0) .With(s => s.Runtime = 30) - .Build(); + .BuildNew(); _series.Id = Db.Insert(_series).Id; _episode = Builder.CreateNew() - .With(e => e.Id = 0) .With(e => e.EpisodeFileId = 0) .With(e => e.Monitored = false) .With(e => e.SeriesId = _series.Id) .With(e => e.AirDateUtc = DateTime.Today.AddDays(5)) - .Build(); + .BuildNew(); + + _episodeFile = Builder.CreateNew() + .With(e => e.SeriesId = _series.Id) + .With(e => e.Quality = new QualityModel(Quality.HDTV720p)) + .BuildNew(); + } private void GivenEpisodeWithFile() @@ -49,16 +56,21 @@ private void GivenMonitoredEpisode() _episode.Monitored = true; } - private void GivenFile() + private void GivenEpisode() { Db.Insert(_episode); } + private void GivenEpisodeFile() + { + Db.Insert(_episodeFile); + } + [Test] public void should_get_stats_for_series() { GivenMonitoredEpisode(); - GivenFile(); + GivenEpisode(); var stats = Subject.SeriesStatistics(); @@ -71,7 +83,7 @@ public void should_get_stats_for_series() public void should_not_have_next_airing_for_episode_with_file() { GivenEpisodeWithFile(); - GivenFile(); + GivenEpisode(); var stats = Subject.SeriesStatistics(); @@ -84,7 +96,7 @@ public void should_have_previous_airing_for_old_episode_with_file() { GivenEpisodeWithFile(); GivenOldEpisode(); - GivenFile(); + GivenEpisode(); var stats = Subject.SeriesStatistics(); @@ -98,7 +110,7 @@ public void should_have_previous_airing_for_old_episode_without_file_monitored() { GivenMonitoredEpisode(); GivenOldEpisode(); - GivenFile(); + GivenEpisode(); var stats = Subject.SeriesStatistics(); @@ -111,7 +123,7 @@ public void should_have_previous_airing_for_old_episode_without_file_monitored() public void should_not_have_previous_airing_for_old_episode_without_file_unmonitored() { GivenOldEpisode(); - GivenFile(); + GivenEpisode(); var stats = Subject.SeriesStatistics(); @@ -123,7 +135,7 @@ public void should_not_have_previous_airing_for_old_episode_without_file_unmonit [Test] public void should_not_include_unmonitored_episode_in_episode_count() { - GivenFile(); + GivenEpisode(); var stats = Subject.SeriesStatistics(); @@ -135,12 +147,36 @@ public void should_not_include_unmonitored_episode_in_episode_count() public void should_include_unmonitored_episode_with_file_in_episode_count() { GivenEpisodeWithFile(); - GivenFile(); + GivenEpisode(); var stats = Subject.SeriesStatistics(); stats.Should().HaveCount(1); stats.First().EpisodeCount.Should().Be(1); } + + [Test] + public void should_have_size_on_disk_of_zero_when_no_episode_file() + { + GivenEpisode(); + + var stats = Subject.SeriesStatistics(); + + stats.Should().HaveCount(1); + stats.First().SizeOnDisk.Should().Be(0); + } + + [Test] + public void should_have_size_on_disk_when_episode_file_exists() + { + GivenEpisode(); + GivenEpisodeFile(); + + var stats = Subject.SeriesStatistics(); + + stats.Should().HaveCount(1); + stats.First().SizeOnDisk.Should().Be(_episodeFile.Size); + } + } } diff --git a/src/NzbDrone.Core/MediaFiles/MediaFileService.cs b/src/NzbDrone.Core/MediaFiles/MediaFileService.cs index 5fef9e220..9e155cdf5 100644 --- a/src/NzbDrone.Core/MediaFiles/MediaFileService.cs +++ b/src/NzbDrone.Core/MediaFiles/MediaFileService.cs @@ -21,6 +21,7 @@ public interface IMediaFileService List FilterExistingFiles(List files, Series series); EpisodeFile Get(int id); List Get(IEnumerable ids); + } public class MediaFileService : IMediaFileService, IHandleAsync diff --git a/src/NzbDrone.Core/SeriesStats/SeriesStatistics.cs b/src/NzbDrone.Core/SeriesStats/SeriesStatistics.cs index e43fb7c64..38989a907 100644 --- a/src/NzbDrone.Core/SeriesStats/SeriesStatistics.cs +++ b/src/NzbDrone.Core/SeriesStats/SeriesStatistics.cs @@ -5,11 +5,12 @@ namespace NzbDrone.Core.SeriesStats { public class SeriesStatistics : ResultSet { - 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; } + public Int32 SeriesId { get; set; } + public String NextAiringString { get; set; } + public String PreviousAiringString { get; set; } + public Int32 EpisodeFileCount { get; set; } + public Int32 EpisodeCount { get; set; } + public Int64 SizeOnDisk { get; set; } public DateTime? NextAiring { diff --git a/src/NzbDrone.Core/SeriesStats/SeriesStatisticsRepository.cs b/src/NzbDrone.Core/SeriesStats/SeriesStatisticsRepository.cs index 683736f77..9f4bc6059 100644 --- a/src/NzbDrone.Core/SeriesStats/SeriesStatisticsRepository.cs +++ b/src/NzbDrone.Core/SeriesStats/SeriesStatisticsRepository.cs @@ -8,7 +8,7 @@ namespace NzbDrone.Core.SeriesStats public interface ISeriesStatisticsRepository { List SeriesStatistics(); - SeriesStatistics SeriesStatistics(int seriesId); + SeriesStatistics SeriesStatistics(Int32 seriesId); } public class SeriesStatisticsRepository : ISeriesStatisticsRepository @@ -28,13 +28,14 @@ public List SeriesStatistics() var sb = new StringBuilder(); sb.AppendLine(GetSelectClause()); + sb.AppendLine(GetEpisodeFilesJoin()); sb.AppendLine(GetGroupByClause()); var queryText = sb.ToString(); return mapper.Query(queryText); } - public SeriesStatistics SeriesStatistics(int seriesId) + public SeriesStatistics SeriesStatistics(Int32 seriesId) { var mapper = _database.GetDataMapper(); @@ -43,27 +44,36 @@ public SeriesStatistics SeriesStatistics(int seriesId) var sb = new StringBuilder(); sb.AppendLine(GetSelectClause()); - sb.AppendLine("WHERE SeriesId = @seriesId"); + sb.AppendLine(GetEpisodeFilesJoin()); + sb.AppendLine("WHERE Episodes.SeriesId = @seriesId"); sb.AppendLine(GetGroupByClause()); var queryText = sb.ToString(); return mapper.Find(queryText); } - private string GetSelectClause() + private String GetSelectClause() { - return @"SELECT - SeriesId, + return @"SELECT Episodes.*, SUM(EpisodeFiles.Size) as SizeOnDisk FROM + (SELECT + Episodes.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, MAX(CASE WHEN AirDateUtc >= @currentDate OR EpisodeFileId = 0 AND Monitored = 0 THEN NULL ELSE AirDateUtc END) AS PreviousAiringString - FROM Episodes"; + FROM Episodes + GROUP BY Episodes.SeriesId) as Episodes"; } - private string GetGroupByClause() + private String GetGroupByClause() { - return "GROUP BY SeriesId"; + return "GROUP BY Episodes.SeriesId"; + } + + private String GetEpisodeFilesJoin() + { + return @"LEFT OUTER JOIN EpisodeFiles + ON EpisodeFiles.SeriesId = Episodes.SeriesId"; } } } diff --git a/src/UI/Series/Details/InfoViewTemplate.html b/src/UI/Series/Details/InfoViewTemplate.html index 9a5f81071..df6e18f2f 100644 --- a/src/UI/Series/Details/InfoViewTemplate.html +++ b/src/UI/Series/Details/InfoViewTemplate.html @@ -4,6 +4,7 @@ {{network}} {{runtime}} minutes {{path}} + {{Bytes sizeOnDisk}} {{#if_eq status compare="continuing"}} Continuing {{else}}