Esempio n. 1
0
        public bool ShouldRefresh(Series series)
        {
            if (series.LastInfoSync < DateTime.UtcNow.AddDays(-30))
            {
                _logger.Trace("Series {0} last updated more than 30 days ago, should refresh.", series.Title);
                return(true);
            }

            if (series.LastInfoSync >= DateTime.UtcNow.AddHours(-6))
            {
                _logger.Trace("Series {0} last updated less than 6 hours ago, should not be refreshed.", series.Title);
                return(false);
            }

            if (series.Status != SeriesStatusType.Ended)
            {
                _logger.Trace("Series {0} is not ended, should refresh.", series.Title);
                return(true);
            }

            var lastEpisode = _episodeService.GetEpisodeBySeries(series.Id).OrderByDescending(e => e.AirDateUtc).FirstOrDefault();

            if (lastEpisode != null && lastEpisode.AirDateUtc > DateTime.UtcNow.AddDays(-30))
            {
                _logger.Trace("Last episode in {0} aired less than 30 days ago, should refresh.", series.Title);
                return(true);
            }

            _logger.Trace("Series {0} ended long ago, should not be refreshed.", series.Title);
            return(false);
        }
Esempio n. 2
0
        public void Execute(MissingEpisodeSearchCommand message)
        {
            List <Episode> episodes;

            if (message.SeriesId.HasValue)
            {
                episodes = _episodeService.GetEpisodeBySeries(message.SeriesId.Value)
                           .Where(e => e.Monitored &&
                                  !e.HasFile &&
                                  e.AirDateUtc.HasValue &&
                                  e.AirDateUtc.Value.Before(DateTime.UtcNow))
                           .ToList();
            }

            else
            {
                episodes = _episodeService.EpisodesWithoutFiles(new PagingSpec <Episode>
                {
                    Page             = 1,
                    PageSize         = 100000,
                    SortDirection    = SortDirection.Ascending,
                    SortKey          = "Id",
                    FilterExpression =
                        v =>
                        v.Monitored == true &&
                        v.Series.Monitored == true
                }).Records.ToList();
            }

            var queue   = _queueService.GetQueue().Select(q => q.Episode.Id);
            var missing = episodes.Where(e => !queue.Contains(e.Id)).ToList();

            SearchForMissingEpisodes(missing);
        }
