Added SeriesStatistics

This commit is contained in:
Mark McDowall 2013-04-20 13:09:12 -07:00
parent 979efb8354
commit f86cb87ced
8 changed files with 60 additions and 4 deletions

View File

@ -31,8 +31,20 @@ namespace NzbDrone.Api.Series
private Response AllSeries() private Response AllSeries()
{ {
var series = _seriesService.GetAllSeries().ToList(); var series = _seriesService.GetAllSeries().ToList();
var seriesStats = _seriesService.SeriesStatistics();
var seriesModels = Mapper.Map<List<Core.Tv.Series>, List<SeriesResource>>(series); var seriesModels = Mapper.Map<List<Core.Tv.Series>, List<SeriesResource>>(series);
foreach (var s in seriesModels)
{
var stats = seriesStats.SingleOrDefault(ss => ss.SeriesId == s.Id);
if (stats == null) continue;
s.EpisodeCount = stats.EpisodeCount;
s.EpisodeFileCount = stats.EpisodeFileCount;
s.NumberOfSeasons = stats.NumberOfSeasons;
s.NextAiring = stats.NextAiring;
}
return seriesModels.AsResponse(); return seriesModels.AsResponse();
} }

View File

@ -21,12 +21,12 @@ namespace NzbDrone.Api.Series
public String Overview { get; set; } public String Overview { get; set; }
public Int32 Episodes { get; set; } public Int32 Episodes { get; set; }
public Boolean HasBanner { get; set; } public Boolean HasBanner { get; set; }
public DateTime NextAiring { get; set; } public DateTime? NextAiring { get; set; }
public String Details { get; set; } public String Details { get; set; }
public String Network { get; set; } public String Network { get; set; }
public String AirTime { get; set; } public String AirTime { get; set; }
public String Language { get; set; } public String Language { get; set; }
public Int32 SeasonCount { get; set; } public Int32 NumberOfSeasons { get; set; }
public Int32 UtcOffset { get; set; } public Int32 UtcOffset { get; set; }
public List<Core.MediaCover.MediaCover> Images { get; set; } public List<Core.MediaCover.MediaCover> Images { get; set; }

View File

@ -56,6 +56,10 @@ namespace NzbDrone.Core.Datastore
Mapper.Entity<QualitySize>().RegisterModel("QualitySizes"); Mapper.Entity<QualitySize>().RegisterModel("QualitySizes");
Mapper.Entity<Log>().RegisterModel("Logs"); Mapper.Entity<Log>().RegisterModel("Logs");
Mapper.Entity<SeriesStatistics>()
.Columns
.AutoMapPropertiesWhere(MappingExtensions.IsMappableProperty);
} }

View File

@ -386,6 +386,7 @@
<Compile Include="Providers\RecycleBinProvider.cs" /> <Compile Include="Providers\RecycleBinProvider.cs" />
<Compile Include="Tv\SeasonService.cs" /> <Compile Include="Tv\SeasonService.cs" />
<Compile Include="Instrumentation\TrimLogsJob.cs" /> <Compile Include="Instrumentation\TrimLogsJob.cs" />
<Compile Include="Tv\SeriesStatistics.cs" />
<Compile Include="Update\AppUpdateJob.cs" /> <Compile Include="Update\AppUpdateJob.cs" />
<Compile Include="Model\Xbmc\TvShowResponse.cs" /> <Compile Include="Model\Xbmc\TvShowResponse.cs" />
<Compile Include="Model\Xbmc\TvShow.cs" /> <Compile Include="Model\Xbmc\TvShow.cs" />

View File

