From 9e7e8cff1145dca833de4650b6fa3c6e4cdd9ad4 Mon Sep 17 00:00:00 2001 From: Qstick Date: Mon, 26 Feb 2018 16:08:44 +0100 Subject: [PATCH] Fixed: Multiple History Issues (#2571) --- .../HistorySpecificationFixture.cs | 6 +- .../HistoryTests/HistoryRepositoryFixture.cs | 8 +- .../HistoryTests/HistoryServiceFixture.cs | 22 +-- .../RssSync/HistorySpecification.cs | 49 +---- .../History/HistoryRepository.cs | 31 +-- src/NzbDrone.Core/History/HistoryService.cs | 182 +----------------- .../Details/HistoryDetailsLayoutTemplate.hbs | 2 +- .../Details/HistoryDetailsViewTemplate.hbs | 2 +- 8 files changed, 33 insertions(+), 269 deletions(-) diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/HistorySpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/HistorySpecificationFixture.cs index 25a10b498..0e9785e83 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/HistorySpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/HistorySpecificationFixture.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using FizzWare.NBuilder; using FluentAssertions; @@ -72,7 +72,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests private void GivenMostRecentForEpisode(int episodeId, string downloadId, QualityModel quality, DateTime date, HistoryEventType eventType) { - Mocker.GetMock().Setup(s => s.MostRecentForEpisode(episodeId)) + Mocker.GetMock().Setup(s => s.MostRecentForMovie(episodeId)) .Returns(new History.History { DownloadId = downloadId, Quality = quality, Date = date, EventType = eventType }); } @@ -92,7 +92,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests [Test] public void should_return_true_if_latest_history_item_is_null() { - Mocker.GetMock().Setup(s => s.MostRecentForEpisode(It.IsAny())).Returns((History.History)null); + Mocker.GetMock().Setup(s => s.MostRecentForMovie(It.IsAny())).Returns((History.History)null); _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeTrue(); } diff --git a/src/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs b/src/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs index 649c3d499..a31e79f5f 100644 --- a/src/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs +++ b/src/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs @@ -1,4 +1,4 @@ -using FizzWare.NBuilder; +using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.History; @@ -32,13 +32,13 @@ namespace NzbDrone.Core.Test.HistoryTests { var historyBluray = Builder.CreateNew() .With(c => c.Quality = new QualityModel(Quality.Bluray1080p)) - .With(c => c.SeriesId = 12) + .With(c => c.MovieId = 12) .With(c => c.EventType = HistoryEventType.Grabbed) .BuildNew(); var historyDvd = Builder.CreateNew() .With(c => c.Quality = new QualityModel(Quality.DVD)) - .With(c => c.SeriesId = 12) + .With(c => c.MovieId = 12) .With(c => c.EventType = HistoryEventType.Grabbed) .BuildNew(); @@ -51,4 +51,4 @@ namespace NzbDrone.Core.Test.HistoryTests } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core.Test/HistoryTests/HistoryServiceFixture.cs b/src/NzbDrone.Core.Test/HistoryTests/HistoryServiceFixture.cs index c2d436ec8..6e100e2ae 100644 --- a/src/NzbDrone.Core.Test/HistoryTests/HistoryServiceFixture.cs +++ b/src/NzbDrone.Core.Test/HistoryTests/HistoryServiceFixture.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using System.Linq; using FizzWare.NBuilder; using Moq; @@ -68,23 +68,23 @@ namespace NzbDrone.Core.Test.HistoryTests [Test] public void should_use_file_name_for_source_title_if_scene_name_is_null() { - var series = Builder.CreateNew().Build(); - var episodes = Builder.CreateListOfSize(1).Build().ToList(); - var episodeFile = Builder.CreateNew() + // Test fails becuase Radarr is using movie.title in historyService with no fallback + + var movie = Builder.CreateNew().Build(); + var movieFile = Builder.CreateNew() .With(f => f.SceneName = null) .Build(); - var localEpisode = new LocalEpisode + var localMovie = new LocalMovie() { - Series = series, - Episodes = episodes, - Path = @"C:\Test\Unsorted\Series.s01e01.mkv" + Movie = movie, + Path = @"C:\Test\Unsorted\Movie.2011.mkv" }; - Subject.Handle(new EpisodeImportedEvent(localEpisode, episodeFile, true, "sab", "abcd", true)); + Subject.Handle(new MovieImportedEvent(localMovie, movieFile, true, "sab", "abcd", true)); Mocker.GetMock() - .Verify(v => v.Insert(It.Is(h => h.SourceTitle == Path.GetFileNameWithoutExtension(localEpisode.Path)))); + .Verify(v => v.Insert(It.Is(h => h.SourceTitle == Path.GetFileNameWithoutExtension(localMovie.Path)))); } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs index 2a312fbdd..e8fb7719f 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs @@ -80,54 +80,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { - if (searchCriteria != null) - { - _logger.Debug("Skipping history check during search"); - return Decision.Accept(); - } - - var cdhEnabled = _configService.EnableCompletedDownloadHandling; - - _logger.Debug("Performing history status check on report"); - foreach (var episode in subject.Episodes) - { - _logger.Debug("Checking current status of episode [{0}] in history", episode.Id); - var mostRecent = _historyService.MostRecentForEpisode(episode.Id); - - if (mostRecent != null && mostRecent.EventType == HistoryEventType.Grabbed) - { - var recent = mostRecent.Date.After(DateTime.UtcNow.AddHours(-12)); - var cutoffUnmet = _qualityUpgradableSpecification.CutoffNotMet(subject.Series.Profile, mostRecent.Quality, subject.ParsedEpisodeInfo.Quality); - var upgradeable = _qualityUpgradableSpecification.IsUpgradable(subject.Series.Profile, mostRecent.Quality, subject.ParsedEpisodeInfo.Quality); - - if (!recent && cdhEnabled) - { - continue; - } - - if (!cutoffUnmet) - { - if (recent) - { - return Decision.Reject("Recent grab event in history already meets cutoff: {0}", mostRecent.Quality); - } - - return Decision.Reject("CDH is disabled and grab event in history already meets cutoff: {0}", mostRecent.Quality); - } - - if (!upgradeable) - { - if (recent) - { - return Decision.Reject("Recent grab event in history is of equal or higher quality: {0}", mostRecent.Quality); - } - - return Decision.Reject("CDH is disabled and grab event in history is of equal or higher quality: {0}", mostRecent.Quality); - } - } - } - - return Decision.Accept(); + throw new NotImplementedException(); } } } diff --git a/src/NzbDrone.Core/History/HistoryRepository.cs b/src/NzbDrone.Core/History/HistoryRepository.cs index 5cde171a3..7ece4ea15 100644 --- a/src/NzbDrone.Core/History/HistoryRepository.cs +++ b/src/NzbDrone.Core/History/HistoryRepository.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Marr.Data.QGen; @@ -11,12 +11,10 @@ namespace NzbDrone.Core.History { public interface IHistoryRepository : IBasicRepository { - List GetBestQualityInHistory(int episodeId); - History MostRecentForEpisode(int episodeId); + List GetBestQualityInHistory(int movieId); History MostRecentForDownloadId(string downloadId); List FindByDownloadId(string downloadId); - List FindDownloadHistory(int idSeriesId, QualityModel quality); - void DeleteForSeries(int seriesId); + List FindDownloadHistory(int idMovieId, QualityModel quality); void DeleteForMovie(int movieId); History MostRecentForMovie(int movieId); } @@ -29,21 +27,13 @@ namespace NzbDrone.Core.History { } - - public List GetBestQualityInHistory(int episodeId) + public List GetBestQualityInHistory(int movieId) { - var history = Query.Where(c => c.EpisodeId == episodeId); + var history = Query.Where(c => c.MovieId == movieId); return history.Select(h => h.Quality).ToList(); } - public History MostRecentForEpisode(int episodeId) - { - return Query.Where(h => h.EpisodeId == episodeId) - .OrderByDescending(h => h.Date) - .FirstOrDefault(); - } - public History MostRecentForDownloadId(string downloadId) { return Query.Where(h => h.DownloadId == downloadId) @@ -56,10 +46,10 @@ namespace NzbDrone.Core.History return Query.Where(h => h.DownloadId == downloadId); } - public List FindDownloadHistory(int idSeriesId, QualityModel quality) + public List FindDownloadHistory(int idMovieId, QualityModel quality) { return Query.Where(h => - h.SeriesId == idSeriesId && + h.MovieId == idMovieId && h.Quality == quality && (h.EventType == HistoryEventType.Grabbed || h.EventType == HistoryEventType.DownloadFailed || @@ -67,11 +57,6 @@ namespace NzbDrone.Core.History ).ToList(); } - public void DeleteForSeries(int seriesId) - { - Delete(c => c.SeriesId == seriesId); - } - public void DeleteForMovie(int movieId) { Delete(c => c.MovieId == movieId); @@ -95,4 +80,4 @@ namespace NzbDrone.Core.History .FirstOrDefault(); } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core/History/HistoryService.cs b/src/NzbDrone.Core/History/HistoryService.cs index a4408ed7a..d18fa328a 100644 --- a/src/NzbDrone.Core/History/HistoryService.cs +++ b/src/NzbDrone.Core/History/HistoryService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -21,7 +21,6 @@ namespace NzbDrone.Core.History QualityModel GetBestQualityInHistory(Profile profile, int episodeId); PagingSpec Paged(PagingSpec pagingSpec); History MostRecentForMovie(int movieId); - History MostRecentForEpisode(int episodeId); History MostRecentForDownloadId(string downloadId); History Get(int historyId); List Find(string downloadId, HistoryEventType eventType); @@ -29,14 +28,11 @@ namespace NzbDrone.Core.History } public class HistoryService : IHistoryService, - IHandle, IHandle, IHandle, - IHandle, IHandle, - IHandle, IHandle, - IHandle + IHandle { private readonly IHistoryRepository _historyRepository; private readonly Logger _logger; @@ -52,11 +48,6 @@ namespace NzbDrone.Core.History return _historyRepository.GetPaged(pagingSpec); } - public History MostRecentForEpisode(int episodeId) - { - return _historyRepository.MostRecentForEpisode(episodeId); - } - public History MostRecentForMovie(int movieId) { return _historyRepository.MostRecentForMovie(movieId); @@ -205,10 +196,7 @@ namespace NzbDrone.Core.History var movieId = trackedDownload.MovieInfo.Movie.Id; - var allHistory = _historyRepository.FindDownloadHistory(movieId, trackedDownload.ImportedMovie.Quality); - - //Find download related items for this movie - var movieHistory = allHistory.Where(h => movieId == h.MovieId).ToList(); + var movieHistory = _historyRepository.FindDownloadHistory(movieId, trackedDownload.ImportedMovie.Quality); var processedDownloadId = movieHistory .Where(c => c.EventType != HistoryEventType.Grabbed && c.DownloadId != null) @@ -244,136 +232,6 @@ namespace NzbDrone.Core.History return downloadId; } - private string FindDownloadId(EpisodeImportedEvent trackedDownload) - { - _logger.Debug("Trying to find downloadId for {0} from history", trackedDownload.ImportedEpisode.Path); - - var episodeIds = trackedDownload.EpisodeInfo.Episodes.Select(c => c.Id).ToList(); - - var allHistory = _historyRepository.FindDownloadHistory(trackedDownload.EpisodeInfo.Series.Id, trackedDownload.ImportedEpisode.Quality); - - - //Find download related items for these episdoes - var episodesHistory = allHistory.Where(h => episodeIds.Contains(h.EpisodeId)).ToList(); - - var processedDownloadId = episodesHistory - .Where(c => c.EventType != HistoryEventType.Grabbed && c.DownloadId != null) - .Select(c => c.DownloadId); - - var stillDownloading = episodesHistory.Where(c => c.EventType == HistoryEventType.Grabbed && !processedDownloadId.Contains(c.DownloadId)).ToList(); - - string downloadId = null; - - if (stillDownloading.Any()) - { - foreach (var matchingHistory in trackedDownload.EpisodeInfo.Episodes.Select(e => stillDownloading.Where(c => c.EpisodeId == e.Id).ToList())) - { - if (matchingHistory.Count != 1) - { - return null; - } - - var newDownloadId = matchingHistory.Single().DownloadId; - - if (downloadId == null || downloadId == newDownloadId) - { - downloadId = newDownloadId; - } - else - { - return null; - } - } - } - - return downloadId; - } - - public void Handle(EpisodeGrabbedEvent message) - { - foreach (var episode in message.Episode.Episodes) - { - var history = new History - { - EventType = HistoryEventType.Grabbed, - Date = DateTime.UtcNow, - Quality = message.Episode.ParsedEpisodeInfo.Quality, - SourceTitle = message.Episode.Release.Title, - SeriesId = episode.SeriesId, - EpisodeId = episode.Id, - DownloadId = message.DownloadId, - MovieId = 0 - }; - - history.Data.Add("Indexer", message.Episode.Release.Indexer); - history.Data.Add("NzbInfoUrl", message.Episode.Release.InfoUrl); - history.Data.Add("ReleaseGroup", message.Episode.ParsedEpisodeInfo.ReleaseGroup); - history.Data.Add("Age", message.Episode.Release.Age.ToString()); - history.Data.Add("AgeHours", message.Episode.Release.AgeHours.ToString()); - history.Data.Add("AgeMinutes", message.Episode.Release.AgeMinutes.ToString()); - history.Data.Add("PublishedDate", message.Episode.Release.PublishDate.ToString("s") + "Z"); - history.Data.Add("DownloadClient", message.DownloadClient); - history.Data.Add("Size", message.Episode.Release.Size.ToString()); - history.Data.Add("DownloadUrl", message.Episode.Release.DownloadUrl); - history.Data.Add("Guid", message.Episode.Release.Guid); - history.Data.Add("TvdbId", message.Episode.Release.TvdbId.ToString()); - history.Data.Add("TvRageId", message.Episode.Release.TvRageId.ToString()); - history.Data.Add("Protocol", ((int)message.Episode.Release.DownloadProtocol).ToString()); - - if (!message.Episode.ParsedEpisodeInfo.ReleaseHash.IsNullOrWhiteSpace()) - { - history.Data.Add("ReleaseHash", message.Episode.ParsedEpisodeInfo.ReleaseHash); - } - - var torrentRelease = message.Episode.Release as TorrentInfo; - - if (torrentRelease != null) - { - history.Data.Add("TorrentInfoHash", torrentRelease.InfoHash); - } - - _historyRepository.Insert(history); - } - } - - public void Handle(EpisodeImportedEvent message) - { - if (!message.NewDownload) - { - return; - } - - var downloadId = message.DownloadId; - - if (downloadId.IsNullOrWhiteSpace()) - { - downloadId = FindDownloadId(message); - } - - foreach (var episode in message.EpisodeInfo.Episodes) - { - var history = new History - { - EventType = HistoryEventType.DownloadFolderImported, - Date = DateTime.UtcNow, - Quality = message.EpisodeInfo.Quality, - SourceTitle = message.ImportedEpisode.SceneName ?? Path.GetFileNameWithoutExtension(message.EpisodeInfo.Path), - SeriesId = message.ImportedEpisode.SeriesId, - EpisodeId = episode.Id, - DownloadId = downloadId, - MovieId = 0, - }; - - //Won't have a value since we publish this event before saving to DB. - //history.Data.Add("FileId", message.ImportedEpisode.Id.ToString()); - history.Data.Add("DroppedPath", message.EpisodeInfo.Path); - history.Data.Add("ImportedPath", Path.Combine(message.EpisodeInfo.Series.Path, message.ImportedEpisode.RelativePath)); - history.Data.Add("DownloadClient", message.DownloadClient); - - _historyRepository.Insert(history); - } - } - public void Handle(DownloadFailedEvent message) { var history = new History @@ -393,37 +251,5 @@ namespace NzbDrone.Core.History _historyRepository.Insert(history); } - - public void Handle(EpisodeFileDeletedEvent message) - { - if (message.Reason == DeleteMediaFileReason.NoLinkedEpisodes) - { - _logger.Debug("Removing episode file from DB as part of cleanup routine, not creating history event."); - return; - } - - foreach (var episode in message.EpisodeFile.Episodes.Value) - { - var history = new History - { - EventType = HistoryEventType.EpisodeFileDeleted, - Date = DateTime.UtcNow, - Quality = message.EpisodeFile.Quality, - SourceTitle = message.EpisodeFile.Path, - SeriesId = message.EpisodeFile.SeriesId, - EpisodeId = episode.Id, - MovieId = 0 - }; - - history.Data.Add("Reason", message.Reason.ToString()); - - _historyRepository.Insert(history); - } - } - - public void Handle(SeriesDeletedEvent message) - { - _historyRepository.DeleteForSeries(message.Series.Id); - } } -} \ No newline at end of file +} diff --git a/src/UI/Activity/History/Details/HistoryDetailsLayoutTemplate.hbs b/src/UI/Activity/History/Details/HistoryDetailsLayoutTemplate.hbs index d835dda56..1907626fc 100644 --- a/src/UI/Activity/History/Details/HistoryDetailsLayoutTemplate.hbs +++ b/src/UI/Activity/History/Details/HistoryDetailsLayoutTemplate.hbs @@ -7,7 +7,7 @@ {{#if_eq eventType compare="grabbed"}}Grabbed{{/if_eq}} {{#if_eq eventType compare="downloadFailed"}}Download Failed{{/if_eq}} {{#if_eq eventType compare="downloadFolderImported"}}Movie Imported{{/if_eq}} - {{#if_eq eventType compare="episodeFileDeleted"}}Movie File Deleted{{/if_eq}} + {{#if_eq eventType compare="movieFileDeleted"}}Movie File Deleted{{/if_eq}} diff --git a/src/UI/Activity/History/Details/HistoryDetailsViewTemplate.hbs b/src/UI/Activity/History/Details/HistoryDetailsViewTemplate.hbs index 090c46978..83c86e4e3 100644 --- a/src/UI/Activity/History/Details/HistoryDetailsViewTemplate.hbs +++ b/src/UI/Activity/History/Details/HistoryDetailsViewTemplate.hbs @@ -77,7 +77,7 @@ {{/if_eq}} -{{#if_eq eventType compare="episodeFileDeleted"}} +{{#if_eq eventType compare="movieFileDeleted"}}
Path: