Exemple #1
0
        public void equal_operand_false_proper()
        {
            var first = new QualityModel(QualityTypes.Bluray1080p, true);
            var second = new QualityModel(QualityTypes.Bluray1080p, false);

            (first == second).Should().BeFalse();
        }
Exemple #2
0
        public void Icomparer_lesser_proper()
        {
            var first = new QualityModel(QualityTypes.DVD, false);
            var second = new QualityModel(QualityTypes.DVD, true);

            first.Should().BeLessThan(second);
        }
        public void Icomparer_lesser()
        {
            var first = new QualityModel(Quality.DVD, true);
            var second = new QualityModel(Quality.Bluray1080p, true);

            first.Should().BeLessThan(second);
        }
Exemple #4
0
        public void Icomparer_greater_proper()
        {
            var first = new QualityModel(QualityTypes.Bluray1080p, false);
            var second = new QualityModel(QualityTypes.Bluray1080p, true);

            second.Should().BeGreaterThan(first);
        }
        public void equal_operand_false()
        {
            var first = new QualityModel(Quality.Bluray1080p, true);
            var second = new QualityModel(Quality.Unknown, true);

            (first == second).Should().BeFalse();
        }
Exemple #6
0
        public void not_equal_operand()
        {
            var first = new QualityModel(QualityTypes.Bluray1080p, true);
            var second = new QualityModel(QualityTypes.Bluray1080p, true);

            (first != second).Should().BeFalse();
        }
        public void Icomparer_greater_test()
        {
            var first = new QualityModel(Quality.DVD, true);
            var second = new QualityModel(Quality.Bluray1080p, true);

            second.Should().BeGreaterThan(first);
        }
        public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Series series, bool sceneSource, QualityModel quality = null)
        {
            var newFiles = _mediaFileService.FilterExistingFiles(videoFiles.ToList(), series.Id);

            _logger.Debug("Analyzing {0}/{1} files.", newFiles.Count, videoFiles.Count());

            return GetDecisions(newFiles, series, sceneSource, quality).ToList();
        }
Exemple #9
0
        public void equal_operand()
        {
            var first = new QualityModel(QualityTypes.Bluray1080p, true);
            var second = new QualityModel(QualityTypes.Bluray1080p, true);

            (first == second).Should().BeTrue();
            (first >= second).Should().BeTrue();
            (first <= second).Should().BeTrue();
        }
        public bool IsProperUpgrade(QualityModel currentQuality, QualityModel newQuality)
        {
            if (currentQuality.Quality == newQuality.Quality && newQuality > currentQuality)
            {
                _logger.Trace("New quality is a proper for existing quality");
                return true;
            }

            return false;
        }
        public void should_be_greater_when_first_quality_is_a_proper_for_the_same_quality()
        {
            GivenDefaultProfile();

            var first = new QualityModel(Quality.Bluray1080p, new Revision(version: 2));
            var second = new QualityModel(Quality.Bluray1080p, new Revision(version: 1));

            var compare = Subject.Compare(first, second);

            compare.Should().BeGreaterThan(0);
        }
        public void should_be_lesser_when_second_quality_is_greater_than_first()
        {
            GivenDefaultProfile();

            var first = new QualityModel(Quality.DVD);
            var second = new QualityModel(Quality.Bluray1080p);

            var compare = Subject.Compare(first, second);

            compare.Should().BeLessThan(0);
        }
        public void should_be_greater_when_using_a_custom_profile()
        {
            GivenCustomProfile();

            var first = new QualityModel(Quality.DVD);
            var second = new QualityModel(Quality.Bluray720p);

            var compare = Subject.Compare(first, second);

            compare.Should().BeGreaterThan(0);
        }
        public bool IsRevisionUpgrade(QualityModel currentQuality, QualityModel newQuality)
        {
            var compare = newQuality.Revision.CompareTo(currentQuality.Revision);

            if (currentQuality.Quality == newQuality.Quality && compare > 0)
            {
                return true;
            }

            return false;
        }
        public void Icomparer_greater_proper()
        {
            GivenDefaultQualityProfile();

            var first = new QualityModel(Quality.Bluray1080p, false);
            var second = new QualityModel(Quality.Bluray1080p, true);

            var compare = Subject.Compare(second, first);

            compare.Should().BeGreaterThan(0);
        }
        public void Icomparer_lesser_proper()
        {
            GivenDefaultQualityProfile();

            var first = new QualityModel(Quality.DVD, false);
            var second = new QualityModel(Quality.DVD, true);

            var compare = Subject.Compare(first, second);

            compare.Should().BeLessThan(0);
        }
        public void Icomparer_greater_custom_order()
        {
            GivenCustomQualityProfile();

            var first = new QualityModel(Quality.DVD, true);
            var second = new QualityModel(Quality.Bluray720p, true);

            var compare = Subject.Compare(first, second);

            compare.Should().BeGreaterThan(0);
        }
        public bool IsProperUpgrade(QualityModel currentQuality, QualityModel newQuality)
        {
            int compare = newQuality.Proper.CompareTo(currentQuality.Proper);

            if (currentQuality.Quality == newQuality.Quality && compare > 0)
            {
                _logger.Trace("New quality is a proper for existing quality");
                return true;
            }

            return false;
        }
        public bool IsRevisionUpgrade(QualityModel currentQuality, QualityModel newQuality)
        {
            int compare = newQuality.Revision.CompareTo(currentQuality.Revision);

            if (currentQuality.Quality == newQuality.Quality && compare > 0)
            {
                _logger.Debug("New quality is a better revision for existing quality");
                return true;
            }

            return false;
        }
Exemple #20
0
        public bool IsSample(Series series, QualityModel quality, string path, long size, int seasonNumber)
        {
            if (seasonNumber == 0)
            {
                _logger.Debug("Special, skipping sample check");
                return false;
            }

            var extension = Path.GetExtension(path);

            if (extension != null && extension.Equals(".flv", StringComparison.InvariantCultureIgnoreCase))
            {
                _logger.Debug("Skipping sample check for .flv file");
                return false;
            }

            if (extension != null && extension.Equals(".strm", StringComparison.InvariantCultureIgnoreCase))
            {
                _logger.Debug("Skipping sample check for .strm file");
                return false;
            }

            try
            {
                var runTime = _videoFileInfoReader.GetRunTime(path);
                var minimumRuntime = GetMinimumAllowedRuntime(series);

                if (runTime.TotalMinutes.Equals(0))
                {
                    _logger.Error("[{0}] has a runtime of 0, is it a valid video file?", path);
                    return true;
                }

                if (runTime.TotalSeconds < minimumRuntime)
                {
                    _logger.Debug("[{0}] appears to be a sample. Runtime: {1} seconds. Expected at least: {2} seconds", path, runTime, minimumRuntime);
                    return true;
                }
            }

            catch (DllNotFoundException)
            {
                _logger.Debug("Falling back to file size detection");

                return CheckSize(size, quality);
            }

            _logger.Debug("Runtime is over 90 seconds");
            return false;
        }
        public void embedded_document_as_json()
        {
            var quality = new QualityModel { Quality = Quality.Bluray720p, Revision = new Revision(version: 2 )};

            var history = Builder<History.History>.CreateNew()
                            .With(c => c.Id = 0)
                            .With(c => c.Quality = quality)
                            .Build();

            Db.Insert(history);

            var loadedQuality = Db.Single<History.History>().Quality;
            loadedQuality.Should().Be(quality);
        }
        public bool CutoffNotMet(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null)
        {
            if (currentQuality.Quality >= profile.Cutoff)
            {
                if (newQuality != null && IsProperUpgrade(currentQuality, newQuality))
                {
                    return true;
                }

                _logger.Trace("Existing item meets cut-off. skipping.");
                return false;
            }

            return true;
        }
Exemple #23
0
 public void OnGrab(Series series, RemoteEpisode episode, QualityModel quality, WebhookSettings settings)
 {
     var payload = new WebhookPayload
     {
         EventType = "Grab",
         Series = new WebhookSeries(series),
         Episodes = episode.Episodes.ConvertAll(x => new WebhookEpisode(x)
         {
             Quality = quality.Quality.Name,
             QualityVersion = quality.Revision.Version,
             ReleaseGroup = episode.ParsedEpisodeInfo.ReleaseGroup
         })
     };
     NotifyWebhook(payload, settings);
 }
        public bool CutoffNotMet(Profile profile, QualityModel currentQuality, QualityModel newQuality = null)
        {
            var compare = new QualityModelComparer(profile).Compare(currentQuality.Quality, profile.Cutoff);

            if (compare < 0)
            {
                return true;
            }

            if (newQuality != null && IsRevisionUpgrade(currentQuality, newQuality))
            {
                return true;
            }

            return false;
        }
        public bool CutoffNotMet(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null)
        {
            int compare = new QualityModelComparer(profile).Compare(currentQuality.Quality, profile.Cutoff);

            if (compare >= 0)
            {
                if (newQuality != null && IsProperUpgrade(currentQuality, newQuality))
                {
                    return true;
                }

                _logger.Debug("Existing item meets cut-off. skipping.");
                return false;
            }

            return true;
        }
        public bool IsUpgradable(Profile profile, QualityModel currentQuality, QualityModel newQuality = null)
        {
            if (newQuality != null)
            {
                int compare = new QualityModelComparer(profile).Compare(newQuality, currentQuality);
                if (compare <= 0)
                {
                    return false;
                }

                if (IsRevisionUpgrade(currentQuality, newQuality))
                {
                    return true;
                }
            }

            return true;
        }
        public bool IsUpgradable(QualityModel currentQuality, QualityModel newQuality = null)
        {
            if (newQuality != null)
            {
                if (currentQuality >= newQuality)
                {
                    _logger.Trace("existing item has better or equal quality. skipping");
                    return false;
                }

                if (IsProperUpgrade(currentQuality, newQuality))
                {
                    return true;
                }
            }

            return true;
        }
        private IEnumerable<ImportDecision> GetDecisions(IEnumerable<String> videoFiles, Series series, bool sceneSource, QualityModel quality = null)
        {
            foreach (var file in videoFiles)
            {
                ImportDecision decision = null;

                try
                {
                    var parsedEpisode = _parsingService.GetLocalEpisode(file, series, sceneSource);
                    
                    if (parsedEpisode != null)
                    {
                        if (quality != null && new QualityModelComparer(parsedEpisode.Series.QualityProfile).Compare(quality, parsedEpisode.Quality) > 0)
                        {
                            _logger.Trace("Using quality from folder: {0}", quality);
                            parsedEpisode.Quality = quality;
                        }

                        parsedEpisode.Size = _diskProvider.GetFileSize(file);
                        _logger.Trace("Size: {0}", parsedEpisode.Size);

                        decision = GetDecision(parsedEpisode);
                    }

                    else
                    {
                        parsedEpisode = new LocalEpisode();
                        parsedEpisode.Path = file;

                        decision = new ImportDecision(parsedEpisode, "Unable to parse file");
                    }
                }
                catch (Exception e)
                {
                    _logger.ErrorException("Couldn't import file." + file, e);
                }

                if (decision != null)
                {
                    yield return decision;
                }
            }
        }
Exemple #29
0
        public virtual void UpdateEpisodeStatus(int episodeId, EpisodeStatusType episodeStatus, QualityModel quality)
        {
            try
            {
                logger.Trace("Sending Status update to client. EpisodeId: {0}, Status: {1}", episodeId, episodeStatus);

                GetClients().updatedStatus(new
                                               {
                                                       EpisodeId = episodeId,
                                                       EpisodeStatus = episodeStatus.ToString(),
                                                       Quality = (quality == null ? String.Empty : quality.Quality.ToString())
                                               });
            }
            catch (Exception ex)
            {
                logger.TraceException("Error", ex);
                throw;
            }
        }
        public bool IsUpgradable(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null)
        {
            if (newQuality != null)
            {
                int compare = new QualityModelComparer(profile).Compare(newQuality, currentQuality);
                if (compare <= 0)
                {
                    _logger.Trace("existing item has better or equal quality. skipping");
                    return false;
                }

                if (IsProperUpgrade(currentQuality, newQuality))
                {
                    return true;
                }
            }

            return true;
        }
Exemple #31
0
        private bool UseFolderQuality(ParsedEpisodeInfo folderInfo, QualityModel fileQuality, Series series)
        {
            if (folderInfo == null)
            {
                return(false);
            }

            if (folderInfo.Quality.Quality == Quality.Unknown)
            {
                return(false);
            }

            if (fileQuality.QualitySource == QualitySource.Extension)
            {
                return(true);
            }

            if (new QualityModelComparer(series.Profile).Compare(folderInfo.Quality, fileQuality) > 0)
            {
                return(true);
            }

            return(false);
        }
Exemple #32
0
        public ManualImportItem ReprocessItem(string path, string downloadId, int movieId, QualityModel quality, List <Language> languages)
        {
            var rootFolder = Path.GetDirectoryName(path);
            var movie      = _movieService.GetMovie(movieId);

            var downloadClientItem = GetTrackedDownload(downloadId)?.DownloadItem;

            var localEpisode = new LocalMovie
            {
                Movie                   = movie,
                FileMovieInfo           = Parser.Parser.ParseMoviePath(path),
                DownloadClientMovieInfo = downloadClientItem == null ? null : Parser.Parser.ParseMovieTitle(downloadClientItem.Title),
                Path         = path,
                SceneSource  = SceneSource(movie, rootFolder),
                ExistingFile = movie.Path.IsParentPath(path),
                Size         = _diskProvider.GetFileSize(path),
                Languages    = (languages?.SingleOrDefault() ?? Language.Unknown) == Language.Unknown ? LanguageParser.ParseLanguages(path) : languages,
                Quality      = quality.Quality == Quality.Unknown ? QualityParser.ParseQuality(path) : quality
            };

            return(MapItem(_importDecisionMaker.GetDecision(localEpisode, downloadClientItem), rootFolder, downloadId, null));
        }
        public bool QualityCutoffNotMet(Profile profile, QualityModel currentQuality, QualityModel newQuality = null)
        {
            var cutoff        = profile.UpgradeAllowed ? profile.Cutoff : profile.FirststAllowedQuality().Id;
            var cutoffCompare = new QualityModelComparer(profile).Compare(currentQuality.Quality.Id, cutoff);

            if (cutoffCompare < 0)
            {
                return(true);
            }

            if (newQuality != null && IsRevisionUpgrade(currentQuality, newQuality))
            {
                return(true);
            }

            return(false);
        }
 public int CreateQuality(QualityModel quality)
 {
     return(new SaveQualityOperation(_repository).Execute(quality));
 }
Exemple #35
0
        public virtual void UpdateEpisodeStatus(int episodeId, EpisodeStatusType episodeStatus, QualityModel quality)
        {
            try
            {
                logger.Trace("Sending Status update to client. EpisodeId: {0}, Status: {1}", episodeId, episodeStatus);

                var context = GlobalHost.ConnectionManager.GetHubContext <EpisodeHub>();
                context.Clients.updatedStatus(new
                {
                    EpisodeId     = episodeId,
                    EpisodeStatus = episodeStatus.ToString(),
                    Quality       = (quality == null ? String.Empty : quality.Quality.ToString())
                });
            }
            catch (Exception ex)
            {
                logger.TraceException("Error", ex);
                throw;
            }
        }
        public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
        {
            //How do we want to handle drone being off and the automatic search being triggered?
            //TODO: Add a flag to the search to state it is a "scheduled" search

            if (searchCriteria != null)
            {
                _logger.Debug("Ignore delay for searches");
                return(Decision.Accept());
            }

            var profile             = subject.Series.Profile.Value;
            var delayProfile        = _delayProfileService.BestForTags(subject.Series.Tags);
            var delay               = delayProfile.GetProtocolDelay(subject.Release.DownloadProtocol);
            var isPreferredProtocol = subject.Release.DownloadProtocol == delayProfile.PreferredProtocol;

            if (delay == 0)
            {
                _logger.Debug("Profile does not require a waiting period before download for {0}.", subject.Release.DownloadProtocol);
                return(Decision.Accept());
            }

            var comparer = new QualityModelComparer(profile);

            if (isPreferredProtocol)
            {
                foreach (var file in subject.Episodes.Where(c => c.EpisodeFileId != 0).Select(c => c.EpisodeFile.Value))
                {
                    var upgradable = _qualityUpgradableSpecification.IsUpgradable(profile, file.Quality, subject.ParsedEpisodeInfo.Quality);

                    if (upgradable)
                    {
                        var revisionUpgrade = _qualityUpgradableSpecification.IsRevisionUpgrade(file.Quality, subject.ParsedEpisodeInfo.Quality);

                        if (revisionUpgrade)
                        {
                            _logger.Debug("New quality is a better revision for existing quality, skipping delay");
                            return(Decision.Accept());
                        }
                    }
                }
            }

            //If quality meets or exceeds the best allowed quality in the profile accept it immediately
            var bestQualityInProfile = new QualityModel(profile.LastAllowedQuality());
            var isBestInProfile      = comparer.Compare(subject.ParsedEpisodeInfo.Quality, bestQualityInProfile) >= 0;

            if (isBestInProfile && isPreferredProtocol)
            {
                _logger.Debug("Quality is highest in profile for preferred protocol, will not delay");
                return(Decision.Accept());
            }

            var episodeIds = subject.Episodes.Select(e => e.Id);

            var oldest = _pendingReleaseService.OldestPendingRelease(subject.Series.Id, episodeIds);

            if (oldest != null && oldest.Release.AgeMinutes > delay)
            {
                return(Decision.Accept());
            }

            if (subject.Release.AgeMinutes < delay)
            {
                _logger.Debug("Waiting for better quality release, There is a {0} minute delay on {1}", delay, subject.Release.DownloadProtocol);
                return(Decision.Reject("Waiting for better quality release"));
            }

            return(Decision.Accept());
        }
        public bool IsUpgradeAllowed(QualityProfile qualityProfile, LanguageProfile languageProfile, QualityModel currentQuality, Language currentLanguage, QualityModel newQuality, Language newLanguage)
        {
            var isQualityUpgrade  = new QualityModelComparer(qualityProfile).Compare(newQuality, currentQuality) > 0;
            var isLanguageUpgrade = new LanguageComparer(languageProfile).Compare(newLanguage, currentLanguage) > 0;

            if (isQualityUpgrade && qualityProfile.UpgradeAllowed ||
                isLanguageUpgrade && languageProfile.UpgradeAllowed)
            {
                _logger.Debug("At least one profile allows upgrading");
                return(true);
            }

            if (isQualityUpgrade && !qualityProfile.UpgradeAllowed)
            {
                _logger.Debug("Quality profile does not allow upgrades, skipping");
                return(false);
            }

            if (isLanguageUpgrade && !languageProfile.UpgradeAllowed)
            {
                _logger.Debug("Language profile does not allow upgrades, skipping");
                return(false);
            }

            return(true);
        }
        public bool IsUpgradeAllowed(QualityProfile qualityProfile, List <QualityModel> currentQualities, QualityModel newQuality)
        {
            var isQualityUpgrade = IsQualityUpgradable(qualityProfile, currentQualities, newQuality);

            return(CheckUpgradeAllowed(qualityProfile, isQualityUpgrade));
        }
Exemple #39
0
        public ManualImportItem ReprocessItem(string path, string downloadId, int movieId, string releaseGroup, QualityModel quality, List <Language> languages)
        {
            var rootFolder = Path.GetDirectoryName(path);
            var movie      = _movieService.GetMovie(movieId);

            var downloadClientItem = GetTrackedDownload(downloadId)?.DownloadItem;

            var languageParse = LanguageParser.ParseLanguages(path);

            if (languageParse.Count <= 1 && languageParse.First() == Language.Unknown && movie != null)
            {
                languageParse = new List <Language> {
                    movie.OriginalLanguage
                };
                _logger.Debug("Language couldn't be parsed from release, fallback to movie original language: {0}", movie.OriginalLanguage.Name);
            }

            var localEpisode = new LocalMovie
            {
                Movie                   = movie,
                FileMovieInfo           = Parser.Parser.ParseMoviePath(path),
                DownloadClientMovieInfo = downloadClientItem == null ? null : Parser.Parser.ParseMovieTitle(downloadClientItem.Title),
                Path         = path,
                SceneSource  = SceneSource(movie, rootFolder),
                ExistingFile = movie.Path.IsParentPath(path),
                Size         = _diskProvider.GetFileSize(path),
                Languages    = (languages?.SingleOrDefault() ?? Language.Unknown) == Language.Unknown ? languageParse : languages,
                Quality      = quality.Quality == Quality.Unknown ? QualityParser.ParseQuality(path) : quality,
                ReleaseGroup = releaseGroup.IsNullOrWhiteSpace() ? Parser.Parser.ParseReleaseGroup(path) : releaseGroup,
            };

            return(MapItem(_importDecisionMaker.GetDecision(localEpisode, downloadClientItem), rootFolder, downloadId, null));
        }
Exemple #40
0
        public static QualityModel ParseQuality(string name)
        {
            Logger.Debug("Trying to parse quality for {0}", name);

            name = name.Trim();
            var normalizedName = name.Replace('_', ' ').Trim().ToLower();
            var result         = new QualityModel {
                Quality = Quality.Unknown
            };

            result.Proper = ProperRegex.IsMatch(normalizedName);

            if (RawHDRegex.IsMatch(normalizedName))
            {
                result.Quality = Quality.RAWHD;
                return(result);
            }

            var sourceMatch = SourceRegex.Match(normalizedName);
            var resolution  = ParseResolution(normalizedName);
            var codecRegex  = CodecRegex.Match(normalizedName);

            if (sourceMatch.Groups["bluray"].Success)
            {
                if (codecRegex.Groups["xvid"].Success || codecRegex.Groups["divx"].Success)
                {
                    result.Quality = Quality.DVD;
                    return(result);
                }

                if (resolution == Resolution._1080p)
                {
                    result.Quality = Quality.Bluray1080p;
                    return(result);
                }

                if (resolution == Resolution._480p || resolution == Resolution._576p)
                {
                    result.Quality = Quality.DVD;
                    return(result);
                }

                result.Quality = Quality.Bluray720p;
                return(result);
            }

            if (sourceMatch.Groups["webdl"].Success)
            {
                if (resolution == Resolution._1080p)
                {
                    result.Quality = Quality.WEBDL1080p;
                    return(result);
                }

                if (resolution == Resolution._720p)
                {
                    result.Quality = Quality.WEBDL720p;
                    return(result);
                }

                if (name.Contains("[WEBDL]"))
                {
                    result.Quality = Quality.WEBDL720p;
                    return(result);
                }

                result.Quality = Quality.WEBDL480p;
                return(result);
            }

            if (sourceMatch.Groups["hdtv"].Success)
            {
                if (resolution == Resolution._1080p)
                {
                    result.Quality = Quality.HDTV1080p;
                    return(result);
                }

                if (resolution == Resolution._720p)
                {
                    result.Quality = Quality.HDTV720p;
                    return(result);
                }

                if (name.Contains("[HDTV]"))
                {
                    result.Quality = Quality.HDTV720p;
                    return(result);
                }

                result.Quality = Quality.SDTV;
                return(result);
            }

            if (sourceMatch.Groups["bdrip"].Success ||
                sourceMatch.Groups["brrip"].Success)
            {
                if (resolution == Resolution._720p)
                {
                    result.Quality = Quality.Bluray720p;
                    return(result);
                }
                else if (resolution == Resolution._1080p)
                {
                    result.Quality = Quality.Bluray1080p;
                    return(result);
                }
                else
                {
                    result.Quality = Quality.DVD;
                    return(result);
                }
            }

            if (sourceMatch.Groups["dvd"].Success)
            {
                result.Quality = Quality.DVD;
                return(result);
            }

            if (sourceMatch.Groups["pdtv"].Success ||
                sourceMatch.Groups["sdtv"].Success ||
                sourceMatch.Groups["dsr"].Success)
            {
                result.Quality = Quality.SDTV;
                return(result);
            }

            if (resolution == Resolution._1080p)
            {
                result.Quality = Quality.HDTV1080p;
                return(result);
            }

            if (resolution == Resolution._720p)
            {
                result.Quality = Quality.HDTV720p;
                return(result);
            }

            if (codecRegex.Groups["x264"].Success)
            {
                result.Quality = Quality.SDTV;
                return(result);
            }

            if (normalizedName.Contains("bluray720p"))
            {
                result.Quality = Quality.Bluray720p;
            }

            if (normalizedName.Contains("bluray1080p"))
            {
                result.Quality = Quality.Bluray1080p;
            }

            //Based on extension
            if (result.Quality == Quality.Unknown && !name.ContainsInvalidPathChars())
            {
                try
                {
                    result.Quality = MediaFileExtensions.GetQualityForExtension(Path.GetExtension(name));
                }
                catch (ArgumentException)
                {
                    //Swallow exception for cases where string contains illegal
                    //path characters.
                }
            }

            return(result);
        }
Exemple #41
0
 public bool CutoffNotMet(Profile profile, QualityModel currentQuality, List <CustomFormat> currentFormats, QualityModel newQuality = null)
 {
     return(QualityCutoffNotMet(profile, currentQuality, newQuality) || CustomFormatCutoffNotMet(profile, currentFormats));
 }
 public void UpdateQuality(QualityModel quality)
 {
     new UpdateQualityOperation(_repository).Execute(quality);
 }
        private List <ImportDecision> ProcessFiles(Series series, QualityModel quality, params string[] videoFiles)
        {
            var decisions = _importDecisionMaker.GetImportDecisions(videoFiles.ToList(), series, true, quality);

            return(_importApprovedEpisodes.Import(decisions, true));
        }
        public bool IsUpgradable(QualityProfile qualityProfile, List <QualityModel> currentQualities, int currentScore, QualityModel newQuality, int newScore)
        {
            var qualityUpgrade = IsQualityUpgradable(qualityProfile, currentQualities, newQuality);

            if (qualityUpgrade == ProfileComparisonResult.Upgrade)
            {
                _logger.Debug("New item has a better quality");
                return(true);
            }

            if (qualityUpgrade == ProfileComparisonResult.Downgrade)
            {
                _logger.Debug("Existing item has better quality, skipping");
                return(false);
            }

            if (!IsPreferredWordUpgradable(currentScore, newScore))
            {
                _logger.Debug("Existing item has a better preferred word score, skipping");
                return(false);
            }

            _logger.Debug("New item has a better preferred word score");
            return(true);
        }
        public bool CutoffNotMet(QualityProfile profile, LanguageProfile languageProfile, QualityModel currentQuality, Language currentLanguage, int currentScore, QualityModel newQuality = null, int newScore = 0)
        {
            // If we can upgrade the language (it is not the cutoff) then the quality doesn't
            // matter as we can always get same quality with prefered language.
            if (LanguageCutoffNotMet(languageProfile, currentLanguage))
            {
                return(true);
            }

            if (QualityCutoffNotMet(profile, currentQuality, newQuality))
            {
                return(true);
            }

            if (IsPreferredWordUpgradable(currentScore, newScore))
            {
                return(true);
            }

            _logger.Debug("Existing item meets cut-off. skipping.");

            return(false);
        }
Exemple #46
0
        public ManualImportItem ReprocessItem(string path, string downloadId, int seriesId, int?seasonNumber, List <int> episodeIds, string releaseGroup, QualityModel quality, Language language)
        {
            var rootFolder = Path.GetDirectoryName(path);
            var series     = _seriesService.GetSeries(seriesId);

            if (episodeIds.Any())
            {
                var downloadClientItem = GetTrackedDownload(downloadId)?.DownloadItem;

                var localEpisode = new LocalEpisode();
                localEpisode.Series                    = series;
                localEpisode.Episodes                  = _episodeService.GetEpisodes(episodeIds);
                localEpisode.FileEpisodeInfo           = Parser.Parser.ParsePath(path);
                localEpisode.DownloadClientEpisodeInfo = downloadClientItem == null ? null : Parser.Parser.ParseTitle(downloadClientItem.Title);
                localEpisode.Path         = path;
                localEpisode.SceneSource  = SceneSource(series, rootFolder);
                localEpisode.ExistingFile = series.Path.IsParentPath(path);
                localEpisode.Size         = _diskProvider.GetFileSize(path);
                localEpisode.ReleaseGroup = releaseGroup.IsNullOrWhiteSpace() ? Parser.Parser.ParseReleaseGroup(path) : releaseGroup;
                localEpisode.Language     = language == Language.Unknown ? LanguageParser.ParseLanguage(path) : language;
                localEpisode.Quality      = quality.Quality == Quality.Unknown ? QualityParser.ParseQuality(path) : quality;

                return(MapItem(_importDecisionMaker.GetDecision(localEpisode, downloadClientItem), rootFolder, downloadId, null));
            }

            // This case will happen if the user selected a season, but didn't select the episodes in the season then changed the language or quality.
            // Instead of overriding their season selection let it persist and reject it with an appropriate error.

            if (seasonNumber.HasValue)
            {
                var downloadClientItem = GetTrackedDownload(downloadId)?.DownloadItem;

                var localEpisode = new LocalEpisode
                {
                    Series                    = series,
                    Episodes                  = new List <Episode>(),
                    FileEpisodeInfo           = Parser.Parser.ParsePath(path),
                    DownloadClientEpisodeInfo = downloadClientItem == null
                                           ? null
                                           : Parser.Parser.ParseTitle(downloadClientItem.Title),
                    Path         = path,
                    SceneSource  = SceneSource(series, rootFolder),
                    ExistingFile = series.Path.IsParentPath(path),
                    Size         = _diskProvider.GetFileSize(path),
                    ReleaseGroup = releaseGroup.IsNullOrWhiteSpace() ? Parser.Parser.ParseReleaseGroup(path) : releaseGroup,
                    Language     = language == Language.Unknown ? LanguageParser.ParseLanguage(path) : language,
                    Quality      = quality.Quality == Quality.Unknown ? QualityParser.ParseQuality(path) : quality
                };

                return(MapItem(new ImportDecision(localEpisode, new Rejection("Episodes not selected")), rootFolder, downloadId, null));
            }

            return(ProcessFile(rootFolder, rootFolder, path, downloadId, series));
        }
        public bool IsUpgradable(QualityProfile qualityProfile, LanguageProfile languageProfile, QualityModel currentQuality, Language currentLanguage, int currentScore, QualityModel newQuality, Language newLanguage, int newScore)
        {
            var qualityComparer = new QualityModelComparer(qualityProfile);
            var qualityCompare  = qualityComparer.Compare(newQuality?.Quality, currentQuality.Quality);

            if (qualityCompare > 0)
            {
                _logger.Debug("New item has a better quality");
                return(true);
            }

            if (qualityCompare < 0)
            {
                _logger.Debug("Existing item has better quality, skipping");
                return(false);
            }

            // Accept unless the user doesn't want to prefer propers, optionally they can
            // use preferred words to prefer propers/repacks over non-propers/repacks.
            if (_configService.DownloadPropersAndRepacks != ProperDownloadTypes.DoNotPrefer &&
                newQuality?.Revision.CompareTo(currentQuality.Revision) > 0)
            {
                _logger.Debug("New item has a better quality revision");
                return(true);
            }

            var languageCompare = new LanguageComparer(languageProfile).Compare(newLanguage, currentLanguage);

            if (languageCompare > 0)
            {
                _logger.Debug("New item has a more preferred language");
                return(true);
            }

            if (languageCompare < 0)
            {
                _logger.Debug("Existing item has better language, skipping");
                return(false);
            }

            if (!IsPreferredWordUpgradable(currentScore, newScore))
            {
                _logger.Debug("Existing item has a better preferred word score, skipping");
                return(false);
            }

            _logger.Debug("New item has a better preferred word score");
            return(true);
        }
Exemple #48
0
        public List <ImportDecision> GetImportDecisions(List <string> videoFiles, Series series, bool sceneSource, QualityModel quality = null)
        {
            var newFiles = _mediaFileService.FilterExistingFiles(videoFiles.ToList(), series);

            _logger.Debug("Analyzing {0}/{1} files.", newFiles.Count, videoFiles.Count());

            return(GetDecisions(newFiles, series, sceneSource, quality).ToList());
        }
        public void Setup()
        {
            _albumpass1 = new Mock <IImportDecisionEngineSpecification <LocalAlbumRelease> >();
            _albumpass2 = new Mock <IImportDecisionEngineSpecification <LocalAlbumRelease> >();
            _albumpass3 = new Mock <IImportDecisionEngineSpecification <LocalAlbumRelease> >();

            _albumfail1 = new Mock <IImportDecisionEngineSpecification <LocalAlbumRelease> >();
            _albumfail2 = new Mock <IImportDecisionEngineSpecification <LocalAlbumRelease> >();
            _albumfail3 = new Mock <IImportDecisionEngineSpecification <LocalAlbumRelease> >();


            _pass1 = new Mock <IImportDecisionEngineSpecification <LocalTrack> >();
            _pass2 = new Mock <IImportDecisionEngineSpecification <LocalTrack> >();
            _pass3 = new Mock <IImportDecisionEngineSpecification <LocalTrack> >();

            _fail1 = new Mock <IImportDecisionEngineSpecification <LocalTrack> >();
            _fail2 = new Mock <IImportDecisionEngineSpecification <LocalTrack> >();
            _fail3 = new Mock <IImportDecisionEngineSpecification <LocalTrack> >();

            _albumpass1.Setup(c => c.IsSatisfiedBy(It.IsAny <LocalAlbumRelease>())).Returns(Decision.Accept());
            _albumpass2.Setup(c => c.IsSatisfiedBy(It.IsAny <LocalAlbumRelease>())).Returns(Decision.Accept());
            _albumpass3.Setup(c => c.IsSatisfiedBy(It.IsAny <LocalAlbumRelease>())).Returns(Decision.Accept());

            _albumfail1.Setup(c => c.IsSatisfiedBy(It.IsAny <LocalAlbumRelease>())).Returns(Decision.Reject("_albumfail1"));
            _albumfail2.Setup(c => c.IsSatisfiedBy(It.IsAny <LocalAlbumRelease>())).Returns(Decision.Reject("_albumfail2"));
            _albumfail3.Setup(c => c.IsSatisfiedBy(It.IsAny <LocalAlbumRelease>())).Returns(Decision.Reject("_albumfail3"));

            _pass1.Setup(c => c.IsSatisfiedBy(It.IsAny <LocalTrack>())).Returns(Decision.Accept());
            _pass2.Setup(c => c.IsSatisfiedBy(It.IsAny <LocalTrack>())).Returns(Decision.Accept());
            _pass3.Setup(c => c.IsSatisfiedBy(It.IsAny <LocalTrack>())).Returns(Decision.Accept());

            _fail1.Setup(c => c.IsSatisfiedBy(It.IsAny <LocalTrack>())).Returns(Decision.Reject("_fail1"));
            _fail2.Setup(c => c.IsSatisfiedBy(It.IsAny <LocalTrack>())).Returns(Decision.Reject("_fail2"));
            _fail3.Setup(c => c.IsSatisfiedBy(It.IsAny <LocalTrack>())).Returns(Decision.Reject("_fail3"));

            _artist = Builder <Artist> .CreateNew()
                      .With(e => e.QualityProfile = new QualityProfile {
                Items = Qualities.QualityFixture.GetDefaultQualities()
            })
                      .Build();

            _albumRelease = Builder <AlbumRelease> .CreateNew()
                            .Build();

            _quality = new QualityModel(Quality.MP3_256);

            _localTrack = new LocalTrack
            {
                Artist  = _artist,
                Quality = _quality,
                Tracks  = new List <Track> {
                    new Track()
                },
                Path = @"C:\Test\Unsorted\The.Office.S03E115.DVDRip.XviD-OSiTV.avi".AsOsAgnostic()
            };

            GivenAudioFiles(new List <string> {
                @"C:\Test\Unsorted\The.Office.S03E115.DVDRip.XviD-OSiTV.avi".AsOsAgnostic()
            });

            Mocker.GetMock <IIdentificationService>()
            .Setup(s => s.Identify(It.IsAny <List <LocalTrack> >(), It.IsAny <Artist>(), It.IsAny <Album>(), It.IsAny <AlbumRelease>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <bool>()))
            .Returns((List <LocalTrack> tracks, Artist artist, Album album, AlbumRelease release, bool newDownload, bool singleRelease, bool includeExisting) => {
                var ret          = new LocalAlbumRelease(tracks);
                ret.AlbumRelease = _albumRelease;
                return(new List <LocalAlbumRelease> {
                    ret
                });
            });

            Mocker.GetMock <IMediaFileService>()
            .Setup(c => c.FilterUnchangedFiles(It.IsAny <List <IFileInfo> >(), It.IsAny <Artist>(), It.IsAny <FilterFilesType>()))
            .Returns((List <IFileInfo> files, Artist artist, FilterFilesType filter) => files);

            GivenSpecifications(_albumpass1);
        }
Exemple #50
0
        public LocalEpisode Aggregate(LocalEpisode localEpisode, DownloadClientItem downloadClientItem)
        {
            var source               = QualitySource.Unknown;
            var sourceConfidence     = Confidence.Default;
            var resolution           = 0;
            var resolutionConfidence = Confidence.Default;
            var revision             = new Revision(1);
            var revisionConfidence   = Confidence.Default;

            foreach (var augmentQuality in _augmentQualities)
            {
                var augmentedQuality = augmentQuality.AugmentQuality(localEpisode, downloadClientItem);
                if (augmentedQuality == null)
                {
                    continue;
                }

                _logger.Trace("Considering Source {0} ({1}) Resolution {2} ({3}) Revision {4} from {5}", augmentedQuality.Source, augmentedQuality.SourceConfidence, augmentedQuality.Resolution, augmentedQuality.ResolutionConfidence, augmentedQuality.Revision, augmentQuality.Name);

                if (source == QualitySource.Unknown ||
                    augmentedQuality.SourceConfidence > sourceConfidence && augmentedQuality.Source != QualitySource.Unknown)
                {
                    source           = augmentedQuality.Source;
                    sourceConfidence = augmentedQuality.SourceConfidence;
                }

                if (resolution == 0 ||
                    augmentedQuality.ResolutionConfidence > resolutionConfidence && augmentedQuality.Resolution > 0)
                {
                    resolution           = augmentedQuality.Resolution;
                    resolutionConfidence = augmentedQuality.ResolutionConfidence;
                }

                if (augmentedQuality.Revision != null)
                {
                    // Update the revision and confidence if it is higher than the current confidence,
                    // this will allow explicitly detected v0 to override the v1 default.
                    if (augmentedQuality.RevisionConfidence > revisionConfidence)
                    {
                        revision           = augmentedQuality.Revision;
                        revisionConfidence = augmentedQuality.RevisionConfidence;
                    }
                    // Update the revision and confidence if it is the same confidence and the revision is higher,
                    // this will allow the best revision to be used in the event there is a disagreement.
                    else if (augmentedQuality.RevisionConfidence == revisionConfidence &&
                             augmentedQuality.Revision > revision)
                    {
                        revision           = augmentedQuality.Revision;
                        revisionConfidence = augmentedQuality.RevisionConfidence;
                    }
                }
            }

            _logger.Trace("Selected Source {0} ({1}) Resolution {2} ({3}) Revision {4}", source, sourceConfidence, resolution, resolutionConfidence, revision);

            var quality = new QualityModel(QualityFinder.FindBySourceAndResolution(source, resolution), revision);

            if (resolutionConfidence == Confidence.MediaInfo)
            {
                quality.ResolutionDetectionSource = QualityDetectionSource.MediaInfo;
            }
            else if (resolutionConfidence == Confidence.Fallback)
            {
                quality.ResolutionDetectionSource = QualityDetectionSource.Extension;
            }
            else
            {
                quality.ResolutionDetectionSource = QualityDetectionSource.Name;
            }

            if (sourceConfidence == Confidence.Fallback)
            {
                quality.SourceDetectionSource = QualityDetectionSource.Extension;
            }
            else
            {
                quality.SourceDetectionSource = QualityDetectionSource.Name;
            }

            quality.RevisionDetectionSource = revisionConfidence == Confidence.Tag ? QualityDetectionSource.Name : QualityDetectionSource.Unknown;

            _logger.Debug("Using quality: {0}", quality);

            localEpisode.Quality = quality;

            return(localEpisode);
        }
        public bool CutoffNotMet(QualityProfile profile, List <QualityModel> currentQualities, int currentScore, QualityModel newQuality = null, int newScore = 0)
        {
            foreach (var quality in currentQualities)
            {
                if (QualityCutoffNotMet(profile, quality, newQuality))
                {
                    return(true);
                }
            }

            if (IsPreferredWordUpgradable(currentScore, newScore))
            {
                return(true);
            }

            _logger.Debug("Existing item meets cut-off. skipping.");

            return(false);
        }
Exemple #52
0
        public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
        {
            if (searchCriteria != null && searchCriteria.UserInvokedSearch)
            {
                _logger.Debug("Ignoring delay for user invoked search");
                return(Decision.Accept());
            }

            var profile             = subject.Movie.Profile.Value;
            var delayProfile        = _delayProfileService.BestForTags(subject.Movie.Tags);
            var delay               = delayProfile.GetProtocolDelay(subject.Release.DownloadProtocol);
            var isPreferredProtocol = subject.Release.DownloadProtocol == delayProfile.PreferredProtocol;

            // Preferred word count
            var title          = subject.Release.Title;
            var preferredWords = subject.Movie.Profile.Value.PreferredTags;
            var preferredCount = 0;

            if (preferredWords == null)
            {
                preferredCount = 1;
                _logger.Debug("Preferred words is null, setting preffered count to 1.");
            }
            else
            {
                preferredCount = preferredWords.AsEnumerable().Count(w => title.ToLower().Contains(w.ToLower()));
            }

            if (delay == 0)
            {
                _logger.Debug("Profile does not require a waiting period before download for {0}.", subject.Release.DownloadProtocol);
                return(Decision.Accept());
            }

            var comparer = new QualityModelComparer(profile);

            if (isPreferredProtocol && (subject.Movie.MovieFileId != 0 && subject.Movie.MovieFile != null) && (preferredCount > 0 || preferredWords == null))
            {
                var upgradable = _qualityUpgradableSpecification.IsUpgradable(profile, subject.Movie.MovieFile.Value.Quality, subject.ParsedMovieInfo.Quality);

                if (upgradable)
                {
                    var revisionUpgrade = _qualityUpgradableSpecification.IsRevisionUpgrade(subject.Movie.MovieFile.Value.Quality, subject.ParsedMovieInfo.Quality);

                    if (revisionUpgrade)
                    {
                        _logger.Debug("New quality is a better revision for existing quality and preferred word count is {0}, skipping delay", preferredCount);
                        return(Decision.Accept());
                    }
                }
            }

            // If quality meets or exceeds the best allowed quality in the profile accept it immediately
            var bestQualityInProfile = new QualityModel(profile.LastAllowedQuality());
            var isBestInProfile      = comparer.Compare(subject.ParsedMovieInfo.Quality, bestQualityInProfile) >= 0;

            if (isBestInProfile && isPreferredProtocol && (preferredCount > 0 || preferredWords == null))
            {
                _logger.Debug("Quality is highest in profile for preferred protocol and preferred word count is {0}, will not delay.", preferredCount);
                return(Decision.Accept());
            }


            var oldest = _pendingReleaseService.OldestPendingRelease(subject.Movie.Id);

            if (oldest != null && oldest.Release.AgeMinutes > delay)
            {
                return(Decision.Accept());
            }

            if (subject.Release.AgeMinutes < delay)
            {
                _logger.Debug("Waiting for better quality release, There is a {0} minute delay on {1}", delay, subject.Release.DownloadProtocol);
                return(Decision.Reject("Waiting for better quality release"));
            }

            return(Decision.Accept());
        }
        private ProfileComparisonResult IsQualityUpgradable(QualityProfile profile, List <QualityModel> currentQualities, QualityModel newQuality = null)
        {
            if (newQuality != null)
            {
                var totalCompare = 0;

                foreach (var quality in currentQualities)
                {
                    var compare = new QualityModelComparer(profile).Compare(newQuality, quality);

                    totalCompare += compare;

                    if (compare < 0)
                    {
                        // Not upgradable if new quality is a downgrade for any current quality
                        return(ProfileComparisonResult.Downgrade);
                    }
                }

                // Not upgradable if new quality is equal to all current qualities
                if (totalCompare == 0)
                {
                    return(ProfileComparisonResult.Equal);
                }

                // Quality Treated as Equal if Propers are not Prefered
                if (_configService.DownloadPropersAndRepacks == ProperDownloadTypes.DoNotPrefer &&
                    newQuality.Revision.CompareTo(currentQualities.Min(q => q.Revision)) > 0)
                {
                    return(ProfileComparisonResult.Equal);
                }
            }

            return(ProfileComparisonResult.Upgrade);
        }
        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 bool QualityCutoffNotMet(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null)
        {
            var cutoffCompare = new QualityModelComparer(profile).Compare(currentQuality.Quality.Id, profile.Cutoff);

            if (cutoffCompare < 0)
            {
                return(true);
            }

            if (newQuality != null && IsRevisionUpgrade(currentQuality, newQuality))
            {
                return(true);
            }

            return(false);
        }
        public bool CutoffNotMet(Profile profile, QualityModel currentQuality, List <CustomFormat> currentFormats, QualityModel newQuality = null)
        {
            if (QualityCutoffNotMet(profile, currentQuality, newQuality))
            {
                return(true);
            }

            if (CustomFormatCutoffNotMet(profile, currentFormats))
            {
                return(true);
            }

            _logger.Debug("Existing item meets cut-off. skipping.");

            return(false);
        }
        public bool IsUpgradeAllowed(Profile qualityProfile, QualityModel currentQuality, List <CustomFormat> currentCustomFormats, QualityModel newQuality, List <CustomFormat> newCustomFormats)
        {
            var isQualityUpgrade      = new QualityModelComparer(qualityProfile).Compare(newQuality, currentQuality) > 0;
            var isCustomFormatUpgrade = qualityProfile.CalculateCustomFormatScore(newCustomFormats) > qualityProfile.CalculateCustomFormatScore(currentCustomFormats);

            if ((isQualityUpgrade || isCustomFormatUpgrade) && qualityProfile.UpgradeAllowed)
            {
                _logger.Debug("Quality profile allows upgrading");
                return(true);
            }

            return(false);
        }
        public bool IsUpgradable(Profile profile, QualityModel currentQuality, List <CustomFormat> currentCustomFormats, QualityModel newQuality, List <CustomFormat> newCustomFormats)
        {
            var qualityComparer           = new QualityModelComparer(profile);
            var qualityCompare            = qualityComparer.Compare(newQuality?.Quality, currentQuality.Quality);
            var downloadPropersAndRepacks = _configService.DownloadPropersAndRepacks;

            if (qualityCompare > 0)
            {
                _logger.Debug("New item has a better quality");
                return(true);
            }

            if (qualityCompare < 0)
            {
                _logger.Debug("Existing item has better quality, skipping");
                return(false);
            }

            var qualityRevisionCompare = newQuality?.Revision.CompareTo(currentQuality.Revision);

            // Accept unless the user doesn't want to prefer propers, optionally they can
            // use preferred words to prefer propers/repacks over non-propers/repacks.
            if (downloadPropersAndRepacks != ProperDownloadTypes.DoNotPrefer &&
                qualityRevisionCompare > 0)
            {
                return(true);
            }

            var currentFormatScore = profile.CalculateCustomFormatScore(currentCustomFormats);
            var newFormatScore     = profile.CalculateCustomFormatScore(newCustomFormats);

            // Reject unless the user does not prefer propers/repacks and it's a revision downgrade.
            if (downloadPropersAndRepacks != ProperDownloadTypes.DoNotPrefer &&
                qualityRevisionCompare < 0)
            {
                _logger.Debug("Existing item has a better quality revision, skipping");
                return(false);
            }

            if (newFormatScore <= currentFormatScore)
            {
                _logger.Debug("New item's custom formats [{0}] do not improve on [{1}], skipping",
                              newCustomFormats.ConcatToString(),
                              currentCustomFormats.ConcatToString());
                return(false);
            }

            _logger.Debug("New item has a custom format upgrade");
            return(true);
        }
Exemple #59
0
        private IEnumerable <ImportDecision> GetDecisions(IEnumerable <String> videoFiles, Series series, bool sceneSource, QualityModel quality = null)
        {
            foreach (var file in videoFiles)
            {
                ImportDecision decision = null;

                try
                {
                    var localEpisode = _parsingService.GetLocalEpisode(file, series, sceneSource);

                    if (localEpisode != null)
                    {
                        if (quality != null &&
                            new QualityModelComparer(localEpisode.Series.Profile).Compare(quality,
                                                                                          localEpisode.Quality) > 0)
                        {
                            _logger.Debug("Using quality from folder: {0}", quality);
                            localEpisode.Quality = quality;
                        }

                        localEpisode.Size = _diskProvider.GetFileSize(file);
                        _logger.Debug("Size: {0}", localEpisode.Size);

                        //TODO: make it so media info doesn't ruin the import process of a new series
                        if (sceneSource)
                        {
                            localEpisode.MediaInfo = _videoFileInfoReader.GetMediaInfo(file);
                        }

                        decision = GetDecision(localEpisode);
                    }

                    else
                    {
                        localEpisode      = new LocalEpisode();
                        localEpisode.Path = file;

                        decision = new ImportDecision(localEpisode, "Unable to parse file");
                    }
                }
                catch (EpisodeNotFoundException e)
                {
                    var localEpisode = new LocalEpisode();
                    localEpisode.Path = file;

                    decision = new ImportDecision(localEpisode, e.Message);
                }
                catch (Exception e)
                {
                    _logger.ErrorException("Couldn't import file. " + file, e);
                }

                if (decision != null)
                {
                    yield return(decision);
                }
            }
        }
Exemple #60
0
        public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
        {
            //How do we want to handle drone being off and the automatic search being triggered?
            //TODO: Add a flag to the search to state it is a "scheduled" search

            if (searchCriteria != null)
            {
                _logger.Debug("Ignore delay for searches");
                return(true);
            }

            var profile = subject.Series.Profile.Value;

            if (profile.GrabDelay == 0)
            {
                _logger.Debug("Profile does not delay before download");
                return(true);
            }

            var comparer = new QualityModelComparer(profile);

            foreach (var file in subject.Episodes.Where(c => c.EpisodeFileId != 0).Select(c => c.EpisodeFile.Value))
            {
                var upgradable = _qualityUpgradableSpecification.IsUpgradable(profile, file.Quality, subject.ParsedEpisodeInfo.Quality);

                if (upgradable)
                {
                    var revisionUpgrade = _qualityUpgradableSpecification.IsRevisionUpgrade(file.Quality, subject.ParsedEpisodeInfo.Quality);

                    if (revisionUpgrade)
                    {
                        _logger.Debug("New quality is a better revision for existing quality, skipping delay");
                        return(true);
                    }
                }
            }

            //If quality meets or exceeds the best allowed quality in the profile accept it immediately
            var bestQualityInProfile = new QualityModel(profile.Items.Last(q => q.Allowed).Quality);
            var bestCompare          = comparer.Compare(subject.ParsedEpisodeInfo.Quality, bestQualityInProfile);

            if (bestCompare >= 0)
            {
                _logger.Debug("Quality is highest in profile, will not delay");
                return(true);
            }

            if (profile.GrabDelayMode == GrabDelayMode.Cutoff)
            {
                var cutoff        = new QualityModel(profile.Cutoff);
                var cutoffCompare = comparer.Compare(subject.ParsedEpisodeInfo.Quality, cutoff);

                if (cutoffCompare >= 0)
                {
                    _logger.Debug("Quality meets or exceeds the cutoff, will not delay");
                    return(true);
                }
            }

            if (profile.GrabDelayMode == GrabDelayMode.First)
            {
                var episodeIds = subject.Episodes.Select(e => e.Id);

                var oldest = _pendingReleaseService.GetPendingRemoteEpisodes(subject.Series.Id)
                             .Where(r => r.Episodes.Select(e => e.Id).Intersect(episodeIds).Any())
                             .OrderByDescending(p => p.Release.AgeHours)
                             .FirstOrDefault();

                if (oldest != null && oldest.Release.AgeHours > profile.GrabDelay)
                {
                    return(true);
                }
            }

            if (subject.Release.AgeHours < profile.GrabDelay)
            {
                _logger.Debug("Age ({0}) is less than delay {1}, delaying", subject.Release.AgeHours, profile.GrabDelay);
                return(false);
            }

            return(true);
        }