private void AddQualityTokens(Dictionary <string, Func <TokenMatch, string> > tokenHandlers, Series series, EpisodeFile episodeFile) { var qualityTitle = _qualityDefinitionService.Get(episodeFile.Quality.Quality).Title; var qualityProper = GetQualityProper(series, episodeFile.Quality); var qualityReal = GetQualityReal(series, episodeFile.Quality); tokenHandlers["{Quality Full}"] = m => String.Format("{0} {1} {2}", qualityTitle, qualityProper, qualityReal); tokenHandlers["{Quality Title}"] = m => qualityTitle; tokenHandlers["{Quality Proper}"] = m => qualityProper; tokenHandlers["{Quality Real}"] = m => qualityReal; }
private string GetQualityTitle(QualityModel quality) { if (quality.Proper) { return(_qualityDefinitionService.Get(quality.Quality).Title + " Proper"); } else { return(_qualityDefinitionService.Get(quality.Quality).Title); } }
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { _logger.Debug("Beginning size check for: {0}", subject); var quality = subject.ParsedMovieInfo.Quality.Quality; if (subject.Release.Size == 0) { _logger.Debug("Release has unknown size, skipping size check."); return(Decision.Accept()); } var qualityDefinition = _qualityDefinitionService.Get(quality); if (subject.Movie.Runtime == 0) { _logger.Warn("{0} has no runtime information using median movie runtime of 110 minutes.", subject.Movie); subject.Movie.Runtime = 110; } if (qualityDefinition.MinSize.HasValue) { var minSize = qualityDefinition.MinSize.Value.Megabytes(); //Multiply maxSize by Series.Runtime minSize = minSize * subject.Movie.Runtime; //If the parsed size is smaller than minSize we don't want it if (subject.Release.Size < minSize) { var runtimeMessage = subject.Movie.Title; _logger.Debug("Item: {0}, Size: {1} is smaller than minimum allowed size ({2} bytes for {3}), rejecting.", subject, subject.Release.Size, minSize, runtimeMessage); return(Decision.Reject("{0} is smaller than minimum allowed {1} (for {2})", subject.Release.Size.SizeSuffix(), minSize.SizeSuffix(), runtimeMessage)); } } if (!qualityDefinition.MaxSize.HasValue || qualityDefinition.MaxSize.Value == 0) { _logger.Debug("Max size is unlimited - skipping check."); } else { var maxSize = qualityDefinition.MaxSize.Value.Megabytes(); //Multiply maxSize by Series.Runtime maxSize = maxSize * subject.Movie.Runtime; //If the parsed size is greater than maxSize we don't want it if (subject.Release.Size > maxSize) { ; _logger.Debug("Item: {0}, Size: {1} is greater than maximum allowed size ({2} for {3}), rejecting.", subject, subject.Release.Size, maxSize, subject.Movie.Title); return(Decision.Reject("{0} is larger than maximum allowed {1} (for {2})", subject.Release.Size.SizeSuffix(), maxSize.SizeSuffix(), subject.Movie.Title)); } } _logger.Debug("Item: {0}, meets size constraints.", subject); return(Decision.Accept()); }
public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { _logger.Debug("Beginning size check for: {0}", subject); var quality = subject.ParsedEpisodeInfo.Quality.Quality; if (quality == Quality.RAWHD) { _logger.Debug("Raw-HD release found, skipping size check."); return(true); } if (quality == Quality.Unknown) { _logger.Debug("Unknown quality. skipping size check."); return(false); } var qualityDefinition = _qualityDefinitionService.Get(quality); var minSize = qualityDefinition.MinSize.Megabytes(); //Multiply maxSize by Series.Runtime minSize = minSize * subject.Series.Runtime * subject.Episodes.Count; //If the parsed size is smaller than minSize we don't want it if (subject.Release.Size < minSize) { _logger.Debug("Item: {0}, Size: {1} is smaller than minimum allowed size ({2}), rejecting.", subject, subject.Release.Size, minSize); return(false); } if (qualityDefinition.MaxSize == 0) { _logger.Debug("Max size is 0 (unlimited) - skipping check."); } else { var maxSize = qualityDefinition.MaxSize.Megabytes(); //Multiply maxSize by Series.Runtime maxSize = maxSize * subject.Series.Runtime * subject.Episodes.Count; //Check if there was only one episode parsed and it is the first if (subject.Episodes.Count == 1 && _episodeService.IsFirstOrLastEpisodeOfSeason(subject.Episodes.First().Id)) { maxSize = maxSize * 2; } //If the parsed size is greater than maxSize we don't want it if (subject.Release.Size > maxSize) { _logger.Debug("Item: {0}, Size: {1} is greater than maximum allowed size ({2}), rejecting.", subject, subject.Release.Size, maxSize); return(false); } } _logger.Debug("Item: {0}, meets size constraints.", subject); return(true); }
public Decision IsSatisfiedBy(RemoteAlbum subject, SearchCriteriaBase searchCriteria) { _logger.Debug("Beginning size check for: {0}", subject); var quality = subject.ParsedAlbumInfo.Quality.Quality; if (subject.Release.Size == 0) { _logger.Debug("Release has unknown size, skipping size check."); return(Decision.Accept()); } var qualityDefinition = _qualityDefinitionService.Get(quality); if (qualityDefinition.MinSize.HasValue) { var minSize = qualityDefinition.MinSize.Value.Kilobits(); var minReleaseDuration = subject.Albums.Select(a => a.AlbumReleases.Value.Where(r => r.Monitored || a.AnyReleaseOk).Select(r => r.Duration).Min()).Sum() / 1000; //Multiply minSize by smallest release duration minSize = minSize * minReleaseDuration; //If the parsed size is smaller than minSize we don't want it if (subject.Release.Size < minSize) { var runtimeMessage = $"{minReleaseDuration}sec"; _logger.Debug("Item: {0}, Size: {1} is smaller than minimum allowed size ({2} bytes for {3}), rejecting.", subject, subject.Release.Size, minSize, runtimeMessage); return(Decision.Reject("{0} is smaller than minimum allowed {1}", subject.Release.Size.SizeSuffix(), minSize.SizeSuffix())); } } if (!qualityDefinition.MaxSize.HasValue || qualityDefinition.MaxSize.Value == 0) { _logger.Debug("Max size is unlimited - skipping check."); } else { var maxSize = qualityDefinition.MaxSize.Value.Kilobits(); var maxReleaseDuration = subject.Albums.Select(a => a.AlbumReleases.Value.Where(r => r.Monitored || a.AnyReleaseOk).Select(r => r.Duration).Max()).Sum() / 1000; //Multiply maxSize by Album.Duration maxSize = maxSize * maxReleaseDuration; //If the parsed size is greater than maxSize we don't want it if (subject.Release.Size > maxSize) { var runtimeMessage = $"{maxReleaseDuration}sec"; _logger.Debug("Item: {0}, Size: {1} is greater than maximum allowed size ({2} bytes for {3}), rejecting.", subject, subject.Release.Size, maxSize, runtimeMessage); return(Decision.Reject("{0} is larger than maximum allowed {1}", subject.Release.Size.SizeSuffix(), maxSize.SizeSuffix())); } } _logger.Debug("Item: {0}, meets size constraints.", subject); return(Decision.Accept()); }
private void AddQualityTokens(Dictionary <string, Func <TokenMatch, string> > tokenHandlers, Artist artist, TrackFile trackFile) { var qualityTitle = _qualityDefinitionService.Get(trackFile.Quality.Quality).Title; var qualityProper = GetQualityProper(trackFile.Quality); //var qualityReal = GetQualityReal(artist, trackFile.Quality); tokenHandlers["{Quality Full}"] = m => String.Format("{0}", qualityTitle); tokenHandlers["{Quality Title}"] = m => qualityTitle; tokenHandlers["{Quality Proper}"] = m => qualityProper; //tokenHandlers["{Quality Real}"] = m => qualityReal; }
private void AddQualityTokens(Dictionary <string, Func <TokenMatch, string> > tokenHandlers, Author author, BookFile bookFile) { var qualityTitle = _qualityDefinitionService.Get(bookFile.Quality.Quality).Title; var qualityProper = GetQualityProper(bookFile.Quality); //var qualityReal = GetQualityReal(author, bookFile.Quality); tokenHandlers["{Quality Full}"] = m => string.Format("{0}", qualityTitle); tokenHandlers["{Quality Title}"] = m => qualityTitle; tokenHandlers["{Quality Proper}"] = m => qualityProper; //tokenHandlers["{Quality Real}"] = m => qualityReal; }
private String GetQualityTitle(Series series, QualityModel quality) { var qualitySuffix = String.Empty; if (quality.Revision.Version > 1) { if (series.SeriesType == SeriesTypes.Anime) { qualitySuffix = " v" + quality.Revision.Version; } else { qualitySuffix = " Proper"; } } return(_qualityDefinitionService.Get(quality.Quality).Title + qualitySuffix); }
private void AddQualityTokens(Dictionary <string, Func <TokenMatch, string> > tokenHandlers, Movie movie, MovieFile movieFile) { if (movieFile?.Quality?.Quality == null) { tokenHandlers["{Quality Full}"] = m => ""; tokenHandlers["{Quality Title}"] = m => ""; tokenHandlers["{Quality Proper}"] = m => ""; tokenHandlers["{Quality Real}"] = m => ""; return; } var qualityTitle = _qualityDefinitionService.Get(movieFile.Quality.Quality).Title; var qualityProper = GetQualityProper(movie, movieFile.Quality); var qualityReal = GetQualityReal(movie, movieFile.Quality); tokenHandlers["{Quality Full}"] = m => string.Format("{0} {1} {2}", qualityTitle, qualityProper, qualityReal); tokenHandlers["{Quality Title}"] = m => qualityTitle; tokenHandlers["{Quality Proper}"] = m => qualityProper; tokenHandlers["{Quality Real}"] = m => qualityReal; }
private int CompareSize(DownloadDecision x, DownloadDecision y) { var sizeCompare = CompareBy(x.RemoteMovie, y.RemoteMovie, remoteMovie => { var preferredSize = _qualityDefinitionService.Get(remoteMovie.ParsedMovieInfo.Quality.Quality).PreferredSize; // If no value for preferred it means unlimited so fallback to sort largest is best if (preferredSize.HasValue && remoteMovie.Movie.Runtime > 0) { var preferredMovieSize = remoteMovie.Movie.Runtime * preferredSize.Value.Megabytes(); // Calculate closest to the preferred size return(Math.Abs((remoteMovie.Release.Size - preferredMovieSize).Round(200.Megabytes())) * (-1)); } else { return(remoteMovie.Release.Size.Round(200.Megabytes())); } }); return(sizeCompare); }
public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { _logger.Debug("Beginning size check for: {0}", subject); var quality = subject.ParsedEpisodeInfo.Quality.Quality; if (quality == Quality.RAWHD) { _logger.Debug("Raw-HD release found, skipping size check."); return(Decision.Accept()); } if (subject.ParsedEpisodeInfo.Special) { _logger.Debug("Special release found, skipping size check."); return(Decision.Accept()); } var qualityDefinition = _qualityDefinitionService.Get(quality); var minSize = qualityDefinition.MinSize.Megabytes(); //Multiply maxSize by Series.Runtime minSize = minSize * subject.Series.Runtime * subject.Episodes.Count; //If the parsed size is smaller than minSize we don't want it if (subject.Release.Size < minSize) { _logger.Debug("Item: {0}, Size: {1:0n} is smaller than minimum allowed size ({2:0}), rejecting.", subject, subject.Release.Size, minSize); return(Decision.Reject("{0} is smaller than minimum allowed: {1}", subject.Release.Size.SizeSuffix(), minSize.SizeSuffix())); } if (qualityDefinition.MaxSize == 0) { _logger.Debug("Max size is 0 (unlimited) - skipping check."); } else { var maxSize = qualityDefinition.MaxSize.Megabytes(); //Multiply maxSize by Series.Runtime maxSize = maxSize * subject.Series.Runtime * subject.Episodes.Count; if (subject.Episodes.Count == 1) { Episode episode = subject.Episodes.First(); List <Episode> seasonEpisodes; var seasonSearchCriteria = searchCriteria as SeasonSearchCriteria; if (seasonSearchCriteria != null && !seasonSearchCriteria.Series.UseSceneNumbering && seasonSearchCriteria.Episodes.Any(v => v.Id == episode.Id)) { seasonEpisodes = (searchCriteria as SeasonSearchCriteria).Episodes; } else { seasonEpisodes = _episodeService.GetEpisodesBySeason(episode.SeriesId, episode.SeasonNumber); } //Ensure that this is either the first episode //or is the last episode in a season that has 10 or more episodes if (seasonEpisodes.First().Id == episode.Id || (seasonEpisodes.Count() >= 10 && seasonEpisodes.Last().Id == episode.Id)) { _logger.Debug("Possible double episode, doubling allowed size."); maxSize = maxSize * 2; } } //If the parsed size is greater than maxSize we don't want it if (subject.Release.Size > maxSize) { _logger.Debug("Item: {0}, Size: {1} is greater than maximum allowed size ({2}), rejecting.", subject, subject.Release.Size, maxSize); return(Decision.Reject("{0} is larger than maximum allowed: {1}", subject.Release.Size.SizeSuffix(), maxSize.SizeSuffix())); } } _logger.Debug("Item: {0}, meets size constraints.", subject); return(Decision.Accept()); }
private ImportDecision GetDecision(string file, Movie movie, ParsedMovieInfo folderInfo, bool sceneSource, bool shouldUseFolderName, bool shouldCheckQuality = false) { ImportDecision decision = null; try { var localMovie = _parsingService.GetLocalMovie(file, movie, shouldUseFolderName ? folderInfo : null, sceneSource); if (localMovie != null) { localMovie.Quality = GetQuality(folderInfo, localMovie.Quality, movie); localMovie.Size = _diskProvider.GetFileSize(file); _logger.Debug("Size: {0}", localMovie.Size); var current = localMovie.Quality; //TODO: make it so media info doesn't ruin the import process of a new series if (sceneSource && ShouldCheckQualityForParsedQuality(current.Quality)) { localMovie.MediaInfo = _videoFileInfoReader.GetMediaInfo(file); if (shouldCheckQuality) { _logger.Debug("Checking quality for this video file to make sure nothing mismatched."); var width = localMovie.MediaInfo.Width; var qualityName = current.Quality.Name.ToLower(); QualityModel updated = null; if (width > 2000) { if (qualityName.Contains("bluray")) { updated = new QualityModel(Quality.Bluray2160p); } else if (qualityName.Contains("webdl")) { updated = new QualityModel(Quality.WEBDL2160p); } else if (qualityName.Contains("hdtv")) { updated = new QualityModel(Quality.HDTV2160p); } else { var def = _qualitiesService.Get(Quality.HDTV2160p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.HDTV2160p); } def = _qualitiesService.Get(Quality.WEBDL2160p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.WEBDL2160p); } def = _qualitiesService.Get(Quality.Bluray2160p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.Bluray2160p); } if (updated == null) { updated = new QualityModel(Quality.Bluray2160p); } } } else if (width > 1400) { if (qualityName.Contains("bluray")) { updated = new QualityModel(Quality.Bluray1080p); } else if (qualityName.Contains("webdl")) { updated = new QualityModel(Quality.WEBDL1080p); } else if (qualityName.Contains("hdtv")) { updated = new QualityModel(Quality.HDTV1080p); } else { var def = _qualitiesService.Get(Quality.HDTV1080p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.HDTV1080p); } def = _qualitiesService.Get(Quality.WEBDL1080p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.WEBDL1080p); } def = _qualitiesService.Get(Quality.Bluray1080p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.Bluray1080p); } if (updated == null) { updated = new QualityModel(Quality.Bluray1080p); } } } else if (width > 900) { if (qualityName.Contains("bluray")) { updated = new QualityModel(Quality.Bluray720p); } else if (qualityName.Contains("webdl")) { updated = new QualityModel(Quality.WEBDL720p); } else if (qualityName.Contains("hdtv")) { updated = new QualityModel(Quality.HDTV720p); } else { var def = _qualitiesService.Get(Quality.HDTV720p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.HDTV720p); } def = _qualitiesService.Get(Quality.WEBDL720p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.WEBDL720p); } def = _qualitiesService.Get(Quality.Bluray720p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.Bluray720p); } if (updated == null) { updated = new QualityModel(Quality.Bluray720p); } } } if (updated != null && updated != current) { _logger.Debug("Quality ({0}) of the file is different than the one we have ({1})", updated, current); updated.QualitySource = QualitySource.MediaInfo; localMovie.Quality = updated; } } decision = GetDecision(localMovie); } else { decision = GetDecision(localMovie); } } else { localMovie = new LocalMovie(); localMovie.Path = file; decision = new ImportDecision(localMovie, new Rejection("Unable to parse file")); } } catch (Exception e) { _logger.Error(e, "Couldn't import file. " + file); var localMovie = new LocalMovie { Path = file }; decision = new ImportDecision(localMovie, new Rejection("Unexpected error processing file")); } //LocalMovie nullMovie = null; //decision = new ImportDecision(nullMovie, new Rejection("IMPLEMENTATION MISSING!!!")); return(decision); }
public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { _logger.Debug("Beginning size check for: {0}", subject); var quality = subject.ParsedEpisodeInfo.Quality.Quality; if (subject.ParsedEpisodeInfo.Special) { _logger.Debug("Special release found, skipping size check."); return(Decision.Accept()); } if (subject.Release.Size == 0) { _logger.Debug("Release has unknown size, skipping size check"); return(Decision.Accept()); } var qualityDefinition = _qualityDefinitionService.Get(quality); if (qualityDefinition.MinSize.HasValue) { var minSize = qualityDefinition.MinSize.Value.Megabytes(); //Multiply maxSize by Series.Runtime minSize = minSize * subject.Series.Runtime * subject.Episodes.Count; //If the parsed size is smaller than minSize we don't want it if (subject.Release.Size < minSize) { var runtimeMessage = subject.Episodes.Count == 1 ? $"{subject.Series.Runtime}min" : $"{subject.Episodes.Count}x {subject.Series.Runtime}min"; _logger.Debug("Item: {0}, Size: {1} is smaller than minimum allowed size ({2} bytes for {3}), rejecting.", subject, subject.Release.Size, minSize, runtimeMessage); return(Decision.Reject("{0} is smaller than minimum allowed {1} (for {2})", subject.Release.Size.SizeSuffix(), minSize.SizeSuffix(), runtimeMessage)); } } if (!qualityDefinition.MaxSize.HasValue || qualityDefinition.MaxSize.Value == 0) { _logger.Debug("Max size is unlimited, skipping size check"); } else if (subject.Series.Runtime == 0) { _logger.Debug("Series runtime is 0, unable to validate size until it is available, rejecting"); return(Decision.Reject("Series runtime is 0, unable to validate size until it is available")); } else { var maxSize = qualityDefinition.MaxSize.Value.Megabytes(); //Multiply maxSize by Series.Runtime maxSize = maxSize * subject.Series.Runtime * subject.Episodes.Count; if (subject.Episodes.Count == 1 && subject.Series.SeriesType == SeriesTypes.Standard) { Episode episode = subject.Episodes.First(); List <Episode> seasonEpisodes; var seasonSearchCriteria = searchCriteria as SeasonSearchCriteria; if (seasonSearchCriteria != null && !seasonSearchCriteria.Series.UseSceneNumbering && seasonSearchCriteria.Episodes.Any(v => v.Id == episode.Id)) { seasonEpisodes = seasonSearchCriteria.Episodes; } else { seasonEpisodes = _episodeService.GetEpisodesBySeason(episode.SeriesId, episode.SeasonNumber); } //Ensure that this is either the first episode //or is the last episode in a season that has 10 or more episodes if (seasonEpisodes.First().Id == episode.Id || (seasonEpisodes.Count() >= 10 && seasonEpisodes.Last().Id == episode.Id)) { _logger.Debug("Possible double episode, doubling allowed size."); maxSize = maxSize * 2; } } //If the parsed size is greater than maxSize we don't want it if (subject.Release.Size > maxSize) { var runtimeMessage = subject.Episodes.Count == 1 ? $"{subject.Series.Runtime}min" : $"{subject.Episodes.Count}x {subject.Series.Runtime}min"; _logger.Debug("Item: {0}, Size: {1} is greater than maximum allowed size ({2} for {3}), rejecting", subject, subject.Release.Size, maxSize, runtimeMessage); return(Decision.Reject("{0} is larger than maximum allowed {1} (for {2})", subject.Release.Size.SizeSuffix(), maxSize.SizeSuffix(), runtimeMessage)); } } _logger.Debug("Item: {0}, meets size constraints", subject); return(Decision.Accept()); }
private QualityDefinitionResource GetById(int id) { return(_qualityDefinitionService.Get((Quality)id).InjectTo <QualityDefinitionResource>()); }
public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { _logger.Debug("Beginning size check for: {0}", subject); var quality = subject.ParsedEpisodeInfo.Quality.Quality; if (subject.ParsedEpisodeInfo.Special) { _logger.Debug("Special release found, skipping size check."); return(Decision.Accept()); } if (subject.Release.Size == 0) { _logger.Debug("Release has unknown size, skipping size check"); return(Decision.Accept()); } var runtime = subject.Series.Runtime; if (runtime == 0) { var firstSeasonNumber = subject.Series.Seasons.Where(s => s.SeasonNumber > 0).Min(s => s.SeasonNumber); var pilotEpisode = _episodeService.GetEpisodesBySeason(subject.Series.Id, firstSeasonNumber).First(); if (subject.Episodes.First().SeasonNumber == pilotEpisode.SeasonNumber) { // If the first episode has an air date use it, otherwise use the release's publish date because like runtime it may not have updated yet. var gracePeriodEnd = (pilotEpisode.AirDateUtc ?? subject.Release.PublishDate).AddHours(24); // If episodes don't have an air date that is okay, otherwise make sure it's within 24 hours of the first episode airing. if (subject.Episodes.All(e => !e.AirDateUtc.HasValue || e.AirDateUtc.Value.Before(gracePeriodEnd))) { _logger.Debug("Series runtime is 0, but all episodes in release aired within 24 hours of first episode in season, defaulting runtime to 45 minutes"); runtime = 45; } } // Reject if the run time is still 0 if (runtime == 0) { _logger.Debug("Series runtime is 0, unable to validate size until it is available, rejecting"); return(Decision.Reject("Series runtime is 0, unable to validate size until it is available")); } } var qualityDefinition = _qualityDefinitionService.Get(quality); if (qualityDefinition.MinSize.HasValue) { var minSize = qualityDefinition.MinSize.Value.Megabytes(); // Multiply maxSize by Series.Runtime minSize = minSize * runtime * subject.Episodes.Count; // If the parsed size is smaller than minSize we don't want it if (subject.Release.Size < minSize) { var runtimeMessage = subject.Episodes.Count == 1 ? $"{runtime}min" : $"{subject.Episodes.Count}x {runtime}min"; _logger.Debug("Item: {0}, Size: {1} is smaller than minimum allowed size ({2} bytes for {3}), rejecting.", subject, subject.Release.Size, minSize, runtimeMessage); return(Decision.Reject("{0} is smaller than minimum allowed {1} (for {2})", subject.Release.Size.SizeSuffix(), minSize.SizeSuffix(), runtimeMessage)); } } if (!qualityDefinition.MaxSize.HasValue || qualityDefinition.MaxSize.Value == 0) { _logger.Debug("Max size is unlimited, skipping size check"); } else { var maxSize = qualityDefinition.MaxSize.Value.Megabytes(); // Multiply maxSize by Series.Runtime maxSize = maxSize * runtime * subject.Episodes.Count; if (subject.Episodes.Count == 1 && subject.Series.SeriesType == SeriesTypes.Standard) { var firstEpisode = subject.Episodes.First(); var seasonEpisodes = GetSeasonEpisodes(subject, searchCriteria); // Ensure that this is either the first episode // or is the last episode in a season that has 10 or more episodes if (seasonEpisodes.First().Id == firstEpisode.Id || (seasonEpisodes.Count() >= 10 && seasonEpisodes.Last().Id == firstEpisode.Id)) { _logger.Debug("Possible double episode, doubling allowed size."); maxSize = maxSize * 2; } } // If the parsed size is greater than maxSize we don't want it if (subject.Release.Size > maxSize) { var runtimeMessage = subject.Episodes.Count == 1 ? $"{runtime}min" : $"{subject.Episodes.Count}x {runtime}min"; _logger.Debug("Item: {0}, Size: {1} is greater than maximum allowed size ({2} for {3}), rejecting", subject, subject.Release.Size, maxSize, runtimeMessage); return(Decision.Reject("{0} is larger than maximum allowed {1} (for {2})", subject.Release.Size.SizeSuffix(), maxSize.SizeSuffix(), runtimeMessage)); } } _logger.Debug("Item: {0}, meets size constraints", subject); return(Decision.Accept()); }