@ -13,13 +13,17 @@ namespace NzbDrone.Core.Tv
Series FindByTvdbId(int tvdbId); Series FindByTvdbId(int tvdbId);
void SetSeriesType(int seriesId, SeriesTypes seriesTypes); void SetSeriesType(int seriesId, SeriesTypes seriesTypes);
void SetTvRageId(int seriesId, int tvRageId); void SetTvRageId(int seriesId, int tvRageId);
List<SeriesStatistics> SeriesStatistics();
} }
public class SeriesRepository : BasicRepository<Series>, ISeriesRepository public class SeriesRepository : BasicRepository<Series>, ISeriesRepository
{ {
private readonly IDatabase _database;
public SeriesRepository(IDatabase database) public SeriesRepository(IDatabase database)
: base(database) : base(database)
{ {
_database = database;
} }
public bool SeriesPathExists(string path) public bool SeriesPathExists(string path)
@ -51,5 +55,22 @@ namespace NzbDrone.Core.Tv
{ {
SetFields(new Series { Id = seriesId, TvRageId = tvRageId }, s => s.TvRageId); SetFields(new Series { Id = seriesId, TvRageId = tvRageId }, s => s.TvRageId);
} }
public List<SeriesStatistics> SeriesStatistics()
{
_database.DataMapper.AddParameter("currentDate", DateTime.UtcNow);
var queryText = @"SELECT
SeriesId,
SUM(CASE WHEN Airdate <= @currentDate THEN 1 ELSE 0 END) AS EpisodeCount,
SUM(CASE WHEN EpisodeFileId > 0 AND AirDate <= @currentDate THEN 1 ELSE 0 END) as EpisodeFileCount,
MAX(SeasonNumber) as NumberOfSeasons,
MIN(CASE WHEN AirDate < @currentDate THEN NULL ELSE AirDate END) as NextAiring
FROM Episodes
WHERE Ignored = 0
GROUP BY SeriesId";
return _database.DataMapper.Query<SeriesStatistics>(queryText);
}
} }
} }

View File

@ -33,6 +33,7 @@ namespace NzbDrone.Core.Tv
void UpdateSeries(Series series); void UpdateSeries(Series series);
bool SeriesPathExists(string folder); bool SeriesPathExists(string folder);
List<Series> GetSeriesInList(IEnumerable<int> seriesIds); List<Series> GetSeriesInList(IEnumerable<int> seriesIds);
List<SeriesStatistics> SeriesStatistics();
} }
public class SeriesService : ISeriesService, IHandleAsync<SeriesAddedEvent> public class SeriesService : ISeriesService, IHandleAsync<SeriesAddedEvent>
@ -58,7 +59,6 @@ namespace NzbDrone.Core.Tv
_logger = logger; _logger = logger;
} }
public bool IsMonitored(int id) public bool IsMonitored(int id)
{ {
return _seriesRepository.Get(id).Monitored; return _seriesRepository.Get(id).Monitored;
@ -179,6 +179,11 @@ namespace NzbDrone.Core.Tv
return _seriesRepository.Get(seriesIds).ToList(); return _seriesRepository.Get(seriesIds).ToList();
} }
public List<SeriesStatistics> SeriesStatistics()
{
return _seriesRepository.SeriesStatistics();
}
public void HandleAsync(SeriesAddedEvent message) public void HandleAsync(SeriesAddedEvent message)
{ {
UpdateSeriesInfo(message.Series.Id); UpdateSeriesInfo(message.Series.Id);

View File

@ -0,0 +1,13 @@
using System;
namespace NzbDrone.Core.Tv
{
public class SeriesStatistics
{
public int SeriesId { get; set; }
public int NumberOfSeasons { get; set; }
public DateTime? NextAiring { get; set; }
public int EpisodeFileCount { get; set; }
public int EpisodeCount { get; set; }
}
}

View File

@ -1,6 +1,6 @@
<td>{{{formatStatus status monitored}}}</td> <td>{{{formatStatus status monitored}}}</td>
<td><a href="/series/details/{{id}}">{{title}}</a></td> <td><a href="/series/details/{{id}}">{{title}}</a></td>
<td name="seasonCount"></td> <td name="numberOfSeasons"></td>
<td name="qualityProfileName"></td> <td name="qualityProfileName"></td>
<td name="network"></td> <td name="network"></td>
<!-- If only DT could access the backbone model --> <!-- If only DT could access the backbone model -->