mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-16 11:37:58 +02:00
New: Show disk space used by series on series details
This commit is contained in:
parent
6712c79143
commit
807ed7df1a
@ -160,6 +160,7 @@ private void LinkSeriesStatistics(SeriesResource resource, SeriesStatistics seri
|
|||||||
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 @@ public Int32 SeasonCount
|
|||||||
|
|
||||||
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 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 @@ public class SeriesStatisticsFixture : DbTest<SeriesStatisticsRepository, Series
|
|||||||
{
|
{
|
||||||
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 @@ private void GivenMonitoredEpisode()
|
|||||||
_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 @@ public void should_get_stats_for_series()
|
|||||||
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 @@ public void should_have_previous_airing_for_old_episode_with_file()
|
|||||||
{
|
{
|
||||||
GivenEpisodeWithFile();
|
GivenEpisodeWithFile();
|
||||||
GivenOldEpisode();
|
GivenOldEpisode();
|
||||||
GivenFile();
|
GivenEpisode();
|
||||||
|
|
||||||
var stats = Subject.SeriesStatistics();
|
var stats = Subject.SeriesStatistics();
|
||||||
|
|
||||||
@ -98,7 +110,7 @@ public void should_have_previous_airing_for_old_episode_without_file_monitored()
|
|||||||
{
|
{
|
||||||
GivenMonitoredEpisode();
|
GivenMonitoredEpisode();
|
||||||
GivenOldEpisode();
|
GivenOldEpisode();
|
||||||
GivenFile();
|
GivenEpisode();
|
||||||
|
|
||||||
var stats = Subject.SeriesStatistics();
|
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()
|
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 @@ public void should_not_have_previous_airing_for_old_episode_without_file_unmonit
|
|||||||
[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 @@ public void should_not_include_unmonitored_episode_in_episode_count()
|
|||||||
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 @@ public interface IMediaFileService
|
|||||||
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 @@ public List<SeriesStatistics> SeriesStatistics()
|
|||||||
|
|
||||||
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 @@ public SeriesStatistics SeriesStatistics(int seriesId)
|
|||||||
|
|
||||||
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…
Reference in New Issue
Block a user