New: Show disk space used by series on series details

pull/4/head
Mark McDowall 10 years ago
parent 6712c79143
commit 807ed7df1a

@ -160,6 +160,7 @@ namespace NzbDrone.Api.Series
resource.EpisodeFileCount = seriesStatistics.EpisodeFileCount; resource.EpisodeFileCount = seriesStatistics.EpisodeFileCount;
resource.NextAiring = seriesStatistics.NextAiring; resource.NextAiring = seriesStatistics.NextAiring;
resource.PreviousAiring = seriesStatistics.PreviousAiring; resource.PreviousAiring = seriesStatistics.PreviousAiring;
resource.SizeOnDisk = seriesStatistics.SizeOnDisk;
} }
private void PopulateAlternateTitles(List<SeriesResource> resources) private void PopulateAlternateTitles(List<SeriesResource> resources)

@ -31,6 +31,7 @@ namespace NzbDrone.Api.Series
public Int32 EpisodeCount { get; set; } public Int32 EpisodeCount { get; set; }
public Int32 EpisodeFileCount { get; set; } public Int32 EpisodeFileCount { get; set; }
public Int64 SizeOnDisk { get; set; }
public SeriesStatusType Status { get; set; } public SeriesStatusType Status { get; set; }
public String ProfileName { get; set; } public String ProfileName { get; set; }
public String Overview { get; set; } public String Overview { get; set; }

