Beispiel #1
0
        protected override ReleaseResource MapDecision(DownloadDecision decision, int initialWeight)
        {
            var resource = base.MapDecision(decision, initialWeight);

            _remoteMovieCache.Set(GetCacheKey(resource), decision.RemoteMovie, TimeSpan.FromMinutes(30));

            return(resource);
        }
Beispiel #2
0
        private bool IsMovieProcessed(List <DownloadDecision> decisions, DownloadDecision report)
        {
            var movieId = report.RemoteMovie.Movie.Id;

            return(decisions.Select(r => r.RemoteMovie.Movie)
                   .Select(e => e.Id)
                   .ToList()
                   .Contains(movieId));
        }
        public void Setup()
        {
            _movie = Builder <Movie> .CreateNew()
                     .Build();


            _profile = new Profile
            {
                Name   = "Test",
                Cutoff = Quality.HDTV720p,
                Items  = new List <ProfileQualityItem>
                {
                    new ProfileQualityItem {
                        Allowed = true, Quality = Quality.HDTV720p
                    },
                    new ProfileQualityItem {
                        Allowed = true, Quality = Quality.WEBDL720p
                    },
                    new ProfileQualityItem {
                        Allowed = true, Quality = Quality.Bluray720p
                    }
                },
            };

            _movie.Profile = new LazyLoaded <Profile>(_profile);

            _release = Builder <ReleaseInfo> .CreateNew().Build();

            _parsedMovieInfo = Builder <ParsedMovieInfo> .CreateNew().Build();

            _parsedMovieInfo.Quality = new QualityModel(Quality.HDTV720p);

            _remoteMovie = new RemoteMovie();
            //_remoteEpisode.Episodes = new List<Episode>{ _episode };
            _remoteMovie.Movie           = _movie;
            _remoteMovie.ParsedMovieInfo = _parsedMovieInfo;
            _remoteMovie.Release         = _release;

            _temporarilyRejected = new DownloadDecision(_remoteMovie, new Rejection("Temp Rejected", RejectionType.Temporary));

            Mocker.GetMock <IPendingReleaseRepository>()
            .Setup(s => s.All())
            .Returns(new List <PendingRelease>());

            Mocker.GetMock <IMovieService>()
            .Setup(s => s.GetMovie(It.IsAny <int>()))
            .Returns(_movie);

            Mocker.GetMock <IParsingService>()
            .Setup(s => s.GetMovie(It.IsAny <string>()))
            .Returns(_movie);

            Mocker.GetMock <IPrioritizeDownloadDecision>()
            .Setup(s => s.PrioritizeDecisions(It.IsAny <List <DownloadDecision> >()))
            .Returns((List <DownloadDecision> d) => d);
        }
Beispiel #4
0
        public void Setup()
        {
            _movie = Builder <Movie> .CreateNew()
                     .Build();

            _profile = new Profile
            {
                Name   = "Test",
                Cutoff = Quality.HDTV720p.Id,
                Items  = new List <ProfileQualityItem>
                {
                    new ProfileQualityItem {
                        Allowed = true, Quality = Quality.HDTV720p
                    },
                    new ProfileQualityItem {
                        Allowed = true, Quality = Quality.WEBDL720p
                    },
                    new ProfileQualityItem {
                        Allowed = true, Quality = Quality.Bluray720p
                    }
                },
            };

            _movie.Profile = _profile;

            _release = Builder <ReleaseInfo> .CreateNew().Build();

            _parsedMovieInfo = Builder <ParsedMovieInfo> .CreateNew().Build();

            _parsedMovieInfo.Quality = new QualityModel(Quality.HDTV720p);

            _remoteMovie                 = new RemoteMovie();
            _remoteMovie.Movie           = _movie;
            _remoteMovie.ParsedMovieInfo = _parsedMovieInfo;
            _remoteMovie.Release         = _release;

            _temporarilyRejected = new DownloadDecision(_remoteMovie, new Rejection("Temp Rejected", RejectionType.Temporary));

            _heldReleases = new List <PendingRelease>();

            Mocker.GetMock <IPendingReleaseRepository>()
            .Setup(s => s.All())
            .Returns(_heldReleases);

            Mocker.GetMock <IPendingReleaseRepository>()
            .Setup(s => s.AllByMovieId(It.IsAny <int>()))
            .Returns <int>(i => _heldReleases.Where(v => v.MovieId == i).ToList());

            Mocker.GetMock <IMovieService>()
            .Setup(s => s.GetMovie(It.IsAny <int>()))
            .Returns(_movie);

            Mocker.GetMock <IPrioritizeDownloadDecision>()
            .Setup(s => s.PrioritizeDecisionsForMovies(It.IsAny <List <DownloadDecision> >()))
            .Returns((List <DownloadDecision> d) => d);
        }
        private bool IsEpisodeProcessed(List <DownloadDecision> decisions, DownloadDecision report)
        {
            var episodeIds = report.RemoteEpisode.Episodes.Select(e => e.Id).ToList();

            return(decisions.SelectMany(r => r.RemoteEpisode.Episodes)
                   .Select(e => e.Id)
                   .ToList()
                   .Intersect(episodeIds)
                   .Any());
        }
