public virtual bool IsSatisfiedBy(EpisodeParseResult subject) { var series = _seriesProvider.FindSeries(subject.CleanTitle); if (series == null) { logger.Trace("{0} is not mapped to any series in DB. skipping", subject.CleanTitle); return false; } subject.Series = series; if (!series.Monitored) { logger.Debug("{0} is present in the DB but not tracked. skipping.", subject.CleanTitle); return false; } var episodes = _episodeProvider.GetEpisodesByParseResult(subject); //return monitored if any of the episodes are monitored if (episodes.Any(episode => !episode.Ignored)) { return true; } logger.Debug("All episodes are ignored. skipping."); return false; }
public void Setup() { Mocker.Resolve<QualityUpgradeSpecification>(); _upgradeDisk = Mocker.Resolve<UpgradeDiskSpecification>(); firstFile = new EpisodeFile { Quality = QualityTypes.Bluray1080p, Proper = true }; secondFile = new EpisodeFile { Quality = QualityTypes.Bluray1080p, Proper = true }; var singleEpisodeList = new List<Episode> { new Episode { EpisodeFile = firstFile }, new Episode { EpisodeFile = null } }; var doubleEpisodeList = new List<Episode> { new Episode { EpisodeFile = firstFile }, new Episode { EpisodeFile = secondFile }, new Episode { EpisodeFile = null } }; var fakeSeries = Builder<Series>.CreateNew() .With(c => c.QualityProfile = new QualityProfile { Cutoff = QualityTypes.Bluray1080p }) .Build(); parseResultMulti = new EpisodeParseResult { Series = fakeSeries, Quality = new QualityModel(QualityTypes.DVD, true), EpisodeNumbers = new List<int> { 3, 4 }, SeasonNumber = 12, Episodes = doubleEpisodeList }; parseResultSingle = new EpisodeParseResult { Series = fakeSeries, Quality = new QualityModel(QualityTypes.DVD, true), EpisodeNumbers = new List<int> { 3 }, SeasonNumber = 12, Episodes = singleEpisodeList }; }
public virtual bool IsInQueue(EpisodeParseResult newParseResult) { try { var queue = GetQueue().Where(c => c.ParseResult != null); var matchigTitle = queue.Where(q => String.Equals(q.ParseResult.CleanTitle, newParseResult.Series.CleanTitle, StringComparison.InvariantCultureIgnoreCase)); var matchingTitleWithQuality = matchigTitle.Where(q => q.ParseResult.Quality >= newParseResult.Quality); if (newParseResult.Series.IsDaily) { return matchingTitleWithQuality.Any(q => q.ParseResult.AirDate.Value.Date == newParseResult.AirDate.Value.Date); } var matchingSeason = matchingTitleWithQuality.Where(q => q.ParseResult.SeasonNumber == newParseResult.SeasonNumber); if (newParseResult.FullSeason) { return matchingSeason.Any(); } return matchingSeason.Any(q => q.ParseResult.EpisodeNumbers != null && q.ParseResult.EpisodeNumbers.Any(e => newParseResult.EpisodeNumbers.Contains(e))); } catch (Exception ex) { logger.WarnException("Unable to connect to Nzbget to check queue.", ex); return false; } }
public virtual bool DownloadReport(EpisodeParseResult parseResult) { var downloadTitle = GetDownloadTitle(parseResult); var provider = GetActiveDownloadClient(); bool success = provider.DownloadNzb(parseResult.NzbUrl, GetDownloadTitle(parseResult)); if (success) { logger.Trace("Download added to Queue: {0}", downloadTitle); foreach (var episode in _episodeProvider.GetEpisodesByParseResult(parseResult)) { var history = new History(); history.Date = DateTime.Now; history.Indexer = parseResult.Indexer; history.IsProper = parseResult.Quality.Proper; history.Quality = parseResult.Quality.QualityType; history.NzbTitle = parseResult.OriginalString; history.EpisodeId = episode.EpisodeId; history.SeriesId = episode.SeriesId; _historyProvider.Add(history); _episodeProvider.MarkEpisodeAsFetched(episode.EpisodeId); _signalRProvider.UpdateEpisodeStatus(episode.EpisodeId, EpisodeStatusType.Downloading); } _externalNotificationProvider.OnGrab(downloadTitle); } return success; }
private void WithGermanRelease() { parseResult = Builder<EpisodeParseResult> .CreateNew() .With(p => p.Language = LanguageType.German) .Build(); }
public void Setup() { spec = Mocker.Resolve<AllowedDownloadSpecification>(); parseResult = new EpisodeParseResult(); Mocker.GetMock<QualityAllowedByProfileSpecification>() .Setup(c => c.IsSatisfiedBy(It.IsAny<EpisodeParseResult>())) .Returns(true); Mocker.GetMock<AcceptableSizeSpecification>() .Setup(c => c.IsSatisfiedBy(It.IsAny<EpisodeParseResult>())) .Returns(true); Mocker.GetMock<UpgradeDiskSpecification>() .Setup(c => c.IsSatisfiedBy(It.IsAny<EpisodeParseResult>())) .Returns(true); Mocker.GetMock<AlreadyInQueueSpecification>() .Setup(c => c.IsSatisfiedBy(It.IsAny<EpisodeParseResult>())) .Returns(false); Mocker.GetMock<RetentionSpecification>() .Setup(c => c.IsSatisfiedBy(It.IsAny<EpisodeParseResult>())) .Returns(true); }
private void WithEnglishRelease() { parseResult = Builder<EpisodeParseResult> .CreateNew() .With(p => p.Language = LanguageType.English) .Build(); }
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 } }; }
protected override EpisodeParseResult CustomParser(SyndicationItem item, EpisodeParseResult currentResult) { if (currentResult != null) { currentResult.Size = 0; } return currentResult; }
public void Setup() { retentionSpecification = Mocker.Resolve<RetentionSpecification>(); parseResult = new EpisodeParseResult { Age = 100 }; }
protected override EpisodeParseResult CustomParser(SyndicationItem item, EpisodeParseResult currentResult) { if (currentResult != null) { var sizeString = Regex.Match(item.Summary.Text, @"\d+\.\d{1,2} \w{3}", RegexOptions.IgnoreCase).Value; currentResult.Size = Parser.GetReportSize(sizeString); } return currentResult; }
public virtual bool IsSatisfiedBy(EpisodeParseResult subject) { logger.Trace("Checking if report meets quality requirements. {0}", subject.Quality); if (!subject.Series.QualityProfile.Allowed.Contains(subject.Quality.Quality)) { logger.Trace("Quality {0} rejected by Series' quality profile", subject.Quality); return false; } return true; }
public virtual bool IsSatisfiedBy(EpisodeParseResult subject) { logger.Trace("Checking if report meets language requirements. {0}", subject.Language); if (subject.Language != LanguageType.English) { logger.Trace("Report Language: {0} rejected because it is not english", subject.Language); return false; } return true; }
public virtual bool IsSatisfiedBy(EpisodeParseResult subject) { foreach (var file in _episodeProvider.GetEpisodesByParseResult(subject).Select(c => c.EpisodeFile).Where(c => c != null)) { logger.Trace("Comparing file quality with report. Existing file is {0} proper:{1}", file.Quality, file.Proper); if (!_qualityUpgradeSpecification.IsSatisfiedBy(new Quality { QualityType = file.Quality, Proper = file.Proper }, subject.Quality, subject.Series.QualityProfile.Cutoff)) return false; } return true; }
public virtual bool IsSatisfiedBy(EpisodeParseResult subject) { logger.Trace("Checking if report meets retention requirements. {0}", subject.Age); if (_configProvider.Retention > 0 && subject.Age > _configProvider.Retention) { logger.Trace("Quality {0} rejected by user's retention limit", subject.Age); return false; } return true; }
public virtual bool IsSatisfiedBy(EpisodeParseResult subject) { if (!_qualityAllowedByProfileSpecification.IsSatisfiedBy(subject)) return false; if (!_upgradeDiskSpecification.IsSatisfiedBy(subject)) return false; if (!_retentionSpecification.IsSatisfiedBy(subject)) return false; if (!_acceptableSizeSpecification.IsSatisfiedBy(subject)) return false; if (_alreadyInQueueSpecification.IsSatisfiedBy(subject)) return false; logger.Debug("Episode {0} is needed", subject); return true; }
public void tostring_full_season() { var parseResult = new EpisodeParseResult(); parseResult.SeriesTitle = "My Series"; parseResult.SeasonNumber = 12; parseResult.FullSeason = true; parseResult.AirDate = null; parseResult.Quality = new Quality(QualityTypes.HDTV, false); parseResult.ToString().Should().Be("My Series - Season 12 HDTV"); }
public override SearchHistoryItem CheckReport(Series series, dynamic options, EpisodeParseResult episodeParseResult, SearchHistoryItem item) { if(options.SeasonNumber != episodeParseResult.SeasonNumber) { logger.Trace("Season number does not match searched season number, skipping."); item.SearchError = ReportRejectionType.WrongSeason; return item; } return item; }
public void tostring_multi_season_episode_proper() { var parseResult = new EpisodeParseResult(); parseResult.SeriesTitle = "My Series"; parseResult.SeasonNumber = 12; parseResult.EpisodeNumbers = new List<int> { 3, 4, 5 }; parseResult.FullSeason = false; parseResult.AirDate = null; parseResult.Quality = new Quality(QualityTypes.HDTV, true); parseResult.ToString().Should().Be("My Series - S12E03-04-05 HDTV [proper]"); }
public void tostring_single_season_episode() { var parseResult = new EpisodeParseResult(); parseResult.SeriesTitle = "My Series"; parseResult.SeasonNumber = 12; parseResult.EpisodeNumbers = new List<int> { 3 }; parseResult.FullSeason = false; parseResult.AirDate = null; parseResult.Quality = new Quality(QualityTypes.HDTV, false); parseResult.ToString().Should().Be("My Series - S12E03 HDTV"); }
public virtual ReportRejectionType IsSatisfiedBy(EpisodeParseResult subject) { if (!_qualityAllowedByProfileSpecification.IsSatisfiedBy(subject)) return ReportRejectionType.QualityNotWanted; if (!_customStartDateSpecification.IsSatisfiedBy(subject)) return ReportRejectionType.AiredAfterCustomStartDate; if (!_upgradeDiskSpecification.IsSatisfiedBy(subject)) return ReportRejectionType.ExistingQualityIsEqualOrBetter; if (!_languageSpecification.IsSatisfiedBy(subject)) return ReportRejectionType.LanguageNotWanted; if (!_retentionSpecification.IsSatisfiedBy(subject)) return ReportRejectionType.Retention; if (!_acceptableSizeSpecification.IsSatisfiedBy(subject)) return ReportRejectionType.Size; if (!_allowedReleaseGroupSpecification.IsSatisfiedBy(subject)) return ReportRejectionType.ReleaseGroupNotWanted; if (_alreadyInQueueSpecification.IsSatisfiedBy(subject)) return ReportRejectionType.AlreadyInQueue; logger.Debug("Episode {0} is needed", subject); return ReportRejectionType.None; }
public virtual bool IsSatisfiedBy(EpisodeParseResult subject) { foreach (var episode in subject.Episodes) { var bestQualityInHistory = _historyProvider.GetBestQualityInHistory(subject.Series.SeriesId, episode.SeasonNumber, episode.EpisodeNumber); if (bestQualityInHistory != null) { logger.Trace("Comparing history quality with report. History is {0}", bestQualityInHistory); if (!_qualityUpgradeSpecification.IsSatisfiedBy(bestQualityInHistory, subject.Quality, subject.Series.QualityProfile.Cutoff)) return false; } } return true; }
public override SearchHistoryItem CheckReport(Series series, dynamic options, EpisodeParseResult episodeParseResult, SearchHistoryItem item) { Episode episode = options.Episode; if (!episodeParseResult.AirDate.HasValue || episodeParseResult.AirDate.Value != episode.AirDate.Value) { logger.Trace("Episode AirDate does not match searched episode number, skipping."); item.SearchError = ReportRejectionType.WrongEpisode; return item; } return item; }
public virtual bool IsSatisfiedBy(EpisodeParseResult subject) { logger.Trace("Beginning size check for: {0}", subject); if(subject.Quality.Quality == QualityTypes.RAWHD) { logger.Trace("Raw-HD release found, skipping size check."); return true; } var qualityType = _qualityTypeProvider.Get((int)subject.Quality.Quality); if (qualityType.MaxSize == 0) { logger.Trace("Max size is 0 (unlimited) - skipping check."); return true; } var maxSize = qualityType.MaxSize.Megabytes(); var series = subject.Series; //Multiply maxSize by Series.Runtime maxSize = maxSize * series.Runtime; //Multiply maxSize by the number of episodes parsed (if EpisodeNumbers is null it will be treated as a single episode) //TODO: is this check really necessary? shouldn't we blowup? if (subject.EpisodeNumbers != null) maxSize = maxSize * subject.EpisodeNumbers.Count; //Check if there was only one episode parsed //and it is the first or last episode of the season if (subject.EpisodeNumbers != null && subject.EpisodeNumbers.Count == 1 && _episodeProvider.IsFirstOrLastEpisodeOfSeason(series.SeriesId, subject.SeasonNumber, subject.EpisodeNumbers[0])) { maxSize = maxSize * 2; } //If the parsed size is greater than maxSize we don't want it if (subject.Size > maxSize) { logger.Trace("Item: {0}, Size: {1} is greater than maximum allowed size ({2}), rejecting.", subject, subject.Size, maxSize); return false; } logger.Trace("Item: {0}, meets size contraints.", subject); return true; }
public void Setup() { _qualityAllowedByProfile = Mocker.Resolve<QualityAllowedByProfileSpecification>(); var fakeSeries = Builder<Series>.CreateNew() .With(c => c.QualityProfile = new QualityProfile { Cutoff = QualityTypes.Bluray1080p }) .Build(); parseResult = new EpisodeParseResult { Series = fakeSeries, Quality = new QualityModel(QualityTypes.DVD, true), EpisodeNumbers = new List<int> { 3 }, SeasonNumber = 12, }; }
public virtual bool IsSatisfiedBy(EpisodeParseResult subject) { foreach (var file in subject.Episodes.Select(c => c.EpisodeFile).Where(c => c != null)) { logger.Trace("Comparing file quality with report. Existing file is {0} proper:{1}", file.Quality, file.Proper); if (!_qualityUpgradeSpecification.IsSatisfiedBy(new QualityModel { Quality = file.Quality, Proper = file.Proper }, subject.Quality, subject.Series.QualityProfile.Cutoff)) return false; if(subject.Quality.Proper && file.DateAdded < DateTime.Today.AddDays(-7)) { logger.Trace("Proper for old file, skipping: {0}", subject); return false; } } return true; }
public virtual bool IsSatisfiedBy(EpisodeParseResult subject) { if (!subject.Series.CustomStartDate.HasValue) { logger.Debug("{0} does not restrict downloads before date.", subject.Series.Title); return true; } if (subject.Episodes.Any(episode => episode.AirDate >= subject.Series.CustomStartDate.Value)) { logger.Debug("One or more episodes aired after cutoff, downloading."); return true; } logger.Debug("Episodes aired before cutoff date: {0}", subject.Series.CustomStartDate); return false; }
public void existing_single_episode_should_return_single_existing_episode() { Db.Insert(fakeEpisode); Db.Insert(fakeSeries); var parseResult = new EpisodeParseResult { Series = fakeSeries, SeasonNumber = fakeEpisode.SeasonNumber, EpisodeNumbers = new List<int> { fakeEpisode.EpisodeNumber } }; var ep = episodeProvider.GetEpisodesByParseResult(parseResult); ep.Should().HaveCount(1); parseResult.EpisodeTitle.Should().Be(fakeEpisode.Title); VerifyEpisode(ep[0], fakeEpisode); Db.Fetch<Episode>().Should().HaveCount(1); }
public override SearchHistoryItem CheckReport(Series series, dynamic options, EpisodeParseResult episodeParseResult, SearchHistoryItem item) { if(series.UseSceneNumbering && options.Episode.SeasonNumber > 0 && options.Episode.EpisodeNumber > 0) { if (options.Episode.SceneSeasonNumber != episodeParseResult.SeasonNumber) { logger.Trace("Season number does not match searched season number, skipping."); item.SearchError = ReportRejectionType.WrongSeason; return item; } if (!episodeParseResult.EpisodeNumbers.Contains(options.Episode.SceneEpisodeNumber)) { logger.Trace("Episode number does not match searched episode number, skipping."); item.SearchError = ReportRejectionType.WrongEpisode; return item; } return item; } if(options.Episode.SeasonNumber != episodeParseResult.SeasonNumber) { logger.Trace("Season number does not match searched season number, skipping."); item.SearchError = ReportRejectionType.WrongSeason; return item; } if (!episodeParseResult.EpisodeNumbers.Contains(options.Episode.EpisodeNumber)) { logger.Trace("Episode number does not match searched episode number, skipping."); item.SearchError = ReportRejectionType.WrongEpisode; return item; } return item; }
public void Setup() { Mocker.Resolve<QualityUpgradeSpecification>(); _upgradeHistory = Mocker.Resolve<UpgradeHistorySpecification>(); var fakeSeries = Builder<Series>.CreateNew() .With(c => c.QualityProfile = new QualityProfile { Cutoff = QualityTypes.Bluray1080p }) .Build(); parseResultMulti = new EpisodeParseResult { Series = fakeSeries, Quality = new Quality(QualityTypes.DVD, true), EpisodeNumbers = new List<int> { 3, 4 }, SeasonNumber = 12, }; parseResultSingle = new EpisodeParseResult { Series = fakeSeries, Quality = new Quality(QualityTypes.DVD, true), EpisodeNumbers = new List<int> { 3 }, SeasonNumber = 12, }; firstQuality = new Quality(QualityTypes.Bluray1080p, true); secondQuality = new Quality(QualityTypes.Bluray1080p, true); var singleEpisodeList = new List<Episode> { new Episode { SeasonNumber = 12, EpisodeNumber = 3 } }; var doubleEpisodeList = new List<Episode> { new Episode { SeasonNumber = 12, EpisodeNumber = 3 }, new Episode { SeasonNumber = 12, EpisodeNumber = 4 }, new Episode { SeasonNumber = 12, EpisodeNumber = 5 } }; Mocker.GetMock<EpisodeProvider>().Setup(c => c.GetEpisodesByParseResult(parseResultSingle)).Returns(singleEpisodeList); Mocker.GetMock<EpisodeProvider>().Setup(c => c.GetEpisodesByParseResult(parseResultMulti)).Returns(doubleEpisodeList); Mocker.GetMock<HistoryProvider>().Setup(c => c.GetBestQualityInHistory(fakeSeries.SeriesId, 12, 3)).Returns(firstQuality); Mocker.GetMock<HistoryProvider>().Setup(c => c.GetBestQualityInHistory(fakeSeries.SeriesId, 12, 4)).Returns(secondQuality); Mocker.GetMock<HistoryProvider>().Setup(c => c.GetBestQualityInHistory(fakeSeries.SeriesId, 12, 5)).Returns<Quality>(null); }