You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Readarr/NzbDrone.Core/Tv/SeasonService.cs

166 lines
9.6 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Tv.Events;
namespace NzbDrone.Core.Tv
{
public interface ISeasonService
{
void SetMonitored(int seriesId, int seasonNumber, bool monitored);
List<Season> SetSeasonPass(int seriesId, int seasonNumber);
List<Season> GetSeasonsBySeries(int seriesId);
List<Season> GetAllSeasons();
Season Get(int id);
}
public class SeasonService : ISeasonService,
IHandle<EpisodeInfoAddedEvent>,
IHandle<EpisodeInfoUpdatedEvent>,
IHandle<EpisodeInfoDeletedEvent>,
IHandleAsync<SeriesDeletedEvent>
{
private readonly ISeasonRepository _seasonRepository;
private readonly IEpisodeService _episodeService;
private readonly Logger _logger;
public SeasonService(ISeasonRepository seasonRepository, IEpisodeService episodeService, Logger logger)
{
_seasonRepository = seasonRepository;
_episodeService = episodeService;
_logger = logger;
}
public void SetMonitored(int seriesId, int seasonNumber, bool monitored)
{
var season = _seasonRepository.Get(seriesId, seasonNumber);
_logger.Trace("Setting monitored flag on Series:{0} Season:{1} to {2}", seriesId, seasonNumber, monitored);
season.Monitored = monitored;
_episodeService.SetEpisodeMonitoredBySeason(seriesId, seasonNumber, monitored);
_seasonRepository.Update(season);
_logger.Info("Monitored flag for Series:{0} Season:{1} successfully set to {2}", seriesId, seasonNumber, monitored);
}
public List<Season> SetSeasonPass(int seriesId, int seasonNumber)
{
_logger.Trace("Setting up Season Pass for {0} starting with season: {0}", seriesId, seasonNumber);
var seasons = GetSeasonsBySeries(seriesId);
foreach (var season in seasons)
{
if (season.SeasonNumber >= seasonNumber)
{
_logger.Trace("Setting monitored flag on Series:{0} Season:{1} to {2}", seriesId, seasonNumber, true);
season.Monitored = true;
_episodeService.SetEpisodeMonitoredBySeason(seriesId, season.SeasonNumber, true);
}
else
{
_logger.Trace("Setting monitored flag on Series:{0} Season:{1} to {2}", seriesId, seasonNumber, false);
season.Monitored = false;
_episodeService.SetEpisodeMonitoredBySeason(seriesId, season.SeasonNumber, false);
}
}
_seasonRepository.UpdateMany(seasons);
_logger.Trace("Season Pass set for {0} starting with season: {0}", seriesId, seasonNumber);
return seasons;
}
public List<Season> GetSeasonsBySeries(int seriesId)
{
return _seasonRepository.GetSeasonBySeries(seriesId);
}
public List<Season> GetAllSeasons()
{
return _seasonRepository.All().ToList();
}
public Season Get(int id)
{
return _seasonRepository.Get(id);
}
private void EnsureSeasons(IEnumerable<Episode> episodes)
{
var seriesGroup = episodes.GroupBy(c => c.SeriesId);
foreach (var group in seriesGroup)
{
var seriesId = group.Key;
var existingSeasons = _seasonRepository.GetSeasonNumbers(seriesId);
var seasonNumbers = group.Select(c => c.SeasonNumber).Distinct();
var missingSeasons = seasonNumbers.Where(seasonNumber => !existingSeasons.Contains(seasonNumber));
var seasonToAdd = missingSeasons.Select(c => new Season()
{
SeriesId = seriesId,
SeasonNumber = c,
Monitored = true
});
_seasonRepository.InsertMany(seasonToAdd.ToList());
}
}
private void RemoveOrphanedSeasons(IEnumerable<Episode> episodes)
{
var seriesGroup = episodes.GroupBy(c => c.SeriesId);
foreach (var group in seriesGroup)
{
var deletedEpisodesSeasons = group.Select(c => c.SeasonNumber).Distinct();
var seriesId = group.Key;
var seasons = _seasonRepository.GetSeasonBySeries(seriesId);
foreach (var deletedEpisodesSeason in deletedEpisodesSeasons)
{
if (!_episodeService.GetEpisodesBySeason(seriesId, deletedEpisodesSeason).Any())
{
var season = seasons.SingleOrDefault(s => s.SeasonNumber == deletedEpisodesSeason);
if (season == null)
{
continue;
}
_seasonRepository.Delete(season);
}
}
}
}
public void Handle(EpisodeInfoAddedEvent message)
{
EnsureSeasons(message.Episodes);
}
public void Handle(EpisodeInfoUpdatedEvent message)
{
EnsureSeasons(message.Episodes);
}
public void Handle(EpisodeInfoDeletedEvent message)
{
RemoveOrphanedSeasons(message.Episodes);
}
public void HandleAsync(SeriesDeletedEvent message)
{
var seasons = GetSeasonsBySeries(message.Series.Id);
_seasonRepository.DeleteMany(seasons);
}
}
}