Beispiel #6
0
        private bool IsBookProcessed(List <DownloadDecision> decisions, DownloadDecision report)
        {
            var bookIds = report.RemoteBook.Books.Select(e => e.Id).ToList();

            return(decisions.SelectMany(r => r.RemoteBook.Books)
                   .Select(e => e.Id)
                   .ToList()
                   .Intersect(bookIds)
                   .Any());
        }
Beispiel #7
0
        private bool IsAlbumProcessed(List <DownloadDecision> decisions, DownloadDecision report)
        {
            var albumIds = report.RemoteAlbum.Albums.Select(e => e.Id).ToList();

            return(decisions.SelectMany(r => r.RemoteAlbum.Albums)
                   .Select(e => e.Id)
                   .ToList()
                   .Intersect(albumIds)
                   .Any());
        }
Beispiel #8
0
        public static ReleaseResource ToResource(this DownloadDecision model)
        {
            var releaseInfo       = model.RemoteEpisode.Release;
            var parsedEpisodeInfo = model.RemoteEpisode.ParsedEpisodeInfo;
            var remoteEpisode     = model.RemoteEpisode;
            var torrentInfo       = (model.RemoteEpisode.Release as TorrentInfo) ?? new TorrentInfo();

            // TODO: Clean this mess up. don't mix data from multiple classes, use sub-resources instead? (Got a huge Deja Vu, didn't we talk about this already once?)
            return(new ReleaseResource
            {
                Guid = releaseInfo.Guid,
                Quality = parsedEpisodeInfo.Quality,
                //QualityWeight
                Age = releaseInfo.Age,
                AgeHours = releaseInfo.AgeHours,
                AgeMinutes = releaseInfo.AgeMinutes,
                Size = releaseInfo.Size,
                IndexerId = releaseInfo.IndexerId,
                Indexer = releaseInfo.Indexer,
                ReleaseGroup = parsedEpisodeInfo.ReleaseGroup,
                ReleaseHash = parsedEpisodeInfo.ReleaseHash,
                Title = releaseInfo.Title,
                FullSeason = parsedEpisodeInfo.FullSeason,
                SeasonNumber = parsedEpisodeInfo.SeasonNumber,
                Language = parsedEpisodeInfo.Language,
                AirDate = parsedEpisodeInfo.AirDate,
                SeriesTitle = parsedEpisodeInfo.SeriesTitle,
                EpisodeNumbers = parsedEpisodeInfo.EpisodeNumbers,
                AbsoluteEpisodeNumbers = parsedEpisodeInfo.AbsoluteEpisodeNumbers,
                Approved = model.Approved,
                TemporarilyRejected = model.TemporarilyRejected,
                Rejected = model.Rejected,
                TvdbId = releaseInfo.TvdbId,
                TvRageId = releaseInfo.TvRageId,
                Rejections = model.Rejections.Select(r => r.Reason).ToList(),
                PublishDate = releaseInfo.PublishDate,
                CommentUrl = releaseInfo.CommentUrl,
                DownloadUrl = releaseInfo.DownloadUrl,
                InfoUrl = releaseInfo.InfoUrl,
                DownloadAllowed = remoteEpisode.DownloadAllowed,
                //ReleaseWeight
                PreferredWordScore = remoteEpisode.PreferredWordScore,

                MagnetUrl = torrentInfo.MagnetUrl,
                InfoHash = torrentInfo.InfoHash,
                Seeders = torrentInfo.Seeders,
                Leechers = (torrentInfo.Peers.HasValue && torrentInfo.Seeders.HasValue) ? (torrentInfo.Peers.Value - torrentInfo.Seeders.Value) : (int?)null,
                Protocol = releaseInfo.DownloadProtocol,

                IsDaily = parsedEpisodeInfo.IsDaily,
                IsAbsoluteNumbering = parsedEpisodeInfo.IsAbsoluteNumbering,
                IsPossibleSpecialEpisode = parsedEpisodeInfo.IsPossibleSpecialEpisode,
                Special = parsedEpisodeInfo.Special,
            });
        }