Esempio n. 3
0
        private void PerformUpdate(Series series)
        {
            _logger.Debug("Updating scene numbering mapping for: {0}", series);

            try
            {
                var mappings = _xemProxy.GetSceneTvdbMappings(series.TvdbId);

                if (!mappings.Any() && !series.UseSceneNumbering)
                {
                    _logger.Debug("Mappings for: {0} are empty, skipping", series);
                    _cache.Remove(series.TvdbId.ToString());
                    return;
                }

                var episodes = _episodeService.GetEpisodeBySeries(series.Id);

                foreach (var episode in episodes)
                {
                    episode.SceneAbsoluteEpisodeNumber = null;
                    episode.SceneSeasonNumber          = null;
                    episode.SceneEpisodeNumber         = null;
                    episode.UnverifiedSceneNumbering   = false;
                }

                foreach (var mapping in mappings)
                {
                    _logger.Debug("Setting scene numbering mappings for {0} S{1:00}E{2:00}", series, mapping.Tvdb.Season, mapping.Tvdb.Episode);

                    var episode = episodes.SingleOrDefault(e => e.SeasonNumber == mapping.Tvdb.Season && e.EpisodeNumber == mapping.Tvdb.Episode);

                    if (episode == null)
                    {
                        _logger.Debug("Information hasn't been added to TheTVDB yet, skipping.");
                        continue;
                    }

                    episode.SceneAbsoluteEpisodeNumber = mapping.Scene.Absolute;
                    episode.SceneSeasonNumber          = mapping.Scene.Season;
                    episode.SceneEpisodeNumber         = mapping.Scene.Episode;
                }

                if (episodes.Any(v => v.SceneEpisodeNumber.HasValue && v.SceneSeasonNumber != 0))
                {
                    ExtrapolateMappings(series, episodes, mappings);
                }

                _episodeService.UpdateEpisodes(episodes);
                series.UseSceneNumbering = mappings.Any();
                _seriesService.UpdateSeries(series);

                _logger.Debug("XEM mapping updated for {0}", series);
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error updating scene numbering mappings for: " + series, ex);
            }
        }
        public void Execute(CleanMediaFileDb message)
        {
            var seriesFile = _mediaFileService.GetFilesBySeries(message.SeriesId);
            var series     = _seriesService.GetSeries(message.SeriesId);
            var episodes   = _episodeService.GetEpisodeBySeries(message.SeriesId);

            foreach (var episodeFile in seriesFile)
            {
                try
                {
                    if (!_diskProvider.FileExists(episodeFile.Path))
                    {
                        _logger.Trace("File [{0}] no longer exists on disk, removing from db", episodeFile.Path);
                        _mediaFileService.Delete(episodeFile);
                        continue;
                    }

                    if (!_diskProvider.IsParent(series.Path, episodeFile.Path))
                    {
                        _logger.Trace("File [{0}] does not belong to this series, removing from db", episodeFile.Path);
                        _mediaFileService.Delete(episodeFile);
                        continue;
                    }

                    if (!episodes.Any(e => e.EpisodeFileId == episodeFile.Id))
                    {
                        _logger.Trace("File [{0}] is not assigned to any episodes, removing from db", episodeFile.Path);
                        _mediaFileService.Delete(episodeFile);
                        continue;
                    }

//                    var localEpsiode = _parsingService.GetEpisodes(episodeFile.Path, series);
//
//                    if (localEpsiode == null || episodes.Count != localEpsiode.Episodes.Count)
//                    {
//                        _logger.Trace("File [{0}] parsed episodes has changed, removing from db", episodeFile.Path);
//                        _mediaFileService.Delete(episodeFile);
//                        continue;
//                    }
                }

                catch (Exception ex)
                {
                    var errorMessage = String.Format("Unable to cleanup EpisodeFile in DB: {0}", episodeFile.Id);
                    _logger.ErrorException(errorMessage, ex);
                }
            }

            foreach (var episode in episodes)
            {
                if (episode.EpisodeFileId > 0 && !seriesFile.Any(f => f.Id == episode.EpisodeFileId))
                {
                    episode.EpisodeFileId = 0;
                    _episodeService.UpdateEpisode(episode);
                }
            }
        }
        public void Clean(Series series, List <string> filesOnDisk)
        {
            var seriesFiles = _mediaFileService.GetFilesBySeries(series.Id);
            var episodes    = _episodeService.GetEpisodeBySeries(series.Id);

            var filesOnDiskKeys = new HashSet <string>(filesOnDisk, PathEqualityComparer.Instance);

            foreach (var seriesFile in seriesFiles)
            {
                var episodeFile     = seriesFile;
                var episodeFilePath = Path.Combine(series.Path, episodeFile.RelativePath);

                try
                {
                    if (!filesOnDiskKeys.Contains(episodeFilePath))
                    {
                        _logger.Debug("File [{0}] no longer exists on disk, removing from db", episodeFilePath);
                        _mediaFileService.Delete(seriesFile, DeleteMediaFileReason.MissingFromDisk);
                        continue;
                    }

                    if (episodes.None(e => e.EpisodeFileId == episodeFile.Id))
                    {
                        _logger.Debug("File [{0}] is not assigned to any episodes, removing from db", episodeFilePath);
                        _mediaFileService.Delete(episodeFile, DeleteMediaFileReason.NoLinkedEpisodes);
                        continue;
                    }

//                    var localEpsiode = _parsingService.GetLocalEpisode(episodeFile.Path, series);
//
//                    if (localEpsiode == null || episodes.Count != localEpsiode.Episodes.Count)
//                    {
//                        _logger.Debug("File [{0}] parsed episodes has changed, removing from db", episodeFile.Path);
//                        _mediaFileService.Delete(episodeFile);
//                        continue;
//                    }
                }

                catch (Exception ex)
                {
                    var errorMessage = string.Format("Unable to cleanup EpisodeFile in DB: {0}", episodeFile.Id);
                    _logger.Error(ex, errorMessage);
                }
            }

            foreach (var e in episodes)
            {
                var episode = e;

                if (episode.EpisodeFileId > 0 && seriesFiles.None(f => f.Id == episode.EpisodeFileId))
                {
                    episode.EpisodeFileId = 0;
                    _episodeService.UpdateEpisode(episode);
                }
            }
        }
Esempio n. 6
0
        public List <RenameEpisodeFilePreview> GetRenamePreviews(int seriesId)
        {
            var series   = _seriesService.GetSeries(seriesId);
            var episodes = _episodeService.GetEpisodeBySeries(seriesId);
            var files    = _mediaFileService.GetFilesBySeries(seriesId);

            return(GetPreviews(series, episodes, files)
                   .OrderByDescending(e => e.SeasonNumber)
                   .ThenByDescending(e => e.EpisodeNumbers.First())
                   .ToList());
        }
Esempio n. 7
0
        private List <EpisodeResource> GetEpisodes()
        {
            var seriesId = (int?)Request.Query.SeriesId;

            if (seriesId == null)
            {
                throw new BadRequestException("seriesId is missing");
            }

            return(ToListResource(() => _episodeService.GetEpisodeBySeries(seriesId.Value)));
        }
Esempio n. 8
0
        private List <EpisodeFile> GetEpisodeFiles(int seriesId)
        {
            var episodeFiles = _mediaFileService.GetFilesBySeries(seriesId);
            var episodes     = _episodeService.GetEpisodeBySeries(seriesId);

            foreach (var episodeFile in episodeFiles)
            {
                var localEpisodeFile = episodeFile;
                episodeFile.Episodes = new LazyList <Episode>(episodes.Where(e => e.EpisodeFileId == localEpisodeFile.Id));
            }

            return(episodeFiles);
        }
Esempio n. 9
0
        private void PerformUpdate(Series series)
        {
            _logger.Trace("Updating scene numbering mapping for: {0}", series);
            try
            {
                var episodesToUpdate = new List <Episode>();
                var mappings         = _xemProxy.GetSceneTvdbMappings(series.TvdbId);

                if (!mappings.Any())
                {
                    _logger.Trace("Mappings for: {0} are empty, skipping", series);
                    _cache.Remove(series.TvdbId.ToString());
                    return;
                }

                var episodes = _episodeService.GetEpisodeBySeries(series.Id);

                foreach (var mapping in mappings)
                {
                    _logger.Trace("Setting scene numbering mappings for {0} S{1:00}E{2:00}", series, mapping.Tvdb.Season, mapping.Tvdb.Episode);

                    var episode = episodes.SingleOrDefault(e => e.SeasonNumber == mapping.Tvdb.Season && e.EpisodeNumber == mapping.Tvdb.Episode);

                    if (episode == null)
                    {
                        _logger.Trace("Information hasn't been added to TheTVDB yet, skipping.");
                        continue;
                    }

                    episode.AbsoluteEpisodeNumber = mapping.Scene.Absolute;
                    episode.SceneSeasonNumber     = mapping.Scene.Season;
                    episode.SceneEpisodeNumber    = mapping.Scene.Episode;
                    episodesToUpdate.Add(episode);
                }

                _logger.Trace("Committing scene numbering mappings to database for: {0}", series);
                _episodeService.UpdateEpisodes(episodesToUpdate);

                _logger.Trace("Setting UseSceneMapping for {0}", series);
                series.UseSceneNumbering = true;
                _seriesService.UpdateSeries(series);
            }

            catch (Exception ex)
            {
                _logger.ErrorException("Error updating scene numbering mappings for: " + series, ex);
            }
        }
Esempio n. 10
0
        public void Execute(MissingEpisodeSearchCommand message)
        {
            var            monitored = message.Monitored;
            List <Episode> episodes;

            if (message.SeriesId.HasValue)
            {
                episodes = _episodeService.GetEpisodeBySeries(message.SeriesId.Value)
                           .Where(e => e.Monitored == monitored &&
                                  !e.HasFile &&
                                  e.AirDateUtc.HasValue &&
                                  e.AirDateUtc.Value.Before(DateTime.UtcNow))
                           .ToList();
            }

            else
            {
                var pagingSpec = new PagingSpec <Episode>
                {
                    Page          = 1,
                    PageSize      = 100000,
                    SortDirection = SortDirection.Ascending,
                    SortKey       = "Id"
                };

                if (monitored)
                {
                    pagingSpec.FilterExpressions.Add(v => v.Monitored == true && v.Series.Monitored == true);
                }
                else
                {
                    pagingSpec.FilterExpressions.Add(v => v.Monitored == false || v.Series.Monitored == false);
                }

                episodes = _episodeService.EpisodesWithoutFiles(pagingSpec).Records.ToList();
            }

            var queue   = _queueService.GetQueue().Where(q => q.Episode != null).Select(q => q.Episode.Id);
            var missing = episodes.Where(e => !queue.Contains(e.Id)).ToList();

            SearchForEpisodes(missing, monitored, message.Trigger == CommandTrigger.Manual);
        }
Esempio n. 11
0
        private void HandleScanEvents(Series series)
        {
            if (series.AddOptions == null)
            {
                return;
            }

            _logger.Info("[{0}] was recently added, performing post-add actions", series.Title);

            var episodes = _episodeService.GetEpisodeBySeries(series.Id);

            SetEpisodeMonitoredStatus(series, episodes);

            if (series.AddOptions.SearchForMissingEpisodes)
            {
                _commandExecutor.PublishCommand(new MissingEpisodeSearchCommand(series.Id));
            }

            series.AddOptions = null;
            _seriesService.RemoveAddOptions(series);
        }
Esempio n. 12
0
        public void RefreshEpisodeInfo(Series series, IEnumerable <Episode> remoteEpisodes)
        {
            _logger.Info("Starting episode info refresh for: {0}", series);
            var successCount = 0;
            var failCount    = 0;

            var existingEpisodes = _episodeService.GetEpisodeBySeries(series.Id);
            var seasons          = series.Seasons;

            var updateList             = new List <Episode>();
            var newList                = new List <Episode>();
            var dupeFreeRemoteEpisodes = remoteEpisodes.DistinctBy(m => new { m.SeasonNumber, m.EpisodeNumber }).ToList();

            if (series.SeriesType == SeriesTypes.Anime)
            {
                dupeFreeRemoteEpisodes = MapAbsoluteEpisodeNumbers(dupeFreeRemoteEpisodes);
            }

            foreach (var episode in OrderEpisodes(series, dupeFreeRemoteEpisodes))
            {
                try
                {
                    var episodeToUpdate = GetEpisodeToUpdate(series, episode, existingEpisodes);

                    if (episodeToUpdate != null)
                    {
                        existingEpisodes.Remove(episodeToUpdate);
                        updateList.Add(episodeToUpdate);
                    }
                    else
                    {
                        episodeToUpdate           = new Episode();
                        episodeToUpdate.Monitored = GetMonitoredStatus(episode, seasons);
                        newList.Add(episodeToUpdate);
                    }

                    episodeToUpdate.SeriesId              = series.Id;
                    episodeToUpdate.EpisodeNumber         = episode.EpisodeNumber;
                    episodeToUpdate.SeasonNumber          = episode.SeasonNumber;
                    episodeToUpdate.AbsoluteEpisodeNumber = episode.AbsoluteEpisodeNumber;
                    episodeToUpdate.Title      = episode.Title ?? "TBA";
                    episodeToUpdate.Overview   = episode.Overview;
                    episodeToUpdate.AirDate    = episode.AirDate;
                    episodeToUpdate.AirDateUtc = episode.AirDateUtc;
                    episodeToUpdate.Ratings    = episode.Ratings;
                    episodeToUpdate.Images     = episode.Images;

                    successCount++;
                }
                catch (Exception e)
                {
                    _logger.Fatal(e, "An error has occurred while updating episode info for series {0}. {1}", series, episode);
                    failCount++;
                }
            }

            var allEpisodes = new List <Episode>();

            allEpisodes.AddRange(newList);
            allEpisodes.AddRange(updateList);

            AdjustMultiEpisodeAirTime(series, allEpisodes);
            AdjustDirectToDvdAirDate(series, allEpisodes);

            _episodeService.DeleteMany(existingEpisodes);
            _episodeService.UpdateMany(updateList);
            _episodeService.InsertMany(newList);

            _eventAggregator.PublishEvent(new EpisodeInfoRefreshedEvent(series, newList, updateList));

            if (failCount != 0)
            {
                _logger.Info("Finished episode refresh for series: {0}. Successful: {1} - Failed: {2} ",
                             series.Title, successCount, failCount);
            }
            else
            {
                _logger.Info("Finished episode refresh for series: {0}.", series);
            }
        }
Esempio n. 13
0
        public void SetEpisodeMonitoredStatus(Series series, MonitoringOptions monitoringOptions)
        {
            if (monitoringOptions != null)
            {
                _logger.Debug("[{0}] Setting episode monitored status.", series.Title);

                var episodes = _episodeService.GetEpisodeBySeries(series.Id);

                if (monitoringOptions.IgnoreEpisodesWithFiles)
                {
                    _logger.Debug("Unmonitoring Episodes with Files");
                    ToggleEpisodesMonitoredState(episodes.Where(e => e.HasFile), false);
                }
                else
                {
                    _logger.Debug("Monitoring Episodes with Files");
                    ToggleEpisodesMonitoredState(episodes.Where(e => e.HasFile), true);
                }

                if (monitoringOptions.IgnoreEpisodesWithoutFiles)
                {
                    _logger.Debug("Unmonitoring Episodes without Files");
                    ToggleEpisodesMonitoredState(episodes.Where(e => !e.HasFile && e.AirDateUtc.HasValue && e.AirDateUtc.Value.Before(DateTime.UtcNow)), false);
                }
                else
                {
                    _logger.Debug("Monitoring Episodes without Files");
                    ToggleEpisodesMonitoredState(episodes.Where(e => !e.HasFile && e.AirDateUtc.HasValue && e.AirDateUtc.Value.Before(DateTime.UtcNow)), true);
                }

                var lastSeason = series.Seasons.Select(s => s.SeasonNumber).MaxOrDefault();

                foreach (var s in series.Seasons)
                {
                    var season = s;

                    // If the season is unmonitored we should unmonitor all episodes in that season

                    if (!season.Monitored)
                    {
                        _logger.Debug("Unmonitoring all episodes in season {0}", season.SeasonNumber);
                        ToggleEpisodesMonitoredState(episodes.Where(e => e.SeasonNumber == season.SeasonNumber), false);
                    }

                    // If the season is not the latest season and all it's episodes are unmonitored the season will be unmonitored

                    if (season.SeasonNumber < lastSeason)
                    {
                        if (episodes.Where(e => e.SeasonNumber == season.SeasonNumber).All(e => !e.Monitored))
                        {
                            _logger.Debug("Unmonitoring season {0} because all episodes are not monitored", season.SeasonNumber);
                            season.Monitored = false;
                        }
                    }
                }

                _episodeService.UpdateEpisodes(episodes);
            }

            _seriesService.UpdateSeries(series, false);
        }
        public void SetEpisodeMonitoredStatus(Series series, MonitoringOptions monitoringOptions)
        {
            // Update the series without changing the episodes
            if (monitoringOptions == null)
            {
                _seriesService.UpdateSeries(series, false);
                return;
            }

            // Fallback for v2 endpoints
            if (monitoringOptions.Monitor == MonitorTypes.Unknown)
            {
                LegacySetEpisodeMonitoredStatus(series, monitoringOptions);
                return;
            }

            var firstSeason = series.Seasons.Select(s => s.SeasonNumber).Where(s => s > 0).MinOrDefault();
            var lastSeason  = series.Seasons.Select(s => s.SeasonNumber).MaxOrDefault();
            var episodes    = _episodeService.GetEpisodeBySeries(series.Id);

            switch (monitoringOptions.Monitor)
            {
            case MonitorTypes.All:
                _logger.Debug("[{0}] Monitoring all episodes", series.Title);
                ToggleEpisodesMonitoredState(episodes, e => e.SeasonNumber > 0);

                break;

            case MonitorTypes.Future:
                _logger.Debug("[{0}] Monitoring future episodes", series.Title);
                ToggleEpisodesMonitoredState(episodes, e => e.SeasonNumber > 0 && (!e.AirDateUtc.HasValue || e.AirDateUtc >= DateTime.UtcNow));

                break;

            case MonitorTypes.Missing:
                _logger.Debug("[{0}] Monitoring missing episodes", series.Title);
                ToggleEpisodesMonitoredState(episodes, e => e.SeasonNumber > 0 && !e.HasFile);

                break;

            case MonitorTypes.Existing:
                _logger.Debug("[{0}] Monitoring existing episodes", series.Title);
                ToggleEpisodesMonitoredState(episodes, e => e.SeasonNumber > 0 && e.HasFile);

                break;

            case MonitorTypes.Pilot:
                _logger.Debug("[{0}] Monitoring first episode episodes", series.Title);
                ToggleEpisodesMonitoredState(episodes,
                                             e => e.SeasonNumber > 0 && e.SeasonNumber == firstSeason && e.EpisodeNumber == 1);

                break;

            case MonitorTypes.FirstSeason:
                _logger.Debug("[{0}] Monitoring first season episodes", series.Title);
                ToggleEpisodesMonitoredState(episodes, e => e.SeasonNumber > 0 && e.SeasonNumber == firstSeason);

                break;

            case MonitorTypes.LatestSeason:
                if (episodes.Where(e => e.SeasonNumber == lastSeason)
                    .All(e => e.AirDateUtc.HasValue &&
                         e.AirDateUtc.Value.Before(DateTime.UtcNow) &&
                         !e.AirDateUtc.Value.InLastDays(90)))
                {
                    _logger.Debug("[{0}] Unmonitoring all episodes because latest season aired more than 90 days ago", series.Title);
                    ToggleEpisodesMonitoredState(episodes, e => false);
                    break;
                }

                _logger.Debug("[{0}] Monitoring latest season episodes", series.Title);

                ToggleEpisodesMonitoredState(episodes, e => e.SeasonNumber > 0 && e.SeasonNumber == lastSeason);

                break;

            case MonitorTypes.None:
                _logger.Debug("[{0}] Unmonitoring all episodes", series.Title);
                ToggleEpisodesMonitoredState(episodes, e => false);

                break;
            }

            var monitoredSeasons = episodes.Where(e => e.Monitored)
                                   .Select(e => e.SeasonNumber)
                                   .Distinct()
                                   .ToList();

            foreach (var season in series.Seasons)
            {
                var seasonNumber = season.SeasonNumber;

                // Monitor the season when:
                // - Not specials
                // - The latest season
                // - Not only supposed to monitor the first season
                if (seasonNumber > 0 &&
                    seasonNumber == lastSeason &&
                    monitoringOptions.Monitor != MonitorTypes.FirstSeason &&
                    monitoringOptions.Monitor != MonitorTypes.Pilot &&
                    monitoringOptions.Monitor != MonitorTypes.None)
                {
                    season.Monitored = true;
                }
                // Don't monitor season 1 if only the pilot episode is monitored
                else if (seasonNumber == firstSeason && monitoringOptions.Monitor == MonitorTypes.Pilot)
                {
                    season.Monitored = false;
                }
                // Monitor the season if it has any monitor episodes
                else if (monitoredSeasons.Contains(seasonNumber))
                {
                    season.Monitored = true;
                }
                // Don't monitor the season
                else
                {
                    season.Monitored = false;
                }
            }

            _episodeService.UpdateEpisodes(episodes);
            _seriesService.UpdateSeries(series, false);
        }
Esempio n. 15
0
        public void RefreshEpisodeInfo(Series series, IEnumerable <Episode> remoteEpisodes)
        {
            _logger.Info("Starting episode info refresh for: {0}", series);
            var successCount = 0;
            var failCount    = 0;

            var existingEpisodes = _episodeService.GetEpisodeBySeries(series.Id);
            var seasons          = series.Seasons;

            var updateList             = new List <Episode>();
            var newList                = new List <Episode>();
            var dupeFreeRemoteEpisodes = remoteEpisodes.DistinctBy(m => new { m.SeasonNumber, m.EpisodeNumber }).ToList();

            foreach (var episode in dupeFreeRemoteEpisodes.OrderBy(e => e.SeasonNumber).ThenBy(e => e.EpisodeNumber))
            {
                try
                {
                    var episodeToUpdate = existingEpisodes.FirstOrDefault(e => e.SeasonNumber == episode.SeasonNumber && e.EpisodeNumber == episode.EpisodeNumber);

                    if (episodeToUpdate != null)
                    {
                        existingEpisodes.Remove(episodeToUpdate);
                        updateList.Add(episodeToUpdate);
                    }
                    else
                    {
                        episodeToUpdate           = new Episode();
                        episodeToUpdate.Monitored = GetMonitoredStatus(episode, seasons);
                        newList.Add(episodeToUpdate);
                    }

                    episodeToUpdate.SeriesId      = series.Id;
                    episodeToUpdate.EpisodeNumber = episode.EpisodeNumber;
                    episodeToUpdate.SeasonNumber  = episode.SeasonNumber;
                    episodeToUpdate.Title         = episode.Title;
                    episodeToUpdate.Overview      = episode.Overview;
                    episodeToUpdate.AirDate       = episode.AirDate;
                    episodeToUpdate.AirDateUtc    = episode.AirDateUtc;
                    episodeToUpdate.Ratings       = episode.Ratings;
                    episodeToUpdate.Images        = episode.Images;

                    successCount++;
                }
                catch (Exception e)
                {
                    _logger.FatalException(String.Format("An error has occurred while updating episode info for series {0}. {1}", series, episode), e);
                    failCount++;
                }
            }

            var allEpisodes = new List <Episode>();

            allEpisodes.AddRange(newList);
            allEpisodes.AddRange(updateList);

            AdjustMultiEpisodeAirTime(series, allEpisodes);
            SetAbsoluteEpisodeNumber(allEpisodes);

            _episodeService.DeleteMany(existingEpisodes);
            _episodeService.UpdateMany(updateList);
            _episodeService.InsertMany(newList);

            if (newList.Any())
            {
                _eventAggregator.PublishEvent(new EpisodeInfoAddedEvent(newList, series));
            }

            if (updateList.Any())
            {
                _eventAggregator.PublishEvent(new EpisodeInfoUpdatedEvent(updateList));
            }

            if (existingEpisodes.Any())
            {
                _eventAggregator.PublishEvent(new EpisodeInfoDeletedEvent(updateList));
            }

            if (failCount != 0)
            {
                _logger.Info("Finished episode refresh for series: {0}. Successful: {1} - Failed: {2} ",
                             series.Title, successCount, failCount);
            }
            else
            {
                _logger.Info("Finished episode refresh for series: {0}.", series);
            }
        }
        public void SetEpisodeMonitoredStatus(Series series, MonitoringOptions monitoringOptions)
        {
            if (monitoringOptions != null)
            {
                _logger.Debug("[{0}] Setting episode monitored status.", series.Title);

                var episodes = _episodeService.GetEpisodeBySeries(series.Id);

                if (monitoringOptions.IgnoreEpisodesWithFiles)
                {
                    _logger.Debug("Ignoring Episodes with Files");
                    ToggleEpisodesMonitoredState(episodes.Where(e => e.HasFile), false);
                }

                else
                {
                    _logger.Debug("Monitoring Episodes with Files");
                    ToggleEpisodesMonitoredState(episodes.Where(e => e.HasFile), true);
                }

                if (monitoringOptions.IgnoreEpisodesWithoutFiles)
                {
                    _logger.Debug("Ignoring Episodes without Files");
                    ToggleEpisodesMonitoredState(episodes.Where(e => !e.HasFile && e.AirDateUtc.HasValue && e.AirDateUtc.Value.Before(DateTime.UtcNow)), false);
                }

                else
                {
                    _logger.Debug("Monitoring Episodes without Files");
                    ToggleEpisodesMonitoredState(episodes.Where(e => !e.HasFile && e.AirDateUtc.HasValue && e.AirDateUtc.Value.Before(DateTime.UtcNow)), true);
                }

                var lastSeason = series.Seasons.Select(s => s.SeasonNumber).MaxOrDefault();

                foreach (var s in series.Seasons)
                {
                    var season = s;

                    if (season.Monitored)
                    {
                        if (!monitoringOptions.IgnoreEpisodesWithFiles && !monitoringOptions.IgnoreEpisodesWithoutFiles)
                        {
                            ToggleEpisodesMonitoredState(episodes.Where(e => e.SeasonNumber == season.SeasonNumber), true);
                        }
                    }

                    else
                    {
                        if (!monitoringOptions.IgnoreEpisodesWithFiles && !monitoringOptions.IgnoreEpisodesWithoutFiles)
                        {
                            ToggleEpisodesMonitoredState(episodes.Where(e => e.SeasonNumber == season.SeasonNumber), false);
                        }

                        else if (season.SeasonNumber == 0)
                        {
                            ToggleEpisodesMonitoredState(episodes.Where(e => e.SeasonNumber == season.SeasonNumber), false);
                        }
                    }

                    if (season.SeasonNumber < lastSeason)
                    {
                        if (episodes.Where(e => e.SeasonNumber == season.SeasonNumber).All(e => !e.Monitored))
                        {
                            season.Monitored = false;
                        }
                    }
                }

                _episodeService.UpdateEpisodes(episodes);
            }

            _seriesService.UpdateSeries(series);
        }