public virtual void AddEpisode(Episode episode) { //If Season is ignored ignore this episode episode.Ignored = _seasonProvider.IsIgnored(episode.SeriesId, episode.SeasonNumber); _database.Insert(episode); }
public void Setup() { fakeSeries = Builder<Series>.CreateNew().Build(); fakeDailySeries = Builder<Series>.CreateNew() .With(c => c.IsDaily = true) .Build(); fakeEpisode = Builder<Episode>.CreateNew() .With(e => e.SeriesId = fakeSeries.SeriesId) .With(e => e.Title = "Episode (1)") .Build(); fakeEpisode2 = Builder<Episode>.CreateNew() .With(e => e.SeriesId = fakeSeries.SeriesId) .With(e => e.SeasonNumber = fakeEpisode.SeasonNumber) .With(e => e.EpisodeNumber = fakeEpisode.EpisodeNumber + 1) .With(e => e.Title = "Episode (2)") .Build(); fakeDailyEpisode = Builder<Episode>.CreateNew() .With(e => e.SeriesId = fakeSeries.SeriesId) .With(e => e.AirDate = DateTime.Now.Date) .With(e => e.Title = "Daily Episode 1") .Build(); WithRealDb(); episodeProvider = Mocker.Resolve<EpisodeProvider>(); }
public EpisodeFile MapIt(EpisodeFile episodeFile, Series series, Episode episode) { // Terminating call. Since we can return null from this function // we need to be ready for PetaPoco to callback later with null // parameters if (episodeFile == null) return _current; // Is this the same EpisodeFile as the current one we're processing if (_current != null && _current.EpisodeFileId == episodeFile.EpisodeFileId) { // Yes, just add this post to the current EpisodeFiles's collection of Episodes _current.Episodes.Add(episode); // Return null to indicate we're not done with this EpisodeFiles yet return null; } // This is a different EpisodeFile to the current one, or this is the // first time through and we don't have an EpisodeFile yet // Save the current EpisodeFile var prev = _current; // Setup the new current EpisodeFile _current = episodeFile; _current.Episodes = new List<Episode>(); _current.Episodes.Add(episode); _current.Series = series; // Return the now populated previous EpisodeFile (or null if first time through) return prev; }
public virtual string ConvertFile(Episode episode, ProgressNotification notification) { _notification = notification; _currentEpisode = episode; var outputFile = _configProvider.GetValue("iPodConvertDir", ""); var handBrakePreset = _configProvider.GetValue("HandBrakePreset", "iPhone & iPod Touch"); var handBrakeCommand = String.Format("-i \"{0}\" -o \"{1}\" --preset=\"{2}\"", episode.EpisodeFile.Path, outputFile, handBrakePreset); var handBrakeFile = @"C:\Program Files (x86)\Handbrake\HandBrakeCLI.exe"; try { var process = new Process(); process.StartInfo.FileName = handBrakeFile; process.StartInfo.Arguments = handBrakeCommand; process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; process.StartInfo.RedirectStandardOutput = true; process.OutputDataReceived += new DataReceivedEventHandler(HandBrakeOutputDataReceived); process.Start(); process.BeginOutputReadLine(); process.WaitForExit(); } catch (Exception ex) { Logger.DebugException(ex.Message, ex); return String.Empty; } return outputFile; }
public void Setup() { _customStartDateSpecification = Mocker.Resolve<CustomStartDateSpecification>(); firstEpisode = new Episode { AirDate = DateTime.Today }; secondEpisode = new Episode { AirDate = DateTime.Today }; fakeSeries = Builder<Series>.CreateNew() .With(c => c.Monitored = true) .With(c => c.CustomStartDate = null) .Build(); parseResultMulti = new EpisodeParseResult { SeriesTitle = "Title", Series = fakeSeries, EpisodeNumbers = new List<int> { 3, 4 }, SeasonNumber = 12, Episodes = new List<Episode> { firstEpisode, secondEpisode } }; parseResultSingle = new EpisodeParseResult { SeriesTitle = "Title", Series = fakeSeries, EpisodeNumbers = new List<int> { 3 }, SeasonNumber = 12, Episodes = new List<Episode> { firstEpisode } }; }
public void Setup() { _series = Builder<Series> .CreateNew() .Build(); _episode = Builder<Episode> .CreateNew() .With(e => e.SeriesId = _series.SeriesId) .With(e => e.Series = _series) .Build(); _episodes = Builder<Episode> .CreateListOfSize(10) .All() .With(e => e.SeriesId = _series.SeriesId) .With(e => e.Series = _series) .Build() .ToList(); _parseResults = Builder<EpisodeParseResult> .CreateListOfSize(10) .Build(); _indexer1 = new Mock<IndexerBase>(); _indexer2 = new Mock<IndexerBase>(); _indexers = new List<IndexerBase> { _indexer1.Object, _indexer2.Object }; Mocker.GetMock<IndexerProvider>() .Setup(c => c.GetEnabledIndexers()) .Returns(_indexers); }
public void WithSceneNumbering() { _episode = Builder<Episode> .CreateNew() .With(e => e.SeriesId = _series.SeriesId) .Build(); Db.Insert(_episode); }
public void WithNullSceneNumbering() { _episode = Builder<Episode> .CreateNew() .With(e => e.SeriesId = _series.SeriesId) .Build(); Db.Insert(_episode); Db.Execute("UPDATE Episodes SET SceneSeasonNumber = NULL, SceneEpisodeNumber = NULL"); }
public void Setup() { _recentEpisode = Builder<Episode> .CreateNew() .With(e => e.AirDate = DateTime.Today) .Build(); _oldEpisode = Builder<Episode> .CreateNew() .With(e => e.AirDate = DateTime.Today.AddDays(-365)) .Build(); }
public virtual bool IsSatisfiedBy(Episode subject) { //Used to check if the existing episode can be upgraded by searching (Before we search) if (subject.EpisodeFileId == 0) return true; var profile = _qualityProvider.Get(subject.Series.QualityProfileId); //TODO:How about proper? if (subject.EpisodeFile.Quality >= profile.Cutoff) return false; return true; ; }
public void Setup() { _searchResults = Builder<TvRageSearchResult> .CreateListOfSize(5) .Build(); _series = Builder<Series> .CreateNew() .With(s => s.FirstAired = DateTime.Today.AddDays(-180)) .Build(); _episode = Builder<Episode> .CreateNew() .With(e => e.AirDate = DateTime.Today.AddDays(-365)) .Build(); }
public TvRageSearchResult ProcessResults(IList<TvRageSearchResult> searchResults, Series series, string sceneCleanName, Episode firstEpisode) { foreach (var result in searchResults) { if (Parser.NormalizeTitle(result.Name).Equals(series.CleanTitle)) return result; if (!String.IsNullOrWhiteSpace(sceneCleanName) && Parser.NormalizeTitle(result.Name).Equals(sceneCleanName)) return result; if (firstEpisode.AirDate.HasValue && result.Started == firstEpisode.AirDate.Value) return result; } return null; }
public void SetUp() { _series = Builder<Series>.CreateNew() .Build(); _episodeFile = Builder<EpisodeFile>.CreateNew() .With(f => f.Quality = QualityTypes.SDTV) .Build(); _episode = Builder<Episode>.CreateNew() .With(e => e.EpisodeFileId = 0) .With(e => e.SeriesId = _series.SeriesId) .With(e => e.Series = _series) .With(e => e.EpisodeFileId = _episodeFile.EpisodeFileId) .With(e => e.EpisodeFile = _episodeFile) .Build(); }
public void Setup() { _series = Builder<Series>.CreateNew() .Build(); _episode = Builder<Episode>.CreateNew() .Build(); var items = Builder<SearchHistoryItem>.CreateListOfSize(10) .All() .With(c => c.Quality = QualityTypes.SDTV) .Build().ToList(); _searchHistory = Builder<SearchHistory>.CreateNew() .With(h => h.EpisodeId = _episode.EpisodeId) .With(h => h.SeriesId - _series.SeriesId) .With(h => h.SearchHistoryItems = items) .Build(); }
public void Setup() { _series = Builder<Series> .CreateNew() .Build(); _episode = Builder<Episode> .CreateNew() .With(e => e.SeriesId = _series.SeriesId) .With(e => e.Series = _series) .Build(); _episodeParseResult = Builder<EpisodeParseResult> .CreateNew() .With(p => p.AirDate = _episode.AirDate) .With(p => p.Episodes = new List<Episode> { _episode }) .With(p => p.Series = _series) .Build(); _searchHistoryItem = new SearchHistoryItem(); }
public void Setup() { _searchResults = Builder<TvRageSearchResult> .CreateListOfSize(5) .Build(); _series = Builder<Series> .CreateNew() .With(s => s.TvRageId = 0) .With(s => s.TvRageTitle = null) .With(s => s.UtcOffset = 0) .With(s => s.FirstAired = DateTime.Today.AddDays(-180)) .Build(); _episode = Builder<Episode> .CreateNew() .With(e => e.AirDate = DateTime.Today.AddDays(-365)) .Build(); _tvRageSeries = Builder<TvRageSeries> .CreateNew() .With(s => s.UtcOffset = -8) .Build(); Mocker.GetMock<EpisodeProvider>() .Setup(s => s.GetEpisode(_series.SeriesId, 1, 1)) .Returns(_episode); Mocker.GetMock<SceneMappingProvider>() .Setup(s => s.GetCleanName(_series.SeriesId)) .Returns(""); Mocker.GetMock<TvRageProvider>() .Setup(s => s.SearchSeries(_series.Title)) .Returns(_searchResults); Mocker.GetMock<TvRageProvider>() .Setup(s => s.GetSeries(_searchResults.First().ShowId)) .Returns(_tvRageSeries); }
public void Setup() { monitoredEpisodeSpecification = Mocker.Resolve<MonitoredEpisodeSpecification>(); fakeSeries = Builder<Series>.CreateNew() .With(c => c.Monitored = true) .Build(); parseResultMulti = new EpisodeParseResult { SeriesTitle = "Title", Series = fakeSeries, EpisodeNumbers = new List<int> { 3, 4 }, SeasonNumber = 12, }; parseResultSingle = new EpisodeParseResult { SeriesTitle = "Title", Series = fakeSeries, EpisodeNumbers = new List<int> { 3 }, SeasonNumber = 12, }; firstEpisode = new Episode { Ignored = false }; secondEpisode = new Episode { Ignored = false }; var singleEpisodeList = new List<Episode> { firstEpisode }; var doubleEpisodeList = new List<Episode> { firstEpisode, secondEpisode }; Mocker.GetMock<EpisodeProvider>().Setup(c => c.GetEpisodesByParseResult(parseResultSingle)).Returns(singleEpisodeList); Mocker.GetMock<EpisodeProvider>().Setup(c => c.GetEpisodesByParseResult(parseResultMulti)).Returns(doubleEpisodeList); Mocker.GetMock<SeriesProvider>().Setup(c => c.FindSeries(parseResultMulti.CleanTitle)).Returns(fakeSeries); Mocker.GetMock<SeriesProvider>().Setup(c => c.FindSeries(parseResultSingle.CleanTitle)).Returns(fakeSeries); }
public Season MapIt(Season season, Episode episode, EpisodeFile episodeFile) { // Terminating call. Since we can return null from this function // we need to be ready for PetaPoco to callback later with null // parameters if (season == null) return _current; //Todo: Find a Query that doesn't require this check //Map EpisodeFile to Episode (Map to null if 0, because PetaPoco is returning a POCO when it should be null) episode.EpisodeFile = (episode.EpisodeFileId == 0 ? null : episodeFile); // Is this the same season as the current one we're processing if (_current != null && _current.SeasonId == season.SeasonId) { // Yes, just add this post to the current author's collection of posts _current.Episodes.Add(episode); // Return null to indicate we're not done with this author yet return null; } // This is season different author to the current one, or this is the // first time through and we don't have an season yet // Save the current author var prev = _current; // Setup the new current season _current = season; _current.Episodes = new List<Episode>(); _current.Episodes.Add(episode); // Return the now populated previous season (or null if first time through) return prev; }
public List<EpisodeParseResult> PerformDailyEpisodeSearch(Series series, Episode episode) { var reports = new List<EpisodeParseResult>(); var title = GetSeriesTitle(series); Parallel.ForEach(_indexerProvider.GetEnabledIndexers(), indexer => { try { logger.Trace("Episode {0} is a daily episode, searching as daily", episode); reports.AddRange(indexer.FetchDailyEpisode(title, episode.AirDate.Value)); } catch (Exception e) { logger.ErrorException(String.Format("An error has occurred while searching for {0}-{1} from: {2}", series.Title, episode.AirDate, indexer.Name), e); } }); return reports; }
public virtual void RefreshEpisodeInfo(Series series) { logger.Trace("Starting episode info refresh for series: {0}", series.Title.WithDefault(series.SeriesId)); int successCount = 0; int failCount = 0; var tvDbSeriesInfo = _tvDbProvider.GetSeries(series.SeriesId, true); var seriesEpisodes = GetEpisodeBySeries(series.SeriesId); var updateList = new List<Episode>(); var newList = new List<Episode>(); foreach (var episode in tvDbSeriesInfo.Episodes.OrderBy(e => e.SeasonNumber).ThenBy(e => e.EpisodeNumber)) { try { //skip episodes that are too far in the future and have no title. if ((episode.FirstAired > DateTime.Now.AddDays(2) || episode.FirstAired.Year < 1900) && string.IsNullOrWhiteSpace(episode.EpisodeName)) continue; logger.Trace("Updating info for [{0}] - S{1}E{2}", tvDbSeriesInfo.SeriesName, episode.SeasonNumber, episode.EpisodeNumber); //first check using tvdbId, this should cover cases when and episode number in a season is changed var episodeToUpdate = seriesEpisodes.SingleOrDefault(e => e.TvDbEpisodeId == episode.Id); //not found, try using season/episode number if (episodeToUpdate == null) { episodeToUpdate = seriesEpisodes.SingleOrDefault(e => e.SeasonNumber == episode.SeasonNumber && e.EpisodeNumber == episode.EpisodeNumber); } //Episode doesn't exist locally if (episodeToUpdate == null) { episodeToUpdate = new Episode(); newList.Add(episodeToUpdate); //If it is Episode Zero Ignore it, since it is new if (episode.EpisodeNumber == 0 && episode.SeasonNumber > 1) { episodeToUpdate.Ignored = true; } //Else we need to check if this episode should be ignored based on IsIgnored rules else { episodeToUpdate.Ignored = _seasonProvider.IsIgnored(series.SeriesId, episode.SeasonNumber); } } else { updateList.Add(episodeToUpdate); } episodeToUpdate.SeriesId = series.SeriesId; episodeToUpdate.TvDbEpisodeId = episode.Id; episodeToUpdate.EpisodeNumber = episode.EpisodeNumber; episodeToUpdate.SeasonNumber = episode.SeasonNumber; episodeToUpdate.Title = episode.EpisodeName; episodeToUpdate.Overview = episode.Overview; if (episode.FirstAired.Year > 1900) episodeToUpdate.AirDate = episode.FirstAired.Date; else episodeToUpdate.AirDate = null; successCount++; } catch (Exception e) { logger.FatalException( String.Format("An error has occurred while updating episode info for series {0}", tvDbSeriesInfo.SeriesName), e); failCount++; } } _database.InsertMany(newList); _database.UpdateMany(updateList); if (failCount != 0) { logger.Info("Finished episode refresh for series: {0}. Successful: {1} - Failed: {2} ", tvDbSeriesInfo.SeriesName, successCount, failCount); } else { logger.Info("Finished episode refresh for series: {0}.", tvDbSeriesInfo.SeriesName); } DeleteEpisodesNotInTvdb(series, tvDbSeriesInfo); }
public virtual void UpdateEpisode(Episode episode) { _database.Update(episode); }
public virtual void RefreshEpisodeInfo(Series series) { logger.Trace("Starting episode info refresh for series: {0}", series.Title.WithDefault(series.SeriesId)); var successCount = 0; var failCount = 0; var tvdbEpisodes = _tvDbProvider.GetSeries(series.SeriesId, true) .Episodes .Where(episode => !string.IsNullOrWhiteSpace(episode.EpisodeName) || (episode.FirstAired < DateTime.Now.AddDays(2) && episode.FirstAired.Year > 1900)) .ToList(); var seriesEpisodes = GetEpisodeBySeries(series.SeriesId); var updateList = new List<Episode>(); var newList = new List<Episode>(); _seasonProvider.EnsureSeasons(series.SeriesId, tvdbEpisodes.Select(c => c.SeasonNumber).Distinct()); foreach (var episode in tvdbEpisodes.OrderBy(e => e.SeasonNumber).ThenBy(e => e.EpisodeNumber)) { try { logger.Trace("Updating info for [{0}] - S{1:00}E{2:00}", series.Title, episode.SeasonNumber, episode.EpisodeNumber); //first check using tvdbId, this should cover cases when and episode number in a season is changed var episodeToUpdate = seriesEpisodes.SingleOrDefault(e => e.TvDbEpisodeId == episode.Id); //not found, try using season/episode number if (episodeToUpdate == null) { episodeToUpdate = seriesEpisodes.SingleOrDefault(e => e.SeasonNumber == episode.SeasonNumber && e.EpisodeNumber == episode.EpisodeNumber); } if (episodeToUpdate == null) { episodeToUpdate = new Episode(); newList.Add(episodeToUpdate); //If it is Episode Zero Ignore it (specials, sneak peeks.) if (episode.EpisodeNumber == 0 && episode.SeasonNumber != 1) { episodeToUpdate.Ignored = true; } else { episodeToUpdate.Ignored = _seasonProvider.IsIgnored(series.SeriesId, episode.SeasonNumber); } } else { updateList.Add(episodeToUpdate); } if ((episodeToUpdate.EpisodeNumber != episode.EpisodeNumber || episodeToUpdate.SeasonNumber != episode.SeasonNumber) && episodeToUpdate.EpisodeFileId > 0) { logger.Info("Unlinking episode file because TheTVDB changed the epsiode number..."); _database.Delete<EpisodeFile>(episodeToUpdate.EpisodeFileId); episodeToUpdate.EpisodeFileId = 0; } episodeToUpdate.SeriesId = series.SeriesId; episodeToUpdate.TvDbEpisodeId = episode.Id; episodeToUpdate.EpisodeNumber = episode.EpisodeNumber; episodeToUpdate.SeasonNumber = episode.SeasonNumber; episodeToUpdate.AbsoluteEpisodeNumber = episode.AbsoluteNumber; episodeToUpdate.Title = episode.EpisodeName; episodeToUpdate.Overview = episode.Overview.Truncate(3500); if (episode.FirstAired.Year > 1900) episodeToUpdate.AirDate = episode.FirstAired.Date; else episodeToUpdate.AirDate = null; successCount++; } catch (Exception e) { logger.FatalException(String.Format("An error has occurred while updating episode info for series {0}", series.Title), e); failCount++; } } _database.InsertMany(newList); _database.UpdateMany(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.Title); } DeleteEpisodesNotInTvdb(series, tvdbEpisodes); }
public virtual IList<Episode> GetEpisodesByParseResult(EpisodeParseResult parseResult) { //Disabling auto add, need to make it a lot more conservative. var autoAddNew = false; var result = new List<Episode>(); if (parseResult.AirDate.HasValue) { if (!parseResult.Series.IsDaily) { //Todo: Collect this as a Series we want to treat as a daily series, or possible parsing error logger.Warn("Found daily-style episode for non-daily series: {0}. {1}", parseResult.Series.Title, parseResult.OriginalString); return new List<Episode>(); } var episodeInfo = GetEpisode(parseResult.Series.SeriesId, parseResult.AirDate.Value); if (episodeInfo == null && autoAddNew) { logger.Info("Episode {0} doesn't exist in db. adding it now. {1}", parseResult, parseResult.OriginalString); episodeInfo = new Episode { SeriesId = parseResult.Series.SeriesId, AirDate = parseResult.AirDate.Value, Title = "TBD", Overview = String.Empty }; var episodesInSeries = GetEpisodeBySeries(parseResult.Series.SeriesId); //Find the current season number var maxSeasonNumber = episodesInSeries.Select(s => s.SeasonNumber).MaxOrDefault(); //Set the season number episodeInfo.SeasonNumber = (maxSeasonNumber == 0) ? 1 : maxSeasonNumber; //Find the latest episode number var maxEpisodeNumber = episodesInSeries .Where(w => w.SeasonNumber == episodeInfo.SeasonNumber) .Select(s => s.EpisodeNumber).MaxOrDefault(); //Set the episode number to max + 1 episodeInfo.EpisodeNumber = maxEpisodeNumber + 1; AddEpisode(episodeInfo); } if (episodeInfo != null) { result.Add(episodeInfo); parseResult.EpisodeTitle = episodeInfo.Title; } return result; } if (parseResult.EpisodeNumbers == null) return result; //Set it to empty before looping through the episode numbers parseResult.EpisodeTitle = String.Empty; foreach (var episodeNumber in parseResult.EpisodeNumbers) { Episode episodeInfo = null; if (parseResult.SceneSource && parseResult.Series.UseSceneNumbering) episodeInfo = GetEpisodeBySceneNumbering(parseResult.Series.SeriesId, parseResult.SeasonNumber, episodeNumber); if (episodeInfo == null) { episodeInfo = GetEpisode(parseResult.Series.SeriesId, parseResult.SeasonNumber, episodeNumber); if (episodeInfo == null && parseResult.AirDate != null) { episodeInfo = GetEpisode(parseResult.Series.SeriesId, parseResult.AirDate.Value); } } //if still null we should add the temp episode if (episodeInfo == null && autoAddNew) { logger.Info("Episode {0} doesn't exist in db. adding it now. {1}", parseResult, parseResult.OriginalString); episodeInfo = new Episode { SeriesId = parseResult.Series.SeriesId, AirDate = DateTime.Now.Date, EpisodeNumber = episodeNumber, SeasonNumber = parseResult.SeasonNumber, Title = "TBD", Overview = String.Empty, }; if (parseResult.EpisodeNumbers.Count == 1 && parseResult.EpisodeNumbers.First() == 0) episodeInfo.Ignored = true; AddEpisode(episodeInfo); } if (episodeInfo != null) { result.Add(episodeInfo); if (parseResult.Series.UseSceneNumbering) { logger.Info("Using Scene to TVDB Mapping for: {0} - Scene: {1}x{2:00} - TVDB: {3}x{4:00}", parseResult.Series.Title, episodeInfo.SceneSeasonNumber, episodeInfo.SceneEpisodeNumber, episodeInfo.SeasonNumber, episodeInfo.EpisodeNumber); } if (parseResult.EpisodeNumbers.Count == 1) { parseResult.EpisodeTitle = episodeInfo.Title.Trim(); } else { parseResult.EpisodeTitle = Parser.CleanupEpisodeTitle(episodeInfo.Title); } } else { logger.Debug("Unable to find {0}", parseResult); } } return result; }
private void VerifyEpisode(Episode actual, Episode excpected) { actual.ShouldHave().AllProperties().But(e => e.Series).But(e => e.EpisodeFile).EqualTo(excpected); }
private static void VerifyFileImport(EpisodeFile result, AutoMoqer Mocker, Episode fakeEpisode, int size) { Mocker.VerifyAllMocks(); result.Should().NotBeNull(); result.SeriesId.Should().Be(fakeEpisode.SeriesId); result.Size.Should().Be(size); result.DateAdded.Should().HaveDay(DateTime.Now.Day); Mocker.GetMock<MediaFileProvider>().Verify(p => p.Add(It.IsAny<EpisodeFile>()), Times.Once()); //Get the count of episodes linked var count = Mocker.GetMock<EpisodeProvider>().Object.GetEpisodesByParseResult(null).Count; Mocker.GetMock<EpisodeProvider>().Verify(p => p.UpdateEpisode(It.Is<Episode>(e => e.EpisodeFileId == result.EpisodeFileId)), Times.Exactly(count)); }