Beispiel #9
0
        public static ReleaseResource ToResource(this DownloadDecision model)
        {
            var releaseInfo   = model.RemoteMovie.Release;
            var remoteMovie   = model.RemoteMovie;
            var torrentInfo   = (model.RemoteMovie.Release as TorrentInfo) ?? new TorrentInfo();
            var mappingResult = MappingResultType.Success;

            mappingResult = model.RemoteMovie.MappingResult;
            var parsedMovieInfo = model.RemoteMovie.ParsedMovieInfo;
            var movieId         = model.RemoteMovie.Movie?.Id ?? 0; //Why not pull this out in frontend instead of passing another variable

            return(new ReleaseResource
            {
                Guid = releaseInfo.Guid,
                Quality = parsedMovieInfo.Quality,
                QualityWeight = parsedMovieInfo.Quality.Quality.Id, //Id kinda hacky for wheight, but what you gonna do? TODO: Fix this shit!
                Age = releaseInfo.Age,
                AgeHours = releaseInfo.AgeHours,
                AgeMinutes = releaseInfo.AgeMinutes,
                Size = releaseInfo.Size,
                IndexerId = releaseInfo.IndexerId,
                Indexer = releaseInfo.Indexer,
                ReleaseGroup = parsedMovieInfo.ReleaseGroup,
                ReleaseHash = parsedMovieInfo.ReleaseHash,
                Title = releaseInfo.Title,
                Languages = parsedMovieInfo.Languages,
                Year = parsedMovieInfo.Year,
                MovieTitle = parsedMovieInfo.MovieTitle,
                Approved = model.Approved,
                TemporarilyRejected = model.TemporarilyRejected,
                Rejected = model.Rejected,
                TvdbId = releaseInfo.TvdbId,
                TvRageId = releaseInfo.TvRageId,
                Rejections = model.Rejections.Select(r => r.Reason).ToList(),
                PublishDate = releaseInfo.PublishDate,
                CommentUrl = releaseInfo.CommentUrl,
                DownloadUrl = releaseInfo.DownloadUrl,
                InfoUrl = releaseInfo.InfoUrl,
                MappingResult = mappingResult,

                //ReleaseWeight
                SuspectedMovieId = movieId,

                MagnetUrl = torrentInfo.MagnetUrl,
                InfoHash = torrentInfo.InfoHash,
                Seeders = torrentInfo.Seeders,
                Leechers = (torrentInfo.Peers.HasValue && torrentInfo.Seeders.HasValue) ? (torrentInfo.Peers.Value - torrentInfo.Seeders.Value) : (int?)null,
                Protocol = releaseInfo.DownloadProtocol,
                IndexerFlags = torrentInfo.IndexerFlags.ToString().Split(new string[] { ", " }, StringSplitOptions.None),
                Edition = parsedMovieInfo.Edition,

                //Special = parsedMovieInfo.Special,
            });
        }
        private IEnumerable<DownloadDecision> GetDecisions(List<ReleaseInfo> reports, SearchCriteriaBase searchCriteria = null)
        {
            if (reports.Any())
            {
                _logger.ProgressInfo("Processing {0} reports", reports.Count);
            }

            else
            {
                _logger.ProgressInfo("No reports found");
            }

            var reportNumber = 1;

            foreach (var report in reports)
            {
                DownloadDecision decision = null;
                _logger.ProgressTrace("Processing report {0}/{1}", reportNumber, reports.Count);

                try
                {
                    var parsedEpisodeInfo = Parser.Parser.ParseTitle(report.Title);

                    if (parsedEpisodeInfo != null && !string.IsNullOrWhiteSpace(parsedEpisodeInfo.SeriesTitle))
                    {
                        var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, report.TvRageId, searchCriteria);
                        remoteEpisode.Release = report;

                        if (remoteEpisode.Series != null)
                        {
                            remoteEpisode.DownloadAllowed = true;
                            decision = GetDecisionForReport(remoteEpisode, searchCriteria);
                        }
                        else
                        {
                            decision = new DownloadDecision(remoteEpisode, "Unknown Series");
                        }
                    }
                }
                catch (Exception e)
                {
                    _logger.ErrorException("Couldn't process report.", e);
                }

                reportNumber++;

                if (decision != null)
                {
                    yield return decision;
                }
            }

        }
Beispiel #11
0
        protected virtual ReleaseResource MapDecision(DownloadDecision decision, int initialWeight)
        {
            var release = decision.ToResource();

            release.ReleaseWeight = initialWeight;

            release.QualityWeight = _qualityProfile.GetIndex(release.Quality.Quality).Index * 100;

            release.QualityWeight += release.Quality.Revision.Real * 10;
            release.QualityWeight += release.Quality.Revision.Version;

            return(release);
        }
Beispiel #12
0
        private void Insert(DownloadDecision decision)
        {
            _repository.Insert(new PendingRelease
            {
                SeriesId          = decision.RemoteEpisode.Series.Id,
                ParsedEpisodeInfo = decision.RemoteEpisode.ParsedEpisodeInfo,
                Release           = decision.RemoteEpisode.Release,
                Title             = decision.RemoteEpisode.Release.Title,
                Added             = DateTime.UtcNow
            });

            _eventAggregator.PublishEvent(new PendingReleasesUpdatedEvent());
        }
Beispiel #13
0
        protected override ReleaseResource MapDecision(DownloadDecision decision, int initialWeight)
        {
            if (decision.IsForMovie)
            {
                _remoteMovieCache.Set(decision.RemoteMovie.Release.Guid, decision.RemoteMovie, TimeSpan.FromMinutes(30));
            }
            else
            {
                _remoteEpisodeCache.Set(decision.RemoteEpisode.Release.Guid, decision.RemoteEpisode, TimeSpan.FromMinutes(30));
            }

            return(base.MapDecision(decision, initialWeight));
        }
Beispiel #14
0
        protected virtual ReleaseResource MapDecision(DownloadDecision decision, int initialWeight)
        {
            var release = decision.ToResource();

            release.ReleaseWeight = initialWeight;

            release.QualityWeight  = QUALITY_PROFILE.GetIndex(release.Quality.Quality).Index * 100;
            release.LanguageWeight = LANGUAGE_PROFILE.Languages.FindIndex(v => v.Language == release.Language) * 100;

            release.QualityWeight += release.Quality.Revision.Real * 10;
            release.QualityWeight += release.Quality.Revision.Version;

            return(release);
        }
Beispiel #15
0
        public static ReleaseResource ToResource(this DownloadDecision model)
        {
            var releaseInfo     = model.RemoteMovie.Release;
            var parsedMovieInfo = model.RemoteMovie.ParsedMovieInfo;
            var remoteMovie     = model.RemoteMovie;
            var torrentInfo     = (model.RemoteMovie.Release as TorrentInfo) ?? new TorrentInfo();
            var indexerFlags    = torrentInfo.IndexerFlags.ToString().Split(new string[] { ", " }, StringSplitOptions.None).Where(x => x != "0");

            // TODO: Clean this mess up. don't mix data from multiple classes, use sub-resources instead? (Got a huge Deja Vu, didn't we talk about this already once?)
            return(new ReleaseResource
            {
                Guid = releaseInfo.Guid,
                Quality = parsedMovieInfo.Quality,
                CustomFormats = remoteMovie.CustomFormats.ToResource(),
                CustomFormatScore = remoteMovie.CustomFormatScore,

                //QualityWeight
                Age = releaseInfo.Age,
                AgeHours = releaseInfo.AgeHours,
                AgeMinutes = releaseInfo.AgeMinutes,
                Size = releaseInfo.Size,
                IndexerId = releaseInfo.IndexerId,
                Indexer = releaseInfo.Indexer,
                ReleaseGroup = parsedMovieInfo.ReleaseGroup,
                ReleaseHash = parsedMovieInfo.ReleaseHash,
                Title = releaseInfo.Title,
                MovieTitles = parsedMovieInfo.MovieTitles,
                Languages = parsedMovieInfo.Languages,
                Approved = model.Approved,
                TemporarilyRejected = model.TemporarilyRejected,
                Rejected = model.Rejected,
                TmdbId = releaseInfo.TmdbId,
                ImdbId = releaseInfo.ImdbId,
                Rejections = model.Rejections.Select(r => r.Reason).ToList(),
                PublishDate = releaseInfo.PublishDate,
                CommentUrl = releaseInfo.CommentUrl,
                DownloadUrl = releaseInfo.DownloadUrl,
                InfoUrl = releaseInfo.InfoUrl,
                DownloadAllowed = remoteMovie.DownloadAllowed,
                Edition = parsedMovieInfo.Edition,

                //ReleaseWeight
                MagnetUrl = torrentInfo.MagnetUrl,
                InfoHash = torrentInfo.InfoHash,
                Seeders = torrentInfo.Seeders,
                Leechers = (torrentInfo.Peers.HasValue && torrentInfo.Seeders.HasValue) ? (torrentInfo.Peers.Value - torrentInfo.Seeders.Value) : (int?)null,
                Protocol = releaseInfo.DownloadProtocol,
                IndexerFlags = indexerFlags
            });
        }
Beispiel #16
0
        private void Insert(DownloadDecision decision, PendingReleaseReason reason)
        {
            _repository.Insert(new PendingRelease
            {
                ArtistId        = decision.RemoteAlbum.Artist.Id,
                ParsedAlbumInfo = decision.RemoteAlbum.ParsedAlbumInfo,
                Release         = decision.RemoteAlbum.Release,
                Title           = decision.RemoteAlbum.Release.Title,
                Added           = DateTime.UtcNow,
                Reason          = reason
            });

            _eventAggregator.PublishEvent(new PendingReleasesUpdatedEvent());
        }
Beispiel #17
0
        public void Add(DownloadDecision decision)
        {
            var alreadyPending = GetPendingReleases();

            var movieId = decision.RemoteMovie.Movie.Id;

            var existingReports = alreadyPending.Where(r => r.RemoteMovie.Movie.Id == movieId);

            if (existingReports.Any(MatchingReleasePredicate(decision.RemoteMovie.Release)))
            {
                _logger.Debug("This release is already pending, not adding again");
                return;
            }

            _logger.Debug("Adding release to pending releases");
            Insert(decision);
        }