@ -3,6 +3,8 @@ using System.Linq;
using FizzWare.NBuilder; using FizzWare.NBuilder;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.SeriesStats; using NzbDrone.Core.SeriesStats;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
@ -14,24 +16,29 @@ namespace NzbDrone.Core.Test.SeriesStatsTests
{ {
private Series _series; private Series _series;
private Episode _episode; private Episode _episode;
private EpisodeFile _episodeFile;
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
_series = Builder<Series>.CreateNew() _series = Builder<Series>.CreateNew()
.With(s => s.Id = 0)
.With(s => s.Runtime = 30) .With(s => s.Runtime = 30)
.Build(); .BuildNew();
_series.Id = Db.Insert(_series).Id; _series.Id = Db.Insert(_series).Id;
_episode = Builder<Episode>.CreateNew() _episode = Builder<Episode>.CreateNew()
.With(e => e.Id = 0)
.With(e => e.EpisodeFileId = 0) .With(e => e.EpisodeFileId = 0)
.With(e => e.Monitored = false) .With(e => e.Monitored = false)
.With(e => e.SeriesId = _series.Id) .With(e => e.SeriesId = _series.Id)
.With(e => e.AirDateUtc = DateTime.Today.AddDays(5)) .With(e => e.AirDateUtc = DateTime.Today.AddDays(5))
.Build(); .BuildNew();
_episodeFile = Builder<EpisodeFile>.CreateNew()
.With(e => e.SeriesId = _series.Id)
.With(e => e.Quality = new QualityModel(Quality.HDTV720p))
.BuildNew();
} }
private void GivenEpisodeWithFile() private void GivenEpisodeWithFile()
@ -49,16 +56,21 @@ namespace NzbDrone.Core.Test.SeriesStatsTests
_episode.Monitored = true; _episode.Monitored = true;
} }
private void GivenFile() private void GivenEpisode()
{ {
Db.Insert(_episode); Db.Insert(_episode);
} }
private void GivenEpisodeFile()
{
Db.Insert(_episodeFile);
}
[Test] [Test]
public void should_get_stats_for_series() public void should_get_stats_for_series()
{ {
GivenMonitoredEpisode(); GivenMonitoredEpisode();
GivenFile(); GivenEpisode();
var stats = Subject.SeriesStatistics(); var stats = Subject.SeriesStatistics();
@ -71,7 +83,7 @@ namespace NzbDrone.Core.Test.SeriesStatsTests
public void should_not_have_next_airing_for_episode_with_file() public void should_not_have_next_airing_for_episode_with_file()
{ {
GivenEpisodeWithFile(); GivenEpisodeWithFile();
GivenFile(); GivenEpisode();
var stats = Subject.SeriesStatistics(); var stats = Subject.SeriesStatistics();
@ -84,7 +96,7 @@ namespace NzbDrone.Core.Test.SeriesStatsTests
{ {
GivenEpisodeWithFile(); GivenEpisodeWithFile();
GivenOldEpisode(); GivenOldEpisode();
GivenFile(); GivenEpisode();
var stats = Subject.SeriesStatistics(); var stats = Subject.SeriesStatistics();
@ -98,7 +110,7 @@ namespace NzbDrone.Core.Test.SeriesStatsTests
{ {
GivenMonitoredEpisode(); GivenMonitoredEpisode();
GivenOldEpisode(); GivenOldEpisode();
GivenFile(); GivenEpisode();
var stats = Subject.SeriesStatistics(); var stats = Subject.SeriesStatistics();
@ -111,7 +123,7 @@ namespace NzbDrone.Core.Test.SeriesStatsTests
public void should_not_have_previous_airing_for_old_episode_without_file_unmonitored() public void should_not_have_previous_airing_for_old_episode_without_file_unmonitored()
{ {
GivenOldEpisode(); GivenOldEpisode();
GivenFile(); GivenEpisode();
var stats = Subject.SeriesStatistics(); var stats = Subject.SeriesStatistics();
@ -123,7 +135,7 @@ namespace NzbDrone.Core.Test.SeriesStatsTests
[Test] [Test]
public void should_not_include_unmonitored_episode_in_episode_count() public void should_not_include_unmonitored_episode_in_episode_count()
{ {
GivenFile(); GivenEpisode();
var stats = Subject.SeriesStatistics(); var stats = Subject.SeriesStatistics();
@ -135,12 +147,36 @@ namespace NzbDrone.Core.Test.SeriesStatsTests
public void should_include_unmonitored_episode_with_file_in_episode_count() public void should_include_unmonitored_episode_with_file_in_episode_count()
{ {
GivenEpisodeWithFile(); GivenEpisodeWithFile();
GivenFile(); GivenEpisode();
var stats = Subject.SeriesStatistics(); var stats = Subject.SeriesStatistics();
stats.Should().HaveCount(1); stats.Should().HaveCount(1);
stats.First().EpisodeCount.Should().Be(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);
}
} }
} }

@ -21,6 +21,7 @@ namespace NzbDrone.Core.MediaFiles
List<string> FilterExistingFiles(List<string> files, Series series); List<string> FilterExistingFiles(List<string> files, Series series);
EpisodeFile Get(int id); EpisodeFile Get(int id);
List<EpisodeFile> Get(IEnumerable<int> ids); List<EpisodeFile> Get(IEnumerable<int> ids);
} }
public class MediaFileService : IMediaFileService, IHandleAsync<SeriesDeletedEvent> public class MediaFileService : IMediaFileService, IHandleAsync<SeriesDeletedEvent>

@ -5,11 +5,12 @@ namespace NzbDrone.Core.SeriesStats
{ {
public class SeriesStatistics : ResultSet public class SeriesStatistics : ResultSet
{ {
public int SeriesId { get; set; } public Int32 SeriesId { get; set; }
public string NextAiringString { get; set; } public String NextAiringString { get; set; }
public string PreviousAiringString { get; set; } public String PreviousAiringString { get; set; }
public int EpisodeFileCount { get; set; } public Int32 EpisodeFileCount { get; set; }
public int EpisodeCount { get; set; } public Int32 EpisodeCount { get; set; }
public Int64 SizeOnDisk { get; set; }
public DateTime? NextAiring public DateTime? NextAiring
{ {

@ -8,7 +8,7 @@ namespace NzbDrone.Core.SeriesStats
public interface ISeriesStatisticsRepository public interface ISeriesStatisticsRepository
{ {
List<SeriesStatistics> SeriesStatistics(); List<SeriesStatistics> SeriesStatistics();
SeriesStatistics SeriesStatistics(int seriesId); SeriesStatistics SeriesStatistics(Int32 seriesId);
} }
public class SeriesStatisticsRepository : ISeriesStatisticsRepository public class SeriesStatisticsRepository : ISeriesStatisticsRepository
@ -28,13 +28,14 @@ namespace NzbDrone.Core.SeriesStats
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.AppendLine(GetSelectClause()); sb.AppendLine(GetSelectClause());
sb.AppendLine(GetEpisodeFilesJoin());
sb.AppendLine(GetGroupByClause()); sb.AppendLine(GetGroupByClause());
var queryText = sb.ToString(); var queryText = sb.ToString();
return mapper.Query<SeriesStatistics>(queryText); return mapper.Query<SeriesStatistics>(queryText);
} }
public SeriesStatistics SeriesStatistics(int seriesId) public SeriesStatistics SeriesStatistics(Int32 seriesId)
{ {
var mapper = _database.GetDataMapper(); var mapper = _database.GetDataMapper();
@ -43,27 +44,36 @@ namespace NzbDrone.Core.SeriesStats
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.AppendLine(GetSelectClause()); sb.AppendLine(GetSelectClause());
sb.AppendLine("WHERE SeriesId = @seriesId"); sb.AppendLine(GetEpisodeFilesJoin());
sb.AppendLine("WHERE Episodes.SeriesId = @seriesId");
sb.AppendLine(GetGroupByClause()); sb.AppendLine(GetGroupByClause());
var queryText = sb.ToString(); var queryText = sb.ToString();
return mapper.Find<SeriesStatistics>(queryText); return mapper.Find<SeriesStatistics>(queryText);
} }
private string GetSelectClause() private String GetSelectClause()
{ {
return @"SELECT return @"SELECT Episodes.*, SUM(EpisodeFiles.Size) as SizeOnDisk FROM
SeriesId, (SELECT
Episodes.SeriesId,
SUM(CASE WHEN (Monitored = 1 AND AirdateUtc <= @currentDate) OR EpisodeFileId > 0 THEN 1 ELSE 0 END) AS EpisodeCount, 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, 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 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";
} }
} }
} }

@ -4,6 +4,7 @@
<span class="label label-info">{{network}}</span> <span class="label label-info">{{network}}</span>
<span class="label label-info">{{runtime}} minutes</span> <span class="label label-info">{{runtime}} minutes</span>
<span class="label label-info">{{path}}</span> <span class="label label-info">{{path}}</span>
<span class="label label-info">{{Bytes sizeOnDisk}}</span>
{{#if_eq status compare="continuing"}} {{#if_eq status compare="continuing"}}
<span class="label label-info">Continuing</span> <span class="label label-info">Continuing</span>
{{else}} {{else}}

Loading…
Cancel
Save