Beispiel #18
0
        public static ReleaseResource ToResource(this DownloadDecision model)
        {
            var releaseInfo    = model.RemoteBook.Release;
            var parsedBookInfo = model.RemoteBook.ParsedBookInfo;
            var remoteBook     = model.RemoteBook;
            var torrentInfo    = (model.RemoteBook.Release as TorrentInfo) ?? new TorrentInfo();

            // TODO: Clean this mess up. don't mix data from multiple classes, use sub-resources instead? (Got a huge Deja Vu, didn't we talk about this already once?)
            return(new ReleaseResource
            {
                Guid = releaseInfo.Guid,
                Quality = parsedBookInfo.Quality,

                //QualityWeight
                Age = releaseInfo.Age,
                AgeHours = releaseInfo.AgeHours,
                AgeMinutes = releaseInfo.AgeMinutes,
                Size = releaseInfo.Size,
                IndexerId = releaseInfo.IndexerId,
                Indexer = releaseInfo.Indexer,
                ReleaseGroup = parsedBookInfo.ReleaseGroup,
                ReleaseHash = parsedBookInfo.ReleaseHash,
                Title = releaseInfo.Title,
                AuthorName = parsedBookInfo.AuthorName,
                BookTitle = parsedBookInfo.BookTitle,
                Discography = parsedBookInfo.Discography,
                Approved = model.Approved,
                TemporarilyRejected = model.TemporarilyRejected,
                Rejected = model.Rejected,
                Rejections = model.Rejections.Select(r => r.Reason).ToList(),
                PublishDate = releaseInfo.PublishDate,
                CommentUrl = releaseInfo.CommentUrl,
                DownloadUrl = releaseInfo.DownloadUrl,
                InfoUrl = releaseInfo.InfoUrl,
                DownloadAllowed = remoteBook.DownloadAllowed,

                //ReleaseWeight
                PreferredWordScore = remoteBook.PreferredWordScore,

                MagnetUrl = torrentInfo.MagnetUrl,
                InfoHash = torrentInfo.InfoHash,
                Seeders = torrentInfo.Seeders,
                Leechers = (torrentInfo.Peers.HasValue && torrentInfo.Seeders.HasValue) ? (torrentInfo.Peers.Value - torrentInfo.Seeders.Value) : (int?)null,
                Protocol = releaseInfo.DownloadProtocol,
            });
        }
Beispiel #19
0
        protected virtual ReleaseResource MapDecision(DownloadDecision decision, int initialWeight)
        {
            var release = decision.ToResource();

            release.ReleaseWeight = initialWeight;

            if (decision.RemoteEpisode.Series != null)
            {
                release.QualityWeight = decision.RemoteEpisode.Series
                                        .QualityProfile.Value
                                        .Items.FindIndex(v => v.Quality == release.Quality.Quality) * 100;
            }

            release.QualityWeight += release.Quality.Revision.Real * 10;
            release.QualityWeight += release.Quality.Revision.Version;

            return(release);
        }
Beispiel #20
0
        protected virtual ReleaseResource MapDecision(DownloadDecision decision, int initialWeight)
        {
            var release = decision.ToResource();

            release.ReleaseWeight = initialWeight;

            if (decision.RemoteAlbum.Artist != null)
            {
                release.QualityWeight = decision.RemoteAlbum
                                        .Artist
                                        .QualityProfile.Value.GetIndex(release.Quality.Quality).Index * 100;
            }

            release.QualityWeight += release.Quality.Revision.Real * 10;
            release.QualityWeight += release.Quality.Revision.Version;

            return(release);
        }
Beispiel #21
0
        public void Add(DownloadDecision decision)
        {
            var alreadyPending = GetPendingReleases();

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

            var existingReports = alreadyPending.Where(r => r.RemoteEpisode.Episodes.Select(e => e.Id)
                                                       .Intersect(episodeIds)
                                                       .Any());

            if (existingReports.Any(MatchingReleasePredicate(decision.RemoteEpisode.Release)))
            {
                _logger.Debug("This release is already pending, not adding again");
                return;
            }

            _logger.Debug("Adding release to pending releases");
            Insert(decision);
        }
        private void Add(List <PendingRelease> alreadyPending, DownloadDecision decision, PendingReleaseReason reason)
        {
            var episodeIds = decision.RemoteEpisode.Episodes.Select(e => e.Id);

            var existingReports = alreadyPending.Where(r => r.RemoteEpisode.Episodes.Select(e => e.Id)
                                                       .Intersect(episodeIds)
                                                       .Any());

            var matchingReports = existingReports.Where(MatchingReleasePredicate(decision.RemoteEpisode.Release)).ToList();

            if (matchingReports.Any())
            {
                var matchingReport = matchingReports.First();

                if (matchingReport.Reason != reason)
                {
                    _logger.Debug("The release {0} is already pending with reason {1}, changing to {2}", decision.RemoteEpisode, matchingReport.Reason, reason);
                    matchingReport.Reason = reason;
                    _repository.Update(matchingReport);
                }
                else
                {
                    _logger.Debug("The release {0} is already pending with reason {1}, not adding again", decision.RemoteEpisode, reason);
                }

                if (matchingReports.Count() > 1)
                {
                    _logger.Debug("The release {0} had {1} duplicate pending, removing duplicates.", decision.RemoteEpisode, matchingReports.Count() - 1);

                    foreach (var duplicate in matchingReports.Skip(1))
                    {
                        _repository.Delete(duplicate.Id);
                        alreadyPending.Remove(duplicate);
                    }
                }

                return;
            }

            _logger.Debug("Adding release {0} to pending releases with reason {1}", decision.RemoteEpisode, reason);
            Insert(decision, reason);
        }
Beispiel #23
0
        private void Insert(DownloadDecision decision)
        {
            var release = new PendingRelease
            {
                MovieId         = decision.RemoteMovie.Movie.Id,
                ParsedMovieInfo = decision.RemoteMovie.ParsedMovieInfo,
                Release         = decision.RemoteMovie.Release,
                Title           = decision.RemoteMovie.Release.Title,
                Added           = DateTime.UtcNow
            };

            if (release.ParsedMovieInfo == null)
            {
                _logger.Warn("Pending release {0} does not have ParsedMovieInfo, will cause issues.", release.Title);
            }

            _repository.Insert(release);

            _eventAggregator.PublishEvent(new PendingReleasesUpdatedEvent());
        }
Beispiel #24
0
        protected virtual ReleaseResource MapDecision(DownloadDecision decision, int initialWeight)
        {
            var release = new ReleaseResource();

            release.InjectFrom(decision.RemoteEpisode.Release);
            release.InjectFrom(decision.RemoteEpisode.ParsedEpisodeInfo);
            release.InjectFrom(decision);
            release.Rejections      = decision.Rejections.Select(r => r.Reason).ToList();
            release.DownloadAllowed = decision.RemoteEpisode.DownloadAllowed;
            release.ReleaseWeight   = initialWeight;

            if (decision.RemoteEpisode.Series != null)
            {
                release.QualityWeight = decision.RemoteEpisode
                                        .Series
                                        .Profile
                                        .Value
                                        .Items
                                        .FindIndex(v => v.Quality == release.Quality.Quality) * 100;
            }

            release.QualityWeight += release.Quality.Revision.Real * 10;
            release.QualityWeight += release.Quality.Revision.Version;

            var torrentRelease = decision.RemoteEpisode.Release as TorrentInfo;

            if (torrentRelease != null)
            {
                release.Protocol = DownloadProtocol.Torrent;
                release.Seeders  = torrentRelease.Seeders;
                //TODO: move this up the chains
                release.Leechers = torrentRelease.Peers - torrentRelease.Seeders;
            }
            else
            {
                release.Protocol = DownloadProtocol.Usenet;
            }

            return(release);
        }
        public void Add(DownloadDecision decision, PendingReleaseReason reason)
        {
            var alreadyPending = GetPendingReleases();

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

            var existingReports = alreadyPending.Where(r => r.RemoteEpisode.Episodes.Select(e => e.Id)
                                                       .Intersect(episodeIds)
                                                       .Any());

            var matchingReports = existingReports.Where(MatchingReleasePredicate(decision.RemoteEpisode.Release)).ToList();

            if (matchingReports.Any())
            {
                var sameReason = true;

                foreach (var matchingReport in matchingReports)
                {
                    if (matchingReport.Reason != reason)
                    {
                        _logger.Debug("The release {0} is already pending with reason {1}, changing to {2}", decision.RemoteEpisode, matchingReport.Reason, reason);
                        matchingReport.Reason = reason;
                        _repository.Update(matchingReport);
                        sameReason = false;
                    }
                }

                if (sameReason)
                {
                    _logger.Debug("The release {0} is already pending with reason {1}, not adding again", decision.RemoteEpisode, reason);
                    return;
                }
            }

            _logger.Debug("Adding release {0} to pending releases with reason {1}", decision.RemoteEpisode, reason);
            Insert(decision, reason);
        }
 private Func <PendingRelease, bool> MatchingReleasePredicate(DownloadDecision decision)
 {
     return(p => p.Title == decision.RemoteEpisode.Release.Title &&
            p.Release.PublishDate == decision.RemoteEpisode.Release.PublishDate &&
            p.Release.Indexer == decision.RemoteEpisode.Release.Indexer);
 }
Beispiel #27
0
        private void PreparePending(List <Tuple <DownloadDecision, PendingReleaseReason> > queue, List <DownloadDecision> grabbed, List <DownloadDecision> pending, DownloadDecision report, PendingReleaseReason reason)
        {
            // If a release was already grabbed with matching episodes we should store it as a fallback
            // and filter it out the next time it is processed.
            // If a higher quality release failed to add to the download client, but a lower quality release
            // was sent to another client we still list it normally so it apparent that it'll grab next time.
            // Delayed is treated the same, but only the first is listed the subsequent items as stored as Fallback.

            if (IsEpisodeProcessed(grabbed, report) ||
                IsEpisodeProcessed(pending, report))
            {
                reason = PendingReleaseReason.Fallback;
            }

            queue.Add(Tuple.Create(report, reason));
            pending.Add(report);
        }
Beispiel #28
0
 public void Add(DownloadDecision decision, PendingReleaseReason reason)
 {
     AddMany(new List <Tuple <DownloadDecision, PendingReleaseReason> > {
         Tuple.Create(decision, reason)
     });
 }
        public void Setup()
        {
            _author = Builder <Author> .CreateNew()
                      .Build();

            _book = Builder <Book> .CreateNew()
                    .Build();

            _profile = new QualityProfile
            {
                Name   = "Test",
                Cutoff = Quality.MP3_320.Id,
                Items  = new List <QualityProfileQualityItem>
                {
                    new QualityProfileQualityItem {
                        Allowed = true, Quality = Quality.MP3_320
                    },
                    new QualityProfileQualityItem {
                        Allowed = true, Quality = Quality.MP3_320
                    },
                    new QualityProfileQualityItem {
                        Allowed = true, Quality = Quality.MP3_320
                    }
                },
            };

            _author.QualityProfile = new LazyLoaded <QualityProfile>(_profile);

            _release = Builder <ReleaseInfo> .CreateNew().Build();

            _parsedBookInfo = Builder <ParsedBookInfo> .CreateNew().Build();

            _parsedBookInfo.Quality = new QualityModel(Quality.MP3_320);

            _remoteBook       = new RemoteBook();
            _remoteBook.Books = new List <Book> {
                _book
            };
            _remoteBook.Author         = _author;
            _remoteBook.ParsedBookInfo = _parsedBookInfo;
            _remoteBook.Release        = _release;

            _temporarilyRejected = new DownloadDecision(_remoteBook, new Rejection("Temp Rejected", RejectionType.Temporary));

            Mocker.GetMock <IPendingReleaseRepository>()
            .Setup(s => s.All())
            .Returns(new List <PendingRelease>());

            Mocker.GetMock <IAuthorService>()
            .Setup(s => s.GetAuthor(It.IsAny <int>()))
            .Returns(_author);

            Mocker.GetMock <IAuthorService>()
            .Setup(s => s.GetAuthors(It.IsAny <IEnumerable <int> >()))
            .Returns(new List <Author> {
                _author
            });

            Mocker.GetMock <IParsingService>()
            .Setup(s => s.GetBooks(It.IsAny <ParsedBookInfo>(), _author, null))
            .Returns(new List <Book> {
                _book
            });

            Mocker.GetMock <IPrioritizeDownloadDecision>()
            .Setup(s => s.PrioritizeDecisions(It.IsAny <List <DownloadDecision> >()))
            .Returns((List <DownloadDecision> d) => d);
        }
        public void Setup()
        {
            _series = Builder <Series> .CreateNew()
                      .Build();

            _episode = Builder <Episode> .CreateNew()
                       .Build();

            _profile = new Profile
            {
                Name   = "Test",
                Cutoff = Quality.HDTV720p,
                Items  = new List <ProfileQualityItem>
                {
                    new ProfileQualityItem {
                        Allowed = true, Quality = Quality.HDTV720p
                    },
                    new ProfileQualityItem {
                        Allowed = true, Quality = Quality.WEBDL720p
                    },
                    new ProfileQualityItem {
                        Allowed = true, Quality = Quality.Bluray720p
                    }
                },
            };

            _series.Profile = new LazyLoaded <Profile>(_profile);

            _release = Builder <ReleaseInfo> .CreateNew().Build();

            _parsedEpisodeInfo = Builder <ParsedEpisodeInfo> .CreateNew().Build();

            _parsedEpisodeInfo.Quality = new QualityModel(Quality.HDTV720p);

            _remoteEpisode          = new RemoteEpisode();
            _remoteEpisode.Episodes = new List <Episode> {
                _episode
            };
            _remoteEpisode.Series            = _series;
            _remoteEpisode.ParsedEpisodeInfo = _parsedEpisodeInfo;
            _remoteEpisode.Release           = _release;

            _temporarilyRejected = new DownloadDecision(_remoteEpisode, new Rejection("Temp Rejected", RejectionType.Temporary));

            _heldReleases = new List <PendingRelease>();

            Mocker.GetMock <IPendingReleaseRepository>()
            .Setup(s => s.All())
            .Returns(_heldReleases);

            Mocker.GetMock <IPendingReleaseRepository>()
            .Setup(s => s.AllBySeriesId(It.IsAny <int>()))
            .Returns <int>(i => _heldReleases.Where(v => v.SeriesId == i).ToList());

            Mocker.GetMock <ISeriesService>()
            .Setup(s => s.GetSeries(It.IsAny <int>()))
            .Returns(_series);

            Mocker.GetMock <ISeriesService>()
            .Setup(s => s.GetSeries(It.IsAny <IEnumerable <int> >()))
            .Returns(new List <Series> {
                _series
            });

            Mocker.GetMock <IParsingService>()
            .Setup(s => s.GetEpisodes(It.IsAny <ParsedEpisodeInfo>(), _series, true, null))
            .Returns(new List <Episode> {
                _episode
            });

            Mocker.GetMock <IPrioritizeDownloadDecision>()
            .Setup(s => s.PrioritizeDecisions(It.IsAny <List <DownloadDecision> >()))
            .Returns((List <DownloadDecision> d) => d);
        }
Beispiel #31
0
        public static ReleaseResource ToResource(this DownloadDecision model)
        {
            var releaseInfo       = model.RemoteEpisode.Release;
            var parsedEpisodeInfo = model.RemoteEpisode.ParsedEpisodeInfo;
            var remoteEpisode     = model.RemoteEpisode;
            var torrentInfo       = (model.RemoteEpisode.Release as TorrentInfo) ?? new TorrentInfo();
            var mappingResult     = MappingResultType.Success;

            if (model.IsForMovie)
            {
                mappingResult = model.RemoteMovie.MappingResult;
                var parsedMovieInfo = model.RemoteMovie.ParsedMovieInfo;
                var movieId         = model.RemoteMovie.Movie?.Id ?? 0;

                return(new ReleaseResource
                {
                    Guid = releaseInfo.Guid,
                    Quality = parsedMovieInfo.Quality,
                    QualityWeight = parsedMovieInfo.Quality.Quality.Id, //Id kinda hacky for wheight, but what you gonna do? TODO: Fix this shit!
                    Age = releaseInfo.Age,
                    AgeHours = releaseInfo.AgeHours,
                    AgeMinutes = releaseInfo.AgeMinutes,
                    Size = releaseInfo.Size,
                    IndexerId = releaseInfo.IndexerId,
                    Indexer = releaseInfo.Indexer,
                    ReleaseGroup = parsedMovieInfo.ReleaseGroup,
                    ReleaseHash = parsedMovieInfo.ReleaseHash,
                    Title = releaseInfo.Title,
                    //FullSeason = parsedMovieInfo.FullSeason,
                    //SeasonNumber = parsedMovieInfo.SeasonNumber,
                    Language = parsedMovieInfo.Language,
                    Year = parsedMovieInfo.Year,
                    MovieTitle = parsedMovieInfo.MovieTitle,
                    EpisodeNumbers = new int[0],
                    AbsoluteEpisodeNumbers = new int[0],
                    Approved = model.Approved,
                    TemporarilyRejected = model.TemporarilyRejected,
                    Rejected = model.Rejected,
                    TvdbId = releaseInfo.TvdbId,
                    TvRageId = releaseInfo.TvRageId,
                    Rejections = model.Rejections.Select(r => r.Reason).ToList(),
                    PublishDate = releaseInfo.PublishDate,
                    CommentUrl = releaseInfo.CommentUrl,
                    DownloadUrl = releaseInfo.DownloadUrl,
                    InfoUrl = releaseInfo.InfoUrl,
                    MappingResult = mappingResult,
                    //ReleaseWeight

                    SuspectedMovieId = movieId,

                    MagnetUrl = torrentInfo.MagnetUrl,
                    InfoHash = torrentInfo.InfoHash,
                    Seeders = torrentInfo.Seeders,
                    Leechers = (torrentInfo.Peers.HasValue && torrentInfo.Seeders.HasValue) ? (torrentInfo.Peers.Value - torrentInfo.Seeders.Value) : (int?)null,
                    Protocol = releaseInfo.DownloadProtocol,
                    IndexerFlags = torrentInfo.IndexerFlags.ToString().Split(new string[] { ", " }, StringSplitOptions.None),
                    Edition = parsedMovieInfo.Edition,

                    IsDaily = false,
                    IsAbsoluteNumbering = false,
                    IsPossibleSpecialEpisode = false,
                    //Special = parsedMovieInfo.Special,
                });
            }

            // TODO: Clean this mess up. don't mix data from multiple classes, use sub-resources instead? (Got a huge Deja Vu, didn't we talk about this already once?)
            return(new ReleaseResource
            {
                Guid = releaseInfo.Guid,
                Quality = parsedEpisodeInfo.Quality,
                //QualityWeight
                Age = releaseInfo.Age,
                AgeHours = releaseInfo.AgeHours,
                AgeMinutes = releaseInfo.AgeMinutes,
                Size = releaseInfo.Size,
                IndexerId = releaseInfo.IndexerId,
                Indexer = releaseInfo.Indexer,
                ReleaseGroup = parsedEpisodeInfo.ReleaseGroup,
                ReleaseHash = parsedEpisodeInfo.ReleaseHash,
                Title = releaseInfo.Title,
                FullSeason = parsedEpisodeInfo.FullSeason,
                SeasonNumber = parsedEpisodeInfo.SeasonNumber,
                Language = parsedEpisodeInfo.Language,
                //AirDate = parsedEpisodeInfo.AirDate,
                //SeriesTitle = parsedEpisodeInfo.SeriesTitle,
                EpisodeNumbers = parsedEpisodeInfo.EpisodeNumbers,
                AbsoluteEpisodeNumbers = parsedEpisodeInfo.AbsoluteEpisodeNumbers,
                Approved = model.Approved,
                TemporarilyRejected = model.TemporarilyRejected,
                Rejected = model.Rejected,
                TvdbId = releaseInfo.TvdbId,
                TvRageId = releaseInfo.TvRageId,
                Rejections = model.Rejections.Select(r => r.Reason).ToList(),
                PublishDate = releaseInfo.PublishDate,
                CommentUrl = releaseInfo.CommentUrl,
                DownloadUrl = releaseInfo.DownloadUrl,
                InfoUrl = releaseInfo.InfoUrl,
                //DownloadAllowed = downloadAllowed,
                //ReleaseWeight

                MagnetUrl = torrentInfo.MagnetUrl,
                InfoHash = torrentInfo.InfoHash,
                Seeders = torrentInfo.Seeders,
                Leechers = (torrentInfo.Peers.HasValue && torrentInfo.Seeders.HasValue) ? (torrentInfo.Peers.Value - torrentInfo.Seeders.Value) : (int?)null,
                Protocol = releaseInfo.DownloadProtocol,

                IsDaily = parsedEpisodeInfo.IsDaily,
                IsAbsoluteNumbering = parsedEpisodeInfo.IsAbsoluteNumbering,
                IsPossibleSpecialEpisode = parsedEpisodeInfo.IsPossibleSpecialEpisode,
                Special = parsedEpisodeInfo.Special,
            });
        }