From 824d315a3bb0ee2c1af3c9a7a9f3321baca50670 Mon Sep 17 00:00:00 2001 From: Qstick Date: Sun, 29 Mar 2020 16:05:48 -0400 Subject: [PATCH] New: Download History Co-Authored-By: Mark McDowall --- frontend/src/Activity/Queue/QueueRow.js | 2 +- .../Actions/Creators/createHandleActions.js | 15 +- .../src/Store/Actions/importMovieActions.js | 6 +- src/NzbDrone.Api/History/HistoryModule.cs | 6 +- src/NzbDrone.Api/History/HistoryResource.cs | 4 +- .../MovieFiles/MovieFileModule.cs | 1 - src/NzbDrone.Api/Queue/QueueActionModule.cs | 3 - .../Datastore/DatabaseRelationshipFixture.cs | 9 +- .../AlreadyImportedSpecificationFixture.cs | 184 +++++++++++++++ .../BlockedIndexerSpecificationFixture.cs | 54 +++++ .../HistorySpecificationFixture.cs | 28 +-- .../UpgradeDiskSpecificationFixture.cs | 4 +- .../ImportFixture.cs | 4 +- .../ProcessFixture.cs | 8 +- .../DownloadClientFixtureBase.cs | 6 +- .../ProcessFailedFixture.cs | 6 +- .../ProcessFixture.cs | 10 +- .../TrackedDownloadAlreadyImportedFixture.cs | 12 +- .../TrackedDownloadServiceFixture.cs | 10 +- .../HistoryTests/HistoryRepositoryFixture.cs | 30 +-- .../HistoryTests/HistoryServiceFixture.cs | 17 +- .../CleanupOrphanedHistoryItemsFixture.cs | 7 +- .../FileListRequestGeneratorFixture.cs | 2 - .../MediaFiles/ImportApprovedMoviesFixture.cs | 2 +- .../Aggregators/AggregateQualityFixture.cs | 1 - .../DifferentQualitySpecificationFixture.cs | 95 ++++++++ .../GrabbedReleaseQualityFixture.cs | 22 +- .../SameFileSpecificationFixture.cs | 76 ------- .../AugmentWithHistoryFixture.cs | 6 +- .../Profiles/ProfileRepositoryFixture.cs | 1 - .../Qualities/QualityFinderFixture.cs | 1 - .../QueueTests/QueueServiceFixture.cs | 4 + .../Analytics/AnalyticsService.cs | 2 +- .../CustomFormatCalculationService.cs | 5 +- .../Migration/172_add_download_history.cs | 94 ++++++++ src/NzbDrone.Core/Datastore/TableMapping.cs | 6 +- .../AlreadyImportedSpecification.cs | 4 +- .../RssSync/HistorySpecification.cs | 2 +- .../Clients/Blackhole/TorrentBlackhole.cs | 2 +- .../Clients/Blackhole/UsenetBlackhole.cs | 2 +- .../Download/Clients/Deluge/Deluge.cs | 2 +- .../DownloadStation/TorrentDownloadStation.cs | 2 +- .../DownloadStation/UsenetDownloadStation.cs | 2 +- .../Download/Clients/Hadouken/Hadouken.cs | 2 +- .../Download/Clients/NzbVortex/NzbVortex.cs | 2 +- .../Download/Clients/Nzbget/Nzbget.cs | 4 +- .../Download/Clients/Pneumatic/Pneumatic.cs | 2 +- .../Clients/QBittorrent/QBittorrent.cs | 2 +- .../Download/Clients/Sabnzbd/Sabnzbd.cs | 4 +- .../Clients/Transmission/TransmissionBase.cs | 2 +- .../Download/Clients/rTorrent/RTorrent.cs | 2 +- .../Download/Clients/uTorrent/UTorrent.cs | 2 +- .../Download/CompletedDownloadService.cs | 10 +- .../Download/DownloadClientItem.cs | 32 ++- .../Download/DownloadEventHub.cs | 6 +- .../Download/DownloadIgnoredEvent.cs | 2 +- .../Download/DownloadProcessingService.cs | 19 +- src/NzbDrone.Core/Download/DownloadService.cs | 2 + .../Download/FailedDownloadService.cs | 21 +- .../Download/History/DownloadHistory.cs | 35 +++ .../History/DownloadHistoryRepository.cs | 31 +++ .../History/DownloadHistoryService.cs | 210 ++++++++++++++++++ src/NzbDrone.Core/Download/IDownloadClient.cs | 1 - .../Download/IgnoredDownloadService.cs | 2 +- .../Download/MovieGrabbedEvent.cs | 4 +- .../RedownloadFailedDownloadService.cs | 1 - .../TrackedDownloadAlreadyImported.cs | 8 +- .../TrackedDownloadService.cs | 68 +++--- src/NzbDrone.Core/History/History.cs | 8 +- .../History/HistoryRepository.cs | 42 ++-- src/NzbDrone.Core/History/HistoryService.cs | 76 ++++--- .../Events/MovieImportFailedEvent.cs | 6 +- .../MediaFiles/Events/MovieImportedEvent.cs | 7 +- .../MovieImport/ImportApprovedMovie.cs | 4 +- .../AlreadyImportedSpecification.cs | 4 +- .../DifferentQualitySpecification.cs | 52 +++++ .../GrabbedReleaseQualitySpecification.cs | 2 +- .../Specifications/SameFileSpecification.cs | 44 ---- .../Parser/Augmenters/AugmentWithHistory.cs | 4 +- src/NzbDrone.Core/Queue/QueueService.cs | 2 +- .../CustomFormats/CustomFormatModule.cs | 1 - src/Radarr.Api.V3/History/HistoryModule.cs | 14 +- src/Radarr.Api.V3/History/HistoryResource.cs | 4 +- src/Radarr.Api.V3/Movies/MovieLookupModule.cs | 1 - .../Quality/QualityProfileResource.cs | 1 - src/Radarr.Api.V3/Queue/QueueActionModule.cs | 7 +- 86 files changed, 1086 insertions(+), 426 deletions(-) create mode 100644 src/NzbDrone.Core.Test/DecisionEngineTests/AlreadyImportedSpecificationFixture.cs create mode 100644 src/NzbDrone.Core.Test/DecisionEngineTests/BlockedIndexerSpecificationFixture.cs create mode 100644 src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/DifferentQualitySpecificationFixture.cs delete mode 100644 src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/SameFileSpecificationFixture.cs create mode 100644 src/NzbDrone.Core/Datastore/Migration/172_add_download_history.cs create mode 100644 src/NzbDrone.Core/Download/History/DownloadHistory.cs create mode 100644 src/NzbDrone.Core/Download/History/DownloadHistoryRepository.cs create mode 100644 src/NzbDrone.Core/Download/History/DownloadHistoryService.cs create mode 100644 src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/DifferentQualitySpecification.cs delete mode 100644 src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/SameFileSpecification.cs diff --git a/frontend/src/Activity/Queue/QueueRow.js b/frontend/src/Activity/Queue/QueueRow.js index 0b6aa6450..31957be71 100644 --- a/frontend/src/Activity/Queue/QueueRow.js +++ b/frontend/src/Activity/Queue/QueueRow.js @@ -317,7 +317,7 @@ class QueueRow extends Component { diff --git a/frontend/src/Store/Actions/Creators/createHandleActions.js b/frontend/src/Store/Actions/Creators/createHandleActions.js index dc998b350..40f77d700 100644 --- a/frontend/src/Store/Actions/Creators/createHandleActions.js +++ b/frontend/src/Store/Actions/Creators/createHandleActions.js @@ -73,11 +73,12 @@ export default function createHandleActions(handlers, defaultState, section) { const newState = getSectionState(state, payloadSection); const items = newState.items; - if (!newState.itemMap) { - newState.itemMap = createItemMap(items); - } - - const index = payload.id in newState.itemMap ? newState.itemMap[payload.id] : -1; + // Client side collections that are created by adding items to an + // existing array may not have an itemMap, the array is probably empty, + // but on the offchance it's not create a new item map based on the + // items in the array. + const itemMap = newState.itemMap ?? createItemMap(items); + const index = payload.id in itemMap ? itemMap[payload.id] : -1; newState.items = [...items]; @@ -96,6 +97,7 @@ export default function createHandleActions(handlers, defaultState, section) { } else if (!updateOnly) { const newIndex = newState.items.push({ ...otherProps }) - 1; + newState.itemMap = { ...itemMap }; newState.itemMap[payload.id] = newIndex; } @@ -152,7 +154,8 @@ export default function createHandleActions(handlers, defaultState, section) { const serverState = _.omit(data, ['records']); const calculatedState = { totalPages: Math.max(Math.ceil(data.totalRecords / data.pageSize), 1), - items: data.records + items: data.records, + itemMap: createItemMap(data.records) }; return updateSectionState(state, payloadSection, Object.assign(newState, serverState, calculatedState)); diff --git a/frontend/src/Store/Actions/importMovieActions.js b/frontend/src/Store/Actions/importMovieActions.js index cd987c418..fae4f2094 100644 --- a/frontend/src/Store/Actions/importMovieActions.js +++ b/frontend/src/Store/Actions/importMovieActions.js @@ -187,12 +187,12 @@ export const actionHandlers = handleThunks({ const addedIds = []; const allNewMovies = ids.reduce((acc, id) => { - const item = _.find(items, { id }); + const item = items.find((i) => i.id === id); const selectedMovie = item.selectedMovie; // Make sure we have a selected movie and // the same movie hasn't been added yet. - if (selectedMovie && !_.some(acc, { tmdbId: selectedMovie.tmdbId })) { + if (selectedMovie && !acc.some((a) => a.tmdbId === selectedMovie.tmdbId)) { const newMovie = getNewMovie(_.cloneDeep(selectedMovie), item); newMovie.path = item.path; @@ -268,7 +268,7 @@ export const reducers = createHandleActions({ [SET_IMPORT_MOVIE_VALUE]: function(state, { payload }) { const newState = getSectionState(state, section); const items = newState.items; - const index = _.findIndex(items, { id: payload.id }); + const index = items.findIndex((item) => item.id === payload.id); newState.items = [...items]; diff --git a/src/NzbDrone.Api/History/HistoryModule.cs b/src/NzbDrone.Api/History/HistoryModule.cs index 63c534c65..e4cfa21f7 100644 --- a/src/NzbDrone.Api/History/HistoryModule.cs +++ b/src/NzbDrone.Api/History/HistoryModule.cs @@ -28,7 +28,7 @@ namespace NzbDrone.Api.History Post("/failed", x => MarkAsFailed()); } - protected HistoryResource MapToResource(Core.History.History model) + protected HistoryResource MapToResource(MovieHistory model) { var resource = model.ToResource(); resource.Movie = model.Movie.ToResource(); @@ -44,12 +44,12 @@ namespace NzbDrone.Api.History private PagingResource GetHistory(PagingResource pagingResource) { var movieId = Request.Query.MovieId; - var pagingSpec = pagingResource.MapToPagingSpec("date", SortDirection.Descending); + var pagingSpec = pagingResource.MapToPagingSpec("date", SortDirection.Descending); var filter = pagingResource.Filters.FirstOrDefault(); if (filter != null && filter.Key == "eventType") { - var filterValue = (HistoryEventType)Convert.ToInt32(filter.Value); + var filterValue = (MovieHistoryEventType)Convert.ToInt32(filter.Value); pagingSpec.FilterExpressions.Add(v => v.EventType == filterValue); } diff --git a/src/NzbDrone.Api/History/HistoryResource.cs b/src/NzbDrone.Api/History/HistoryResource.cs index 699e7083f..356fdb438 100644 --- a/src/NzbDrone.Api/History/HistoryResource.cs +++ b/src/NzbDrone.Api/History/HistoryResource.cs @@ -16,7 +16,7 @@ namespace NzbDrone.Api.History public DateTime Date { get; set; } public string DownloadId { get; set; } - public HistoryEventType EventType { get; set; } + public MovieHistoryEventType EventType { get; set; } public Dictionary Data { get; set; } public MovieResource Movie { get; set; } @@ -24,7 +24,7 @@ namespace NzbDrone.Api.History public static class HistoryResourceMapper { - public static HistoryResource ToResource(this Core.History.History model) + public static HistoryResource ToResource(this MovieHistory model) { if (model == null) { diff --git a/src/NzbDrone.Api/MovieFiles/MovieFileModule.cs b/src/NzbDrone.Api/MovieFiles/MovieFileModule.cs index 93a1ae136..065447f6a 100644 --- a/src/NzbDrone.Api/MovieFiles/MovieFileModule.cs +++ b/src/NzbDrone.Api/MovieFiles/MovieFileModule.cs @@ -1,4 +1,3 @@ -using NLog; using NzbDrone.Core.Datastore.Events; using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.Exceptions; diff --git a/src/NzbDrone.Api/Queue/QueueActionModule.cs b/src/NzbDrone.Api/Queue/QueueActionModule.cs index 01eb8e3d7..6398af620 100644 --- a/src/NzbDrone.Api/Queue/QueueActionModule.cs +++ b/src/NzbDrone.Api/Queue/QueueActionModule.cs @@ -14,7 +14,6 @@ namespace NzbDrone.Api.Queue { private readonly IQueueService _queueService; private readonly ITrackedDownloadService _trackedDownloadService; - private readonly ICompletedDownloadService _completedDownloadService; private readonly IFailedDownloadService _failedDownloadService; private readonly IProvideDownloadClient _downloadClientProvider; private readonly IPendingReleaseService _pendingReleaseService; @@ -22,7 +21,6 @@ namespace NzbDrone.Api.Queue public QueueActionModule(IQueueService queueService, ITrackedDownloadService trackedDownloadService, - ICompletedDownloadService completedDownloadService, IFailedDownloadService failedDownloadService, IProvideDownloadClient downloadClientProvider, IPendingReleaseService pendingReleaseService, @@ -30,7 +28,6 @@ namespace NzbDrone.Api.Queue { _queueService = queueService; _trackedDownloadService = trackedDownloadService; - _completedDownloadService = completedDownloadService; _failedDownloadService = failedDownloadService; _downloadClientProvider = downloadClientProvider; _pendingReleaseService = pendingReleaseService; diff --git a/src/NzbDrone.Core.Test/Datastore/DatabaseRelationshipFixture.cs b/src/NzbDrone.Core.Test/Datastore/DatabaseRelationshipFixture.cs index b79ce1725..8f5b89962 100644 --- a/src/NzbDrone.Core.Test/Datastore/DatabaseRelationshipFixture.cs +++ b/src/NzbDrone.Core.Test/Datastore/DatabaseRelationshipFixture.cs @@ -3,6 +3,7 @@ using System.Linq; using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; +using NzbDrone.Core.History; using NzbDrone.Core.Languages; using NzbDrone.Core.Qualities; using NzbDrone.Core.Test.Framework; @@ -24,7 +25,7 @@ namespace NzbDrone.Core.Test.Datastore var quality = new QualityModel { Quality = Quality.Bluray720p, Revision = new Revision(version: 2) }; var languages = new List { Language.English }; - var history = Builder.CreateNew() + var history = Builder.CreateNew() .With(c => c.Id = 0) .With(c => c.Quality = quality) .With(c => c.Languages = languages) @@ -32,7 +33,7 @@ namespace NzbDrone.Core.Test.Datastore Db.Insert(history); - var loadedQuality = Db.Single().Quality; + var loadedQuality = Db.Single().Quality; loadedQuality.Should().Be(quality); } @@ -41,7 +42,7 @@ namespace NzbDrone.Core.Test.Datastore { var languages = new List { Language.English }; - var history = Builder.CreateListOfSize(2) + var history = Builder.CreateListOfSize(2) .All().With(c => c.Id = 0) .With(c => c.Languages = languages) .Build().ToList(); @@ -51,7 +52,7 @@ namespace NzbDrone.Core.Test.Datastore Db.InsertMany(history); - var returnedHistory = Db.All(); + var returnedHistory = Db.All(); returnedHistory[0].Quality.Quality.Should().Be(Quality.HDTV1080p); } diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/AlreadyImportedSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/AlreadyImportedSpecificationFixture.cs new file mode 100644 index 000000000..237fb3bcd --- /dev/null +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/AlreadyImportedSpecificationFixture.cs @@ -0,0 +1,184 @@ +using System; +using System.Collections.Generic; +using FizzWare.NBuilder; +using FluentAssertions; +using Moq; +using NUnit.Framework; +using NzbDrone.Core.Configuration; +using NzbDrone.Core.DecisionEngine.Specifications; +using NzbDrone.Core.History; +using NzbDrone.Core.Indexers; +using NzbDrone.Core.Movies; +using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.Qualities; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.DecisionEngineTests +{ + [TestFixture] + public class AlreadyImportedSpecificationFixture : CoreTest + { + private const int FIRST_MOVIE_ID = 1; + private const string TITLE = "Movie.Title.2018.720p.HDTV.x264-Radarr"; + + private Movie _movie; + private QualityModel _hdtv720p; + private QualityModel _hdtv1080p; + private RemoteMovie _remoteMovie; + private List _history; + + [SetUp] + public void Setup() + { + _movie = Builder.CreateNew() + .With(m => m.Id = FIRST_MOVIE_ID) + .With(m => m.MovieFileId = 1) + .Build(); + + _hdtv720p = new QualityModel(Quality.HDTV720p, new Revision(version: 1)); + _hdtv1080p = new QualityModel(Quality.HDTV1080p, new Revision(version: 1)); + + _remoteMovie = new RemoteMovie + { + Movie = _movie, + ParsedMovieInfo = new ParsedMovieInfo { Quality = _hdtv720p }, + Release = Builder.CreateNew() + .Build() + }; + + _history = new List(); + + Mocker.GetMock() + .SetupGet(s => s.EnableCompletedDownloadHandling) + .Returns(true); + + Mocker.GetMock() + .Setup(s => s.GetByMovieId(It.IsAny(), null)) + .Returns(_history); + } + + private void GivenCdhDisabled() + { + Mocker.GetMock() + .SetupGet(s => s.EnableCompletedDownloadHandling) + .Returns(false); + } + + private void GivenHistoryItem(string downloadId, string sourceTitle, QualityModel quality, MovieHistoryEventType eventType) + { + _history.Add(new MovieHistory + { + DownloadId = downloadId, + SourceTitle = sourceTitle, + Quality = quality, + Date = DateTime.UtcNow, + EventType = eventType + }); + } + + [Test] + public void should_be_accepted_if_CDH_is_disabled() + { + GivenCdhDisabled(); + + Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeTrue(); + } + + [Test] + public void should_be_accepted_if_movie_does_not_have_a_file() + { + _remoteMovie.Movie.MovieFileId = 0; + + Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeTrue(); + } + + [Test] + public void should_be_accepted_if_movie_does_not_have_grabbed_event() + { + Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeTrue(); + } + + [Test] + public void should_be_accepted_if_movie_does_not_have_imported_event() + { + GivenHistoryItem(Guid.NewGuid().ToString().ToUpper(), TITLE, _hdtv720p, MovieHistoryEventType.Grabbed); + + Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeTrue(); + } + + [Test] + public void should_be_accepted_if_grabbed_and_imported_quality_is_the_same() + { + var downloadId = Guid.NewGuid().ToString().ToUpper(); + + GivenHistoryItem(downloadId, TITLE, _hdtv720p, MovieHistoryEventType.Grabbed); + GivenHistoryItem(downloadId, TITLE, _hdtv720p, MovieHistoryEventType.DownloadFolderImported); + + Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeTrue(); + } + + [Test] + public void should_be_accepted_if_grabbed_download_id_and_release_torrent_hash_is_unknown() + { + var downloadId = Guid.NewGuid().ToString().ToUpper(); + + GivenHistoryItem(downloadId, TITLE, _hdtv720p, MovieHistoryEventType.Grabbed); + GivenHistoryItem(downloadId, TITLE, _hdtv1080p, MovieHistoryEventType.DownloadFolderImported); + + _remoteMovie.Release = Builder.CreateNew() + .With(t => t.DownloadProtocol = DownloadProtocol.Torrent) + .With(t => t.InfoHash = null) + .Build(); + + Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeTrue(); + } + + [Test] + public void should_be_accepted_if_grabbed_download_does_not_have_an_id() + { + var downloadId = Guid.NewGuid().ToString().ToUpper(); + + GivenHistoryItem(null, TITLE, _hdtv720p, MovieHistoryEventType.Grabbed); + GivenHistoryItem(downloadId, TITLE, _hdtv1080p, MovieHistoryEventType.DownloadFolderImported); + + _remoteMovie.Release = Builder.CreateNew() + .With(t => t.DownloadProtocol = DownloadProtocol.Torrent) + .With(t => t.InfoHash = downloadId) + .Build(); + + Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeTrue(); + } + + [Test] + public void should_be_rejected_if_grabbed_download_id_matches_release_torrent_hash() + { + var downloadId = Guid.NewGuid().ToString().ToUpper(); + + GivenHistoryItem(downloadId, TITLE, _hdtv720p, MovieHistoryEventType.Grabbed); + GivenHistoryItem(downloadId, TITLE, _hdtv1080p, MovieHistoryEventType.DownloadFolderImported); + + _remoteMovie.Release = Builder.CreateNew() + .With(t => t.DownloadProtocol = DownloadProtocol.Torrent) + .With(t => t.InfoHash = downloadId) + .Build(); + + Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeFalse(); + } + + [Test] + public void should_be_rejected_if_release_title_matches_grabbed_event_source_title() + { + var downloadId = Guid.NewGuid().ToString().ToUpper(); + + GivenHistoryItem(downloadId, TITLE, _hdtv720p, MovieHistoryEventType.Grabbed); + GivenHistoryItem(downloadId, TITLE, _hdtv1080p, MovieHistoryEventType.DownloadFolderImported); + + _remoteMovie.Release = Builder.CreateNew() + .With(t => t.DownloadProtocol = DownloadProtocol.Torrent) + .With(t => t.InfoHash = downloadId) + .Build(); + + Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeFalse(); + } + } +} diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/BlockedIndexerSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/BlockedIndexerSpecificationFixture.cs new file mode 100644 index 000000000..06a8ac47b --- /dev/null +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/BlockedIndexerSpecificationFixture.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.DecisionEngine; +using NzbDrone.Core.DecisionEngine.Specifications; +using NzbDrone.Core.Indexers; +using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.DecisionEngineTests +{ + [TestFixture] + + public class BlockedIndexerSpecificationFixture : CoreTest + { + private RemoteMovie _remoteMovie; + + [SetUp] + public void Setup() + { + _remoteMovie = new RemoteMovie + { + Release = new ReleaseInfo { IndexerId = 1 } + }; + + Mocker.GetMock() + .Setup(v => v.GetBlockedProviders()) + .Returns(new List()); + } + + private void WithBlockedIndexer() + { + Mocker.GetMock() + .Setup(v => v.GetBlockedProviders()) + .Returns(new List { new IndexerStatus { ProviderId = 1, DisabledTill = DateTime.UtcNow } }); + } + + [Test] + public void should_return_true_if_no_blocked_indexer() + { + Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeTrue(); + } + + [Test] + public void should_return_false_if_blocked_indexer() + { + WithBlockedIndexer(); + + Subject.IsSatisfiedBy(_remoteMovie, null).Accepted.Should().BeFalse(); + Subject.Type.Should().Be(RejectionType.Temporary); + } + } +} diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/HistorySpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/HistorySpecificationFixture.cs index bc5d80312..fde8f7aee 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/HistorySpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/HistorySpecificationFixture.cs @@ -65,14 +65,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests .Returns(true); Mocker.GetMock() - .Setup(x => x.ParseCustomFormat(It.IsAny())) + .Setup(x => x.ParseCustomFormat(It.IsAny())) .Returns(new List()); } - private void GivenMostRecentForEpisode(int episodeId, string downloadId, QualityModel quality, DateTime date, HistoryEventType eventType) + private void GivenMostRecentForEpisode(int episodeId, string downloadId, QualityModel quality, DateTime date, MovieHistoryEventType eventType) { Mocker.GetMock().Setup(s => s.MostRecentForMovie(episodeId)) - .Returns(new History.History { DownloadId = downloadId, Quality = quality, Date = date, EventType = eventType }); + .Returns(new MovieHistory { DownloadId = downloadId, Quality = quality, Date = date, EventType = eventType }); } private void GivenCdhDisabled() @@ -91,14 +91,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests [Test] public void should_return_true_if_latest_history_item_is_null() { - Mocker.GetMock().Setup(s => s.MostRecentForMovie(It.IsAny())).Returns((History.History)null); + Mocker.GetMock().Setup(s => s.MostRecentForMovie(It.IsAny())).Returns((MovieHistory)null); _upgradeHistory.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue(); } [Test] public void should_return_true_if_latest_history_item_is_not_grabbed() { - GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _notupgradableQuality, DateTime.UtcNow, HistoryEventType.DownloadFailed); + GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _notupgradableQuality, DateTime.UtcNow, MovieHistoryEventType.DownloadFailed); _upgradeHistory.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue(); } @@ -111,14 +111,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests [Test] public void should_return_true_if_latest_history_item_is_older_than_twelve_hours() { - GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _notupgradableQuality, DateTime.UtcNow.AddHours(-13), HistoryEventType.Grabbed); + GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _notupgradableQuality, DateTime.UtcNow.AddHours(-13), MovieHistoryEventType.Grabbed); _upgradeHistory.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue(); } [Test] public void should_be_upgradable_if_only_episode_is_upgradable() { - GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _upgradableQuality, DateTime.UtcNow, HistoryEventType.Grabbed); + GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _upgradableQuality, DateTime.UtcNow, MovieHistoryEventType.Grabbed); _upgradeHistory.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue(); } @@ -170,10 +170,10 @@ namespace NzbDrone.Core.Test.DecisionEngineTests _upgradableQuality = new QualityModel(Quality.WEBDL1080p, new Revision(version: 1)); Mocker.GetMock() - .Setup(x => x.ParseCustomFormat(It.IsAny())) + .Setup(x => x.ParseCustomFormat(It.IsAny())) .Returns(new List()); - GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _upgradableQuality, DateTime.UtcNow, HistoryEventType.Grabbed); + GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _upgradableQuality, DateTime.UtcNow, MovieHistoryEventType.Grabbed); _upgradeHistory.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); } @@ -192,7 +192,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests _parseResultSingle.ParsedMovieInfo.Quality = new QualityModel(Quality.WEBDL1080p, new Revision(version: 1)); _upgradableQuality = new QualityModel(Quality.Bluray1080p, new Revision(version: 1)); - GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _upgradableQuality, DateTime.UtcNow, HistoryEventType.Grabbed); + GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _upgradableQuality, DateTime.UtcNow, MovieHistoryEventType.Grabbed); _upgradeHistory.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); } @@ -200,7 +200,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests [Test] public void should_return_false_if_latest_history_item_is_only_one_hour_old() { - GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _notupgradableQuality, DateTime.UtcNow.AddHours(-1), HistoryEventType.Grabbed); + GivenMostRecentForEpisode(FIRST_EPISODE_ID, string.Empty, _notupgradableQuality, DateTime.UtcNow.AddHours(-1), MovieHistoryEventType.Grabbed); _upgradeHistory.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); } @@ -208,7 +208,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests public void should_return_false_if_latest_history_has_a_download_id_and_cdh_is_disabled() { GivenCdhDisabled(); - GivenMostRecentForEpisode(FIRST_EPISODE_ID, "test", _upgradableQuality, DateTime.UtcNow.AddDays(-100), HistoryEventType.Grabbed); + GivenMostRecentForEpisode(FIRST_EPISODE_ID, "test", _upgradableQuality, DateTime.UtcNow.AddDays(-100), MovieHistoryEventType.Grabbed); _upgradeHistory.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue(); } @@ -227,7 +227,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests _parseResultSingle.ParsedMovieInfo.Quality = new QualityModel(Quality.Bluray1080p, new Revision(version: 1)); _upgradableQuality = new QualityModel(Quality.WEBDL1080p, new Revision(version: 1)); - GivenMostRecentForEpisode(FIRST_EPISODE_ID, "test", _upgradableQuality, DateTime.UtcNow.AddDays(-100), HistoryEventType.Grabbed); + GivenMostRecentForEpisode(FIRST_EPISODE_ID, "test", _upgradableQuality, DateTime.UtcNow.AddDays(-100), MovieHistoryEventType.Grabbed); _upgradeHistory.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); } @@ -236,7 +236,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests public void should_return_false_if_only_episode_is_not_upgradable_and_cdh_is_disabled() { GivenCdhDisabled(); - GivenMostRecentForEpisode(FIRST_EPISODE_ID, "test", _notupgradableQuality, DateTime.UtcNow.AddDays(-100), HistoryEventType.Grabbed); + GivenMostRecentForEpisode(FIRST_EPISODE_ID, "test", _notupgradableQuality, DateTime.UtcNow.AddDays(-100), MovieHistoryEventType.Grabbed); _upgradeHistory.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); } } diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs index 7408ed86e..9b694f388 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs @@ -63,14 +63,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests } [Test] - public void should_return_true_if_episode_has_no_existing_file() + public void should_return_true_if_movie_has_no_existing_file() { _parseResultSingle.Movie.MovieFile = null; _upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue(); } [Test] - public void should_be_upgradable_if_only_episode_is_upgradable() + public void should_be_upgradable_if_only_movie_is_upgradable() { WithFirstFileUpgradable(); _upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue(); diff --git a/src/NzbDrone.Core.Test/Download/CompletedDownloadServiceTests/ImportFixture.cs b/src/NzbDrone.Core.Test/Download/CompletedDownloadServiceTests/ImportFixture.cs index 3744fdc6b..9e29b9acb 100644 --- a/src/NzbDrone.Core.Test/Download/CompletedDownloadServiceTests/ImportFixture.cs +++ b/src/NzbDrone.Core.Test/Download/CompletedDownloadServiceTests/ImportFixture.cs @@ -51,7 +51,7 @@ namespace NzbDrone.Core.Test.Download Mocker.GetMock() .Setup(s => s.MostRecentForDownloadId(_trackedDownload.DownloadItem.DownloadId)) - .Returns(new History.History()); + .Returns(new MovieHistory()); Mocker.GetMock() .Setup(s => s.GetMovie("Drone.1998")) @@ -72,7 +72,7 @@ namespace NzbDrone.Core.Test.Download _trackedDownload.DownloadItem.Title = "Droned Pilot"; // Set a badly named download Mocker.GetMock() .Setup(s => s.MostRecentForDownloadId(It.Is(i => i == "1234"))) - .Returns(new History.History() { SourceTitle = "Droned 1998" }); + .Returns(new MovieHistory() { SourceTitle = "Droned 1998" }); Mocker.GetMock() .Setup(s => s.GetMovie(It.IsAny())) diff --git a/src/NzbDrone.Core.Test/Download/CompletedDownloadServiceTests/ProcessFixture.cs b/src/NzbDrone.Core.Test/Download/CompletedDownloadServiceTests/ProcessFixture.cs index 9e97eecb5..0a3dafb12 100644 --- a/src/NzbDrone.Core.Test/Download/CompletedDownloadServiceTests/ProcessFixture.cs +++ b/src/NzbDrone.Core.Test/Download/CompletedDownloadServiceTests/ProcessFixture.cs @@ -4,13 +4,11 @@ using FluentAssertions; using Moq; using NUnit.Framework; using NzbDrone.Common.Disk; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Download.TrackedDownloads; using NzbDrone.Core.History; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles.MovieImport; -using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Movies; using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.Model; @@ -51,7 +49,7 @@ namespace NzbDrone.Core.Test.Download.CompletedDownloadServiceTests Mocker.GetMock() .Setup(s => s.MostRecentForDownloadId(_trackedDownload.DownloadItem.DownloadId)) - .Returns(new History.History()); + .Returns(new MovieHistory()); Mocker.GetMock() .Setup(s => s.GetMovie("Drone.S01E01.HDTV")) @@ -70,7 +68,7 @@ namespace NzbDrone.Core.Test.Download.CompletedDownloadServiceTests { Mocker.GetMock() .Setup(s => s.MostRecentForDownloadId(_trackedDownload.DownloadItem.DownloadId)) - .Returns((History.History)null); + .Returns((MovieHistory)null); } private void GivenMovieMatch() @@ -86,7 +84,7 @@ namespace NzbDrone.Core.Test.Download.CompletedDownloadServiceTests _trackedDownload.DownloadItem.Title = "Droned Pilot"; // Set a badly named download Mocker.GetMock() .Setup(s => s.MostRecentForDownloadId(It.Is(i => i == "1234"))) - .Returns(new History.History() { SourceTitle = "Droned S01E01" }); + .Returns(new MovieHistory() { SourceTitle = "Droned S01E01" }); Mocker.GetMock() .Setup(s => s.GetMovie(It.IsAny())) diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadClientFixtureBase.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadClientFixtureBase.cs index cae124c9a..2a1e1fd5b 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadClientFixtureBase.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadClientFixtureBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using FluentAssertions; using Moq; using NUnit.Framework; @@ -58,7 +58,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests protected void VerifyIdentifiable(DownloadClientItem downloadClientItem) { - downloadClientItem.DownloadClient.Should().Be(Subject.Definition.Name); + downloadClientItem.DownloadClientInfo.Protocol.Should().Be(Subject.Protocol); + downloadClientItem.DownloadClientInfo.Id.Should().Be(Subject.Definition.Id); + downloadClientItem.DownloadClientInfo.Name.Should().Be(Subject.Definition.Name); downloadClientItem.DownloadId.Should().NotBeNullOrEmpty(); downloadClientItem.Title.Should().NotBeNullOrEmpty(); } diff --git a/src/NzbDrone.Core.Test/Download/FailedDownloadServiceTests/ProcessFailedFixture.cs b/src/NzbDrone.Core.Test/Download/FailedDownloadServiceTests/ProcessFailedFixture.cs index b1bcd9808..5a2633354 100644 --- a/src/NzbDrone.Core.Test/Download/FailedDownloadServiceTests/ProcessFailedFixture.cs +++ b/src/NzbDrone.Core.Test/Download/FailedDownloadServiceTests/ProcessFailedFixture.cs @@ -19,7 +19,7 @@ namespace NzbDrone.Core.Test.Download.FailedDownloadServiceTests public class ProcessFailedFixture : CoreTest { private TrackedDownload _trackedDownload; - private List _grabHistory; + private List _grabHistory; [SetUp] public void Setup() @@ -30,7 +30,7 @@ namespace NzbDrone.Core.Test.Download.FailedDownloadServiceTests .With(h => h.Title = "Drone.S01E01.HDTV") .Build(); - _grabHistory = Builder.CreateListOfSize(2).BuildList(); + _grabHistory = Builder.CreateListOfSize(2).BuildList(); var remoteMovie = new RemoteMovie { @@ -44,7 +44,7 @@ namespace NzbDrone.Core.Test.Download.FailedDownloadServiceTests .Build(); Mocker.GetMock() - .Setup(s => s.Find(_trackedDownload.DownloadItem.DownloadId, HistoryEventType.Grabbed)) + .Setup(s => s.Find(_trackedDownload.DownloadItem.DownloadId, MovieHistoryEventType.Grabbed)) .Returns(_grabHistory); } diff --git a/src/NzbDrone.Core.Test/Download/FailedDownloadServiceTests/ProcessFixture.cs b/src/NzbDrone.Core.Test/Download/FailedDownloadServiceTests/ProcessFixture.cs index 009383586..4d96e4c7b 100644 --- a/src/NzbDrone.Core.Test/Download/FailedDownloadServiceTests/ProcessFixture.cs +++ b/src/NzbDrone.Core.Test/Download/FailedDownloadServiceTests/ProcessFixture.cs @@ -19,7 +19,7 @@ namespace NzbDrone.Core.Test.Download.FailedDownloadServiceTests public class ProcessFixture : CoreTest { private TrackedDownload _trackedDownload; - private List _grabHistory; + private List _grabHistory; [SetUp] public void Setup() @@ -30,7 +30,7 @@ namespace NzbDrone.Core.Test.Download.FailedDownloadServiceTests .With(h => h.Title = "Drone.S01E01.HDTV") .Build(); - _grabHistory = Builder.CreateListOfSize(2).BuildList(); + _grabHistory = Builder.CreateListOfSize(2).BuildList(); var remoteMovie = new RemoteMovie { @@ -44,15 +44,15 @@ namespace NzbDrone.Core.Test.Download.FailedDownloadServiceTests .Build(); Mocker.GetMock() - .Setup(s => s.Find(_trackedDownload.DownloadItem.DownloadId, HistoryEventType.Grabbed)) + .Setup(s => s.Find(_trackedDownload.DownloadItem.DownloadId, MovieHistoryEventType.Grabbed)) .Returns(_grabHistory); } private void GivenNoGrabbedHistory() { Mocker.GetMock() - .Setup(s => s.Find(_trackedDownload.DownloadItem.DownloadId, HistoryEventType.Grabbed)) - .Returns(new List()); + .Setup(s => s.Find(_trackedDownload.DownloadItem.DownloadId, MovieHistoryEventType.Grabbed)) + .Returns(new List()); } [Test] diff --git a/src/NzbDrone.Core.Test/Download/TrackedDownloads/TrackedDownloadAlreadyImportedFixture.cs b/src/NzbDrone.Core.Test/Download/TrackedDownloads/TrackedDownloadAlreadyImportedFixture.cs index a571da5fb..ce9768219 100644 --- a/src/NzbDrone.Core.Test/Download/TrackedDownloads/TrackedDownloadAlreadyImportedFixture.cs +++ b/src/NzbDrone.Core.Test/Download/TrackedDownloads/TrackedDownloadAlreadyImportedFixture.cs @@ -15,7 +15,7 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads { private Movie _movie; private TrackedDownload _trackedDownload; - private List _historyItems; + private List _historyItems; [SetUp] public void Setup() @@ -30,15 +30,15 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads .With(t => t.RemoteMovie = remoteMovie) .Build(); - _historyItems = new List(); + _historyItems = new List(); } - public void GivenHistoryForMovie(Movie movie, params HistoryEventType[] eventTypes) + public void GivenHistoryForMovie(Movie movie, params MovieHistoryEventType[] eventTypes) { foreach (var eventType in eventTypes) { _historyItems.Add( - Builder.CreateNew() + Builder.CreateNew() .With(h => h.MovieId = movie.Id) .With(h => h.EventType = eventType) .Build()); @@ -56,7 +56,7 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads [Test] public void should_return_false_if_single_movie_download_is_not_imported() { - GivenHistoryForMovie(_movie, HistoryEventType.Grabbed); + GivenHistoryForMovie(_movie, MovieHistoryEventType.Grabbed); Subject.IsImported(_trackedDownload, _historyItems) .Should() @@ -66,7 +66,7 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads [Test] public void should_return_true_if_single_movie_download_is_imported() { - GivenHistoryForMovie(_movie, HistoryEventType.DownloadFolderImported, HistoryEventType.Grabbed); + GivenHistoryForMovie(_movie, MovieHistoryEventType.DownloadFolderImported, MovieHistoryEventType.Grabbed); Subject.IsImported(_trackedDownload, _historyItems) .Should() diff --git a/src/NzbDrone.Core.Test/Download/TrackedDownloads/TrackedDownloadServiceFixture.cs b/src/NzbDrone.Core.Test/Download/TrackedDownloads/TrackedDownloadServiceFixture.cs index 857b7d826..0f48f933e 100644 --- a/src/NzbDrone.Core.Test/Download/TrackedDownloads/TrackedDownloadServiceFixture.cs +++ b/src/NzbDrone.Core.Test/Download/TrackedDownloads/TrackedDownloadServiceFixture.cs @@ -25,9 +25,9 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads { Mocker.GetMock() .Setup(s => s.FindByDownloadId(It.Is(sr => sr == "35238"))) - .Returns(new List() + .Returns(new List() { - new History.History() + new MovieHistory() { DownloadId = "35238", SourceTitle = "TV Series S01", @@ -68,6 +68,12 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads { Title = "A Movie 1998", DownloadId = "35238", + DownloadClientInfo = new DownloadClientItemClientInfo + { + Protocol = client.Protocol, + Id = client.Id, + Name = client.Name + } }; var trackedDownload = Subject.TrackDownload(client, item); diff --git a/src/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs b/src/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs index 8686d342f..4b2cd9517 100644 --- a/src/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs +++ b/src/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs @@ -12,7 +12,7 @@ using NzbDrone.Core.Test.Framework; namespace NzbDrone.Core.Test.HistoryTests { [TestFixture] - public class HistoryRepositoryFixture : DbTest + public class HistoryRepositoryFixture : DbTest { [SetUp] public void Setup() @@ -22,7 +22,7 @@ namespace NzbDrone.Core.Test.HistoryTests [Test] public void should_read_write_dictionary() { - var history = Builder.CreateNew() + var history = Builder.CreateNew() .With(c => c.Quality = new QualityModel()) .With(c => c.Languages = new List()) .BuildNew(); @@ -38,18 +38,18 @@ namespace NzbDrone.Core.Test.HistoryTests [Test] public void should_get_download_history() { - var historyBluray = Builder.CreateNew() + var historyBluray = Builder.CreateNew() .With(c => c.Quality = new QualityModel(Quality.Bluray1080p)) .With(c => c.Languages = new List { Language.English }) .With(c => c.MovieId = 12) - .With(c => c.EventType = HistoryEventType.Grabbed) + .With(c => c.EventType = MovieHistoryEventType.Grabbed) .BuildNew(); - var historyDvd = Builder.CreateNew() + var historyDvd = Builder.CreateNew() .With(c => c.Quality = new QualityModel(Quality.DVD)) .With(c => c.Languages = new List { Language.English }) .With(c => c.MovieId = 12) - .With(c => c.EventType = HistoryEventType.Grabbed) + .With(c => c.EventType = MovieHistoryEventType.Grabbed) .BuildNew(); Subject.Insert(historyBluray); @@ -63,18 +63,18 @@ namespace NzbDrone.Core.Test.HistoryTests [Test] public void should_get_movie_history() { - var historyMovie1 = Builder.CreateNew() + var historyMovie1 = Builder.CreateNew() .With(c => c.Quality = new QualityModel(Quality.Bluray1080p)) .With(c => c.Languages = new List { Language.English }) .With(c => c.MovieId = 12) - .With(c => c.EventType = HistoryEventType.Grabbed) + .With(c => c.EventType = MovieHistoryEventType.Grabbed) .BuildNew(); - var historyMovie2 = Builder.CreateNew() + var historyMovie2 = Builder.CreateNew() .With(c => c.Quality = new QualityModel(Quality.Bluray1080p)) .With(c => c.Languages = new List { Language.English }) .With(c => c.MovieId = 13) - .With(c => c.EventType = HistoryEventType.Grabbed) + .With(c => c.EventType = MovieHistoryEventType.Grabbed) .BuildNew(); Subject.Insert(historyMovie1); @@ -88,19 +88,19 @@ namespace NzbDrone.Core.Test.HistoryTests [Test] public void should_sort_movie_history_by_date() { - var historyFirst = Builder.CreateNew() + var historyFirst = Builder.CreateNew() .With(c => c.Quality = new QualityModel(Quality.Bluray1080p)) .With(c => c.Languages = new List { Language.English }) .With(c => c.MovieId = 12) - .With(c => c.EventType = HistoryEventType.MovieFileRenamed) + .With(c => c.EventType = MovieHistoryEventType.MovieFileRenamed) .With(c => c.Date = DateTime.UtcNow) .BuildNew(); - var historySecond = Builder.CreateNew() + var historySecond = Builder.CreateNew() .With(c => c.Quality = new QualityModel(Quality.Bluray1080p)) .With(c => c.Languages = new List { Language.English }) .With(c => c.MovieId = 12) - .With(c => c.EventType = HistoryEventType.Grabbed) + .With(c => c.EventType = MovieHistoryEventType.Grabbed) .With(c => c.Date = DateTime.UtcNow.AddMinutes(10)) .BuildNew(); @@ -110,7 +110,7 @@ namespace NzbDrone.Core.Test.HistoryTests var movieHistory = Subject.GetByMovieId(12, null); movieHistory.Should().HaveCount(2); - movieHistory.First().EventType.Should().Be(HistoryEventType.Grabbed); + movieHistory.First().EventType.Should().Be(MovieHistoryEventType.Grabbed); } } } diff --git a/src/NzbDrone.Core.Test/HistoryTests/HistoryServiceFixture.cs b/src/NzbDrone.Core.Test/HistoryTests/HistoryServiceFixture.cs index 83a0457fb..b866b6890 100644 --- a/src/NzbDrone.Core.Test/HistoryTests/HistoryServiceFixture.cs +++ b/src/NzbDrone.Core.Test/HistoryTests/HistoryServiceFixture.cs @@ -4,7 +4,9 @@ using FizzWare.NBuilder; using FluentAssertions; using Moq; using NUnit.Framework; +using NzbDrone.Core.Download; using NzbDrone.Core.History; +using NzbDrone.Core.Indexers; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles.Events; using NzbDrone.Core.Movies; @@ -78,10 +80,21 @@ namespace NzbDrone.Core.Test.HistoryTests Path = @"C:\Test\Unsorted\Movie.2011.mkv" }; - Subject.Handle(new MovieImportedEvent(localMovie, movieFile, true, "sab", "abcd")); + var downloadClientItem = new DownloadClientItem + { + DownloadClientInfo = new DownloadClientItemClientInfo + { + Protocol = DownloadProtocol.Usenet, + Id = 1, + Name = "sab" + }, + DownloadId = "abcd" + }; + + Subject.Handle(new MovieImportedEvent(localMovie, movieFile, true, downloadClientItem, "abcd")); Mocker.GetMock() - .Verify(v => v.Insert(It.Is(h => h.SourceTitle == Path.GetFileNameWithoutExtension(localMovie.Path)))); + .Verify(v => v.Insert(It.Is(h => h.SourceTitle == Path.GetFileNameWithoutExtension(localMovie.Path)))); } } } diff --git a/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedHistoryItemsFixture.cs b/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedHistoryItemsFixture.cs index cbffa879f..ae3fde9be 100644 --- a/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedHistoryItemsFixture.cs +++ b/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedHistoryItemsFixture.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; +using NzbDrone.Core.History; using NzbDrone.Core.Housekeeping.Housekeepers; using NzbDrone.Core.Languages; using NzbDrone.Core.Movies; @@ -11,7 +12,7 @@ using NzbDrone.Core.Test.Framework; namespace NzbDrone.Core.Test.Housekeeping.Housekeepers { [TestFixture] - public class CleanupOrphanedHistoryItemsFixture : DbTest + public class CleanupOrphanedHistoryItemsFixture : DbTest { private Movie _movie; @@ -30,7 +31,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers [Test] public void should_delete_orphaned_items() { - var history = Builder.CreateNew() + var history = Builder.CreateNew() .With(h => h.Quality = new QualityModel()) .With(h => h.Languages = new List()) .BuildNew(); @@ -45,7 +46,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers { GivenSeries(); - var history = Builder.CreateNew() + var history = Builder.CreateNew() .With(h => h.Quality = new QualityModel()) .With(h => h.Languages = new List()) .With(h => h.MovieId = _movie.Id) diff --git a/src/NzbDrone.Core.Test/IndexerTests/FileListTests/FileListRequestGeneratorFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/FileListTests/FileListRequestGeneratorFixture.cs index 702d800cf..39231521f 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/FileListTests/FileListRequestGeneratorFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/FileListTests/FileListRequestGeneratorFixture.cs @@ -1,8 +1,6 @@ using System.Linq; using FluentAssertions; -using Newtonsoft.Json; using NUnit.Framework; -using NzbDrone.Common.Http; using NzbDrone.Core.Indexers.FileList; using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.Test.Framework; diff --git a/src/NzbDrone.Core.Test/MediaFiles/ImportApprovedMoviesFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/ImportApprovedMoviesFixture.cs index a8345fc33..a2cc6ae20 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/ImportApprovedMoviesFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/ImportApprovedMoviesFixture.cs @@ -64,7 +64,7 @@ namespace NzbDrone.Core.Test.MediaFiles Mocker.GetMock() .Setup(x => x.FindByDownloadId(It.IsAny())) - .Returns(new List()); + .Returns(new List()); _downloadClientItem = Builder.CreateNew() .With(d => d.OutputPath = new OsPath(outputPath)) diff --git a/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Aggregation/Aggregators/AggregateQualityFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Aggregation/Aggregators/AggregateQualityFixture.cs index 5b75147dd..a9bc45f96 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Aggregation/Aggregators/AggregateQualityFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Aggregation/Aggregators/AggregateQualityFixture.cs @@ -3,7 +3,6 @@ using System.Linq; using FluentAssertions; using Moq; using NUnit.Framework; -using NzbDrone.Core.CustomFormats; using NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators; using NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators.Augmenters.Quality; using NzbDrone.Core.Parser; diff --git a/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/DifferentQualitySpecificationFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/DifferentQualitySpecificationFixture.cs new file mode 100644 index 000000000..8e92a67ed --- /dev/null +++ b/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/DifferentQualitySpecificationFixture.cs @@ -0,0 +1,95 @@ +using System.Collections.Generic; +using FizzWare.NBuilder; +using FluentAssertions; +using Moq; +using NUnit.Framework; +using NzbDrone.Core.Download; +using NzbDrone.Core.History; +using NzbDrone.Core.MediaFiles.MovieImport.Specifications; +using NzbDrone.Core.Movies; +using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.Profiles; +using NzbDrone.Core.Qualities; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.MediaFiles.MovieImport.Specifications +{ + [TestFixture] + public class DifferentQualitySpecificationFixture : CoreTest + { + private LocalMovie _localMovie; + private DownloadClientItem _downloadClientItem; + + [SetUp] + public void Setup() + { + var qualityProfile = new Profile + { + Cutoff = Quality.Bluray1080p.Id, + Items = Qualities.QualityFixture.GetDefaultQualities(Quality.DVD, Quality.HDTV720p, Quality.Bluray1080p) + }; + + var fakeMovie = Builder.CreateNew() + .With(c => c.Profile = qualityProfile) + .Build(); + + _localMovie = Builder.CreateNew() + .With(l => l.Quality = new QualityModel(Quality.Bluray1080p)) + .With(l => l.DownloadClientMovieInfo = new ParsedMovieInfo()) + .With(l => l.Movie = fakeMovie) + .Build(); + + _downloadClientItem = Builder.CreateNew() + .Build(); + } + + private void GivenGrabbedMovieHistory(QualityModel quality) + { + var history = Builder.CreateListOfSize(1) + .TheFirst(1) + .With(h => h.Quality = quality) + .With(h => h.EventType = MovieHistoryEventType.Grabbed) + .BuildList(); + + Mocker.GetMock() + .Setup(s => s.FindByDownloadId(It.IsAny())) + .Returns(history); + } + + [Test] + public void should_be_accepted_if_no_download_client_item() + { + Subject.IsSatisfiedBy(_localMovie, null).Accepted.Should().BeTrue(); + } + + [Test] + public void should_be_accepted_if_no_grabbed_movie_history() + { + Mocker.GetMock() + .Setup(s => s.FindByDownloadId(It.IsAny())) + .Returns(new List()); + + _localMovie.Movie = Builder.CreateNew() + .With(e => e.MovieFileId = 0) + .Build(); + + Subject.IsSatisfiedBy(_localMovie, _downloadClientItem).Accepted.Should().BeTrue(); + } + + [Test] + public void should_be_accepted_if_quality_matches() + { + GivenGrabbedMovieHistory(_localMovie.Quality); + + Subject.IsSatisfiedBy(_localMovie, _downloadClientItem).Accepted.Should().BeTrue(); + } + + [Test] + public void should_be_rejected_if_quality_does_not_match() + { + GivenGrabbedMovieHistory(new QualityModel(Quality.SDTV)); + + Subject.IsSatisfiedBy(_localMovie, _downloadClientItem).Accepted.Should().BeFalse(); + } + } +} diff --git a/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/GrabbedReleaseQualityFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/GrabbedReleaseQualityFixture.cs index 592310479..aa8041cd7 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/GrabbedReleaseQualityFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/GrabbedReleaseQualityFixture.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using FizzWare.NBuilder; using FluentAssertions; using Moq; @@ -29,7 +29,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport.Specifications .Build(); } - private void GivenHistory(List history) + private void GivenHistory(List history) { Mocker.GetMock() .Setup(s => s.FindByDownloadId(It.IsAny())) @@ -45,7 +45,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport.Specifications [Test] public void should_be_accepted_if_no_history_for_downloadId() { - GivenHistory(new List()); + GivenHistory(new List()); Subject.IsSatisfiedBy(_localMovie, _downloadClientItem).Accepted.Should().BeTrue(); } @@ -53,9 +53,9 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport.Specifications [Test] public void should_be_accepted_if_no_grabbed_history_for_downloadId() { - var history = Builder.CreateListOfSize(1) + var history = Builder.CreateListOfSize(1) .All() - .With(h => h.EventType = HistoryEventType.Unknown) + .With(h => h.EventType = MovieHistoryEventType.Unknown) .BuildList(); GivenHistory(history); @@ -66,9 +66,9 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport.Specifications [Test] public void should_be_accepted_if_grabbed_history_quality_is_unknown() { - var history = Builder.CreateListOfSize(1) + var history = Builder.CreateListOfSize(1) .All() - .With(h => h.EventType = HistoryEventType.Grabbed) + .With(h => h.EventType = MovieHistoryEventType.Grabbed) .With(h => h.Quality = new QualityModel(Quality.Unknown)) .BuildList(); @@ -80,9 +80,9 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport.Specifications [Test] public void should_be_accepted_if_grabbed_history_quality_matches() { - var history = Builder.CreateListOfSize(1) + var history = Builder.CreateListOfSize(1) .All() - .With(h => h.EventType = HistoryEventType.Grabbed) + .With(h => h.EventType = MovieHistoryEventType.Grabbed) .With(h => h.Quality = _localMovie.Quality) .BuildList(); @@ -94,9 +94,9 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport.Specifications [Test] public void should_be_rejected_if_grabbed_history_quality_does_not_match() { - var history = Builder.CreateListOfSize(1) + var history = Builder.CreateListOfSize(1) .All() - .With(h => h.EventType = HistoryEventType.Grabbed) + .With(h => h.EventType = MovieHistoryEventType.Grabbed) .With(h => h.Quality = new QualityModel(Quality.HDTV720p)) .BuildList(); diff --git a/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/SameFileSpecificationFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/SameFileSpecificationFixture.cs deleted file mode 100644 index 961fa3956..000000000 --- a/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/SameFileSpecificationFixture.cs +++ /dev/null @@ -1,76 +0,0 @@ -using FizzWare.NBuilder; -using FluentAssertions; -using NUnit.Framework; -using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.MediaFiles.MovieImport.Specifications; -using NzbDrone.Core.Movies; -using NzbDrone.Core.Parser.Model; -using NzbDrone.Core.Test.Framework; - -namespace NzbDrone.Core.Test.MediaFiles.MovieImport.Specifications -{ - [TestFixture] - public class SameFileSpecificationFixture : CoreTest - { - private LocalMovie _localMovie; - - [SetUp] - public void Setup() - { - _localMovie = Builder.CreateNew() - .With(l => l.Size = 150.Megabytes()) - .Build(); - } - - [Test] - public void should_be_accepted_if_no_existing_file() - { - _localMovie.Movie = Builder.CreateNew() - .With(e => e.MovieFileId = 0) - .Build(); - - Subject.IsSatisfiedBy(_localMovie, null).Accepted.Should().BeTrue(); - } - - [Test] - public void should_be_accepted_if_file_size_is_different() - { - _localMovie.Movie = Builder.CreateNew() - .With(e => e.MovieFileId = 1) - .With(e => e.MovieFile = - new MovieFile - { - Size = _localMovie.Size + 100.Megabytes() - }) - .Build(); - - Subject.IsSatisfiedBy(_localMovie, null).Accepted.Should().BeTrue(); - } - - [Test] - public void should_be_reject_if_file_size_is_the_same() - { - _localMovie.Movie = Builder.CreateNew() - .With(e => e.MovieFileId = 1) - .With(e => e.MovieFile = - new MovieFile - { - Size = _localMovie.Size - }) - .Build(); - - Subject.IsSatisfiedBy(_localMovie, null).Accepted.Should().BeFalse(); - } - - [Test] - public void should_be_accepted_if_file_cannot_be_fetched() - { - _localMovie.Movie = Builder.CreateNew() - .With(e => e.MovieFileId = 1) - .With(e => e.MovieFile = null) - .Build(); - - Subject.IsSatisfiedBy(_localMovie, null).Accepted.Should().BeTrue(); - } - } -} diff --git a/src/NzbDrone.Core.Test/ParserTests/ParsingServiceTests/AugmentersTests/AugmentWithHistoryFixture.cs b/src/NzbDrone.Core.Test/ParserTests/ParsingServiceTests/AugmentersTests/AugmentWithHistoryFixture.cs index 41027c486..75b92c7b8 100644 --- a/src/NzbDrone.Core.Test/ParserTests/ParsingServiceTests/AugmentersTests/AugmentWithHistoryFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/ParsingServiceTests/AugmentersTests/AugmentWithHistoryFixture.cs @@ -54,7 +54,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests }); } - private History.History HistoryWithData(params string[] data) + private MovieHistory HistoryWithData(params string[] data) { var dict = new Dictionary(StringComparer.InvariantCultureIgnoreCase); for (var i = 0; i < data.Length; i += 2) @@ -62,10 +62,10 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests dict.Add(data[i], data[i + 1]); } - return new History.History + return new MovieHistory { Data = dict, - EventType = HistoryEventType.Grabbed + EventType = MovieHistoryEventType.Grabbed }; } diff --git a/src/NzbDrone.Core.Test/Profiles/ProfileRepositoryFixture.cs b/src/NzbDrone.Core.Test/Profiles/ProfileRepositoryFixture.cs index dc18839f5..e8737c404 100644 --- a/src/NzbDrone.Core.Test/Profiles/ProfileRepositoryFixture.cs +++ b/src/NzbDrone.Core.Test/Profiles/ProfileRepositoryFixture.cs @@ -1,6 +1,5 @@ using FluentAssertions; using NUnit.Framework; -using NzbDrone.Core.CustomFormats; using NzbDrone.Core.Profiles; using NzbDrone.Core.Qualities; using NzbDrone.Core.Test.CustomFormats; diff --git a/src/NzbDrone.Core.Test/Qualities/QualityFinderFixture.cs b/src/NzbDrone.Core.Test/Qualities/QualityFinderFixture.cs index 749d0d870..c190809ca 100644 --- a/src/NzbDrone.Core.Test/Qualities/QualityFinderFixture.cs +++ b/src/NzbDrone.Core.Test/Qualities/QualityFinderFixture.cs @@ -1,6 +1,5 @@ using FluentAssertions; using NUnit.Framework; -using NzbDrone.Core.CustomFormats; using NzbDrone.Core.Qualities; namespace NzbDrone.Core.Test.Qualities diff --git a/src/NzbDrone.Core.Test/QueueTests/QueueServiceFixture.cs b/src/NzbDrone.Core.Test/QueueTests/QueueServiceFixture.cs index 39ef9140b..3b2892178 100644 --- a/src/NzbDrone.Core.Test/QueueTests/QueueServiceFixture.cs +++ b/src/NzbDrone.Core.Test/QueueTests/QueueServiceFixture.cs @@ -4,6 +4,7 @@ using System.Linq; using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; +using NzbDrone.Core.Download; using NzbDrone.Core.Download.TrackedDownloads; using NzbDrone.Core.Movies; using NzbDrone.Core.Parser.Model; @@ -20,8 +21,11 @@ namespace NzbDrone.Core.Test.QueueTests [SetUp] public void SetUp() { + var downloadClientInfo = Builder.CreateNew().Build(); + var downloadItem = Builder.CreateNew() .With(v => v.RemainingTime = TimeSpan.FromSeconds(10)) + .With(v => v.DownloadClientInfo = downloadClientInfo) .Build(); var series = Builder.CreateNew() diff --git a/src/NzbDrone.Core/Analytics/AnalyticsService.cs b/src/NzbDrone.Core/Analytics/AnalyticsService.cs index 9e962c0a0..2727431be 100644 --- a/src/NzbDrone.Core/Analytics/AnalyticsService.cs +++ b/src/NzbDrone.Core/Analytics/AnalyticsService.cs @@ -30,7 +30,7 @@ namespace NzbDrone.Core.Analytics { get { - var lastRecord = _historyService.Paged(new PagingSpec() { Page = 0, PageSize = 1, SortKey = "date", SortDirection = SortDirection.Descending }); + var lastRecord = _historyService.Paged(new PagingSpec() { Page = 0, PageSize = 1, SortKey = "date", SortDirection = SortDirection.Descending }); var monthAgo = DateTime.UtcNow.AddMonths(-1); return lastRecord.Records.Any(v => v.Date > monthAgo); diff --git a/src/NzbDrone.Core/CustomFormats/CustomFormatCalculationService.cs b/src/NzbDrone.Core/CustomFormats/CustomFormatCalculationService.cs index 437e073a1..2a3eb48a9 100644 --- a/src/NzbDrone.Core/CustomFormats/CustomFormatCalculationService.cs +++ b/src/NzbDrone.Core/CustomFormats/CustomFormatCalculationService.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using NzbDrone.Common.Extensions; using NzbDrone.Core.Blacklisting; +using NzbDrone.Core.History; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Movies; using NzbDrone.Core.Parser; @@ -15,7 +16,7 @@ namespace NzbDrone.Core.CustomFormats List ParseCustomFormat(ParsedMovieInfo movieInfo); List ParseCustomFormat(MovieFile movieFile); List ParseCustomFormat(Blacklist blacklist); - List ParseCustomFormat(History.History history); + List ParseCustomFormat(MovieHistory history); } public class CustomFormatCalculationService : ICustomFormatCalculationService @@ -113,7 +114,7 @@ namespace NzbDrone.Core.CustomFormats return ParseCustomFormat(info); } - public List ParseCustomFormat(History.History history) + public List ParseCustomFormat(MovieHistory history) { var movie = _movieService.GetMovie(history.MovieId); var parsed = _parsingService.ParseMovieInfo(history.SourceTitle, null); diff --git a/src/NzbDrone.Core/Datastore/Migration/172_add_download_history.cs b/src/NzbDrone.Core/Datastore/Migration/172_add_download_history.cs new file mode 100644 index 000000000..def537015 --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/172_add_download_history.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Data; +using FluentMigrator; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.Datastore.Migration.Framework; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(172)] + public class add_download_history : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Create.TableForModel("DownloadHistory") + .WithColumn("EventType").AsInt32().NotNullable() + .WithColumn("MovieId").AsInt32().NotNullable() + .WithColumn("DownloadId").AsString().NotNullable() + .WithColumn("SourceTitle").AsString().NotNullable() + .WithColumn("Date").AsDateTime().NotNullable() + .WithColumn("Protocol").AsInt32().Nullable() + .WithColumn("IndexerId").AsInt32().Nullable() + .WithColumn("DownloadClientId").AsInt32().Nullable() + .WithColumn("Release").AsString().Nullable() + .WithColumn("Data").AsString().Nullable(); + + Create.Index().OnTable("DownloadHistory").OnColumn("EventType"); + Create.Index().OnTable("DownloadHistory").OnColumn("MovieId"); + Create.Index().OnTable("DownloadHistory").OnColumn("DownloadId"); + + Execute.WithConnection(InitialImportedDownloadHistory); + } + + private static readonly Dictionary EventTypeMap = new Dictionary() + { + { 1, 1 }, // MovieHistoryType.Grabbed -> DownloadHistoryType.Grabbed + { 3, 2 }, // MovieHistoryType.DownloadFolderImported -> DownloadHistoryType.DownloadImported + { 4, 3 }, // MovieHistoryType.DownloadFailed -> DownloadHistoryType.DownloadFailed + { 9, 4 } // MovieHistoryType.DownloadIgnored -> DownloadHistoryType.DownloadIgnored + }; + + private void InitialImportedDownloadHistory(IDbConnection conn, IDbTransaction tran) + { + using (var cmd = conn.CreateCommand()) + { + cmd.Transaction = tran; + cmd.CommandText = "SELECT MovieId, DownloadId, EventType, SourceTitle, Date, Data FROM History WHERE DownloadId IS NOT NULL AND EventType IN (1, 3, 4, 9) GROUP BY EventType, DownloadId"; + + using (var reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + var movieId = reader.GetInt32(0); + var downloadId = reader.GetString(1); + var eventType = reader.GetInt32(2); + var sourceTitle = reader.GetString(3); + var date = reader.GetDateTime(4); + var rawData = reader.GetString(5); + var data = Json.Deserialize>(rawData); + + var downloadHistoryEventType = EventTypeMap[eventType]; + var protocol = data.ContainsKey("protocol") ? Convert.ToInt32(data["protocol"]) : (int?)null; + var downloadHistoryData = new Dictionary(); + + if (data.ContainsKey("indexer")) + { + downloadHistoryData.Add("indexer", data["indexer"]); + } + + if (data.ContainsKey("downloadClient")) + { + downloadHistoryData.Add("downloadClient", data["downloadClient"]); + } + + using (var updateCmd = conn.CreateCommand()) + { + updateCmd.Transaction = tran; + updateCmd.CommandText = @"INSERT INTO DownloadHistory (EventType, MovieId, DownloadId, SourceTitle, Date, Protocol, Data) VALUES (?, ?, ?, ?, ?, ?, ?)"; + updateCmd.AddParameter(downloadHistoryEventType); + updateCmd.AddParameter(movieId); + updateCmd.AddParameter(downloadId); + updateCmd.AddParameter(sourceTitle); + updateCmd.AddParameter(date); + updateCmd.AddParameter(protocol); + updateCmd.AddParameter(downloadHistoryData.ToJson()); + + updateCmd.ExecuteNonQuery(); + } + } + } + } + } + } +} diff --git a/src/NzbDrone.Core/Datastore/TableMapping.cs b/src/NzbDrone.Core/Datastore/TableMapping.cs index 55895c72e..1db725ee7 100644 --- a/src/NzbDrone.Core/Datastore/TableMapping.cs +++ b/src/NzbDrone.Core/Datastore/TableMapping.cs @@ -10,11 +10,13 @@ using NzbDrone.Core.CustomFilters; using NzbDrone.Core.CustomFormats; using NzbDrone.Core.Datastore.Converters; using NzbDrone.Core.Download; +using NzbDrone.Core.Download.History; using NzbDrone.Core.Download.Pending; using NzbDrone.Core.Extras.Metadata; using NzbDrone.Core.Extras.Metadata.Files; using NzbDrone.Core.Extras.Others; using NzbDrone.Core.Extras.Subtitles; +using NzbDrone.Core.History; using NzbDrone.Core.Indexers; using NzbDrone.Core.Instrumentation; using NzbDrone.Core.Jobs; @@ -93,7 +95,7 @@ namespace NzbDrone.Core.Datastore .Ignore(d => d.Protocol) .Ignore(d => d.Tags); - Mapper.Entity("History").RegisterModel(); + Mapper.Entity("History").RegisterModel(); Mapper.Entity("MovieFiles").RegisterModel() .Ignore(f => f.Path); @@ -137,6 +139,8 @@ namespace NzbDrone.Core.Datastore Mapper.Entity("DownloadClientStatus").RegisterModel(); Mapper.Entity("CustomFilters").RegisterModel(); + + Mapper.Entity("DownloadHistory").RegisterModel(); } private static void RegisterMappers() diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/AlreadyImportedSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/AlreadyImportedSpecification.cs index 5492ea2f4..2773254ac 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/AlreadyImportedSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/AlreadyImportedSpecification.cs @@ -49,7 +49,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications } var historyForEpisode = _historyService.GetByMovieId(movie.Id, null); - var lastGrabbed = historyForEpisode.FirstOrDefault(h => h.EventType == HistoryEventType.Grabbed); + var lastGrabbed = historyForEpisode.FirstOrDefault(h => h.EventType == MovieHistoryEventType.Grabbed); if (lastGrabbed == null) { @@ -57,7 +57,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications } var imported = historyForEpisode.FirstOrDefault(h => - h.EventType == HistoryEventType.DownloadFolderImported && + h.EventType == MovieHistoryEventType.DownloadFolderImported && h.DownloadId == lastGrabbed.DownloadId); if (imported == null) diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs index 921404978..2fc65c0e9 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs @@ -47,7 +47,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync _logger.Debug("Checking current status of movie [{0}] in history", subject.Movie.Id); var mostRecent = _historyService.MostRecentForMovie(subject.Movie.Id); - if (mostRecent != null && mostRecent.EventType == HistoryEventType.Grabbed) + if (mostRecent != null && mostRecent.EventType == MovieHistoryEventType.Grabbed) { var customFormats = _formatService.ParseCustomFormat(mostRecent); diff --git a/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs b/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs index 1214f85d3..da5f54b6b 100644 --- a/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs +++ b/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs @@ -88,7 +88,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole { yield return new DownloadClientItem { - DownloadClient = Definition.Name, + DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this), DownloadId = Definition.Name + "_" + item.DownloadId, Category = "radarr", Title = item.Title, diff --git a/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackhole.cs b/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackhole.cs index a81600227..94f9ae5e8 100644 --- a/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackhole.cs +++ b/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackhole.cs @@ -60,7 +60,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole { yield return new DownloadClientItem { - DownloadClient = Definition.Name, + DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this), DownloadId = Definition.Name + "_" + item.DownloadId, Category = "Radarr", Title = item.Title, diff --git a/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs b/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs index a1f97e5c8..687b94f08 100644 --- a/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs +++ b/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs @@ -135,7 +135,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge item.Title = torrent.Name; item.Category = Settings.MovieCategory; - item.DownloadClient = Definition.Name; + item.DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this); var outputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, new OsPath(torrent.DownloadPath)); item.OutputPath = outputPath + torrent.Name; diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs index 3613fedf9..abdaa75a1 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs @@ -87,7 +87,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation var item = new DownloadClientItem() { Category = Settings.TvCategory, - DownloadClient = Definition.Name, + DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this), DownloadId = CreateDownloadId(torrent.Id, serialNumber), Title = torrent.Title, TotalSize = torrent.Size, diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs index 1ea58ba87..4032d8bf3 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs @@ -97,7 +97,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation var item = new DownloadClientItem() { Category = Settings.TvCategory, - DownloadClient = Definition.Name, + DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this), DownloadId = CreateDownloadId(nzb.Id, serialNumber), Title = nzb.Title, TotalSize = nzb.Size, diff --git a/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs b/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs index 1488c8988..dcc14c222 100644 --- a/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs +++ b/src/NzbDrone.Core/Download/Clients/Hadouken/Hadouken.cs @@ -68,7 +68,7 @@ namespace NzbDrone.Core.Download.Clients.Hadouken var item = new DownloadClientItem { - DownloadClient = Definition.Name, + DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this), DownloadId = torrent.InfoHash.ToUpper(), OutputPath = outputPath + torrent.Name, RemainingSize = torrent.TotalSize - torrent.DownloadedBytes, diff --git a/src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortex.cs b/src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortex.cs index 6841a460e..29c0c9bb5 100644 --- a/src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortex.cs +++ b/src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortex.cs @@ -68,7 +68,7 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex { var queueItem = new DownloadClientItem(); - queueItem.DownloadClient = Definition.Name; + queueItem.DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this); queueItem.DownloadId = vortexQueueItem.AddUUID ?? vortexQueueItem.Id.ToString(); queueItem.Category = vortexQueueItem.GroupName; queueItem.Title = vortexQueueItem.UiTitle; diff --git a/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs b/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs index 3c3a04734..1884a57e4 100644 --- a/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs +++ b/src/NzbDrone.Core/Download/Clients/Nzbget/Nzbget.cs @@ -75,7 +75,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget queueItem.Title = item.NzbName; queueItem.TotalSize = totalSize; queueItem.Category = item.Category; - queueItem.DownloadClient = Definition.Name; + queueItem.DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this); queueItem.CanMoveFiles = true; queueItem.CanBeRemoved = true; @@ -122,7 +122,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget var historyItem = new DownloadClientItem(); var itemDir = item.FinalDir.IsNullOrWhiteSpace() ? item.DestDir : item.FinalDir; - historyItem.DownloadClient = Definition.Name; + historyItem.DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this); historyItem.DownloadId = droneParameter == null ? item.Id.ToString() : droneParameter.Value.ToString(); historyItem.Title = item.Name; historyItem.TotalSize = MakeInt64(item.FileSizeHi, item.FileSizeLo); diff --git a/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs b/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs index c84a40b3d..1455c3bb7 100644 --- a/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs +++ b/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs @@ -73,7 +73,7 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic var historyItem = new DownloadClientItem { - DownloadClient = Definition.Name, + DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this), DownloadId = GetDownloadClientId(file), Title = title, diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs index 65c7e05b7..62c531926 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs @@ -135,7 +135,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent Category = torrent.Category.IsNotNullOrWhiteSpace() ? torrent.Category : torrent.Label, Title = torrent.Name, TotalSize = torrent.Size, - DownloadClient = Definition.Name, + DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this), RemainingSize = (long)(torrent.Size * (1.0 - torrent.Progress)), RemainingTime = GetRemainingTime(torrent), SeedRatio = torrent.Ratio, diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs index 9592b80af..d719d495e 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs @@ -64,7 +64,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd } var queueItem = new DownloadClientItem(); - queueItem.DownloadClient = Definition.Name; + queueItem.DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this); queueItem.DownloadId = sabQueueItem.Id; queueItem.Category = sabQueueItem.Category; queueItem.Title = sabQueueItem.Title; @@ -119,7 +119,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd var historyItem = new DownloadClientItem { - DownloadClient = Definition.Name, + DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this), DownloadId = sabHistoryItem.Id, Category = sabHistoryItem.Category, Title = sabHistoryItem.Title, diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs index bd4e9aa98..eeffe3dd0 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs @@ -72,7 +72,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission item.Category = Settings.MovieCategory; item.Title = torrent.Name; - item.DownloadClient = Definition.Name; + item.DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this); item.OutputPath = GetOutputPath(outputPath, torrent); item.TotalSize = torrent.TotalSize; diff --git a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs index f6c393e94..a1091cacc 100644 --- a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrent.cs @@ -122,7 +122,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent } var item = new DownloadClientItem(); - item.DownloadClient = Definition.Name; + item.DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this); item.Title = torrent.Name; item.DownloadId = torrent.Hash; item.OutputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, new OsPath(torrent.Path)); diff --git a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs index e3ed91759..f8afa5578 100644 --- a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs @@ -120,7 +120,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent item.Title = torrent.Name; item.TotalSize = torrent.Size; item.Category = torrent.Label; - item.DownloadClient = Definition.Name; + item.DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this); item.RemainingSize = torrent.Remaining; item.SeedRatio = torrent.Ratio; diff --git a/src/NzbDrone.Core/Download/CompletedDownloadService.cs b/src/NzbDrone.Core/Download/CompletedDownloadService.cs index ec16784e7..9e15fb81b 100644 --- a/src/NzbDrone.Core/Download/CompletedDownloadService.cs +++ b/src/NzbDrone.Core/Download/CompletedDownloadService.cs @@ -1,9 +1,7 @@ using System.IO; using System.Linq; -using NLog; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Extensions; -using NzbDrone.Core.Configuration; using NzbDrone.Core.Download.TrackedDownloads; using NzbDrone.Core.History; using NzbDrone.Core.MediaFiles; @@ -108,7 +106,7 @@ namespace NzbDrone.Core.Download var allMoviesImported = importResults.Where(c => c.Result == ImportResultType.Imported) .Select(c => c.ImportDecision.LocalMovie.Movie) - .Count() >= 1; + .Any(); if (allMoviesImported) { @@ -117,7 +115,7 @@ namespace NzbDrone.Core.Download return; } - // Double check if all episodes were imported by checking the history if at least one + // Double check if all movies were imported by checking the history if at least one // file was imported. This will allow the decision engine to reject already imported // episode files and still mark the download complete when all files are imported. if (importResults.Any(c => c.Result == ImportResultType.Imported)) @@ -126,9 +124,9 @@ namespace NzbDrone.Core.Download .OrderByDescending(h => h.Date) .ToList(); - var allEpisodesImportedInHistory = _trackedDownloadAlreadyImported.IsImported(trackedDownload, historyItems); + var allMoviesImportedInHistory = _trackedDownloadAlreadyImported.IsImported(trackedDownload, historyItems); - if (allEpisodesImportedInHistory) + if (allMoviesImportedInHistory) { trackedDownload.State = TrackedDownloadState.Imported; _eventAggregator.PublishEvent(new DownloadCompletedEvent(trackedDownload)); diff --git a/src/NzbDrone.Core/Download/DownloadClientItem.cs b/src/NzbDrone.Core/Download/DownloadClientItem.cs index 3b5922c6a..91e19e3c3 100644 --- a/src/NzbDrone.Core/Download/DownloadClientItem.cs +++ b/src/NzbDrone.Core/Download/DownloadClientItem.cs @@ -1,13 +1,15 @@ -using System; +using System; using System.Diagnostics; using NzbDrone.Common.Disk; +using NzbDrone.Core.Indexers; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Download { - [DebuggerDisplay("{DownloadClient}:{Title}")] + [DebuggerDisplay("{DownloadClientName}:{Title}")] public class DownloadClientItem { - public string DownloadClient { get; set; } + public DownloadClientItemClientInfo DownloadClientInfo { get; set; } public string DownloadId { get; set; } public string Category { get; set; } public string Title { get; set; } @@ -16,16 +18,32 @@ namespace NzbDrone.Core.Download public long RemainingSize { get; set; } public TimeSpan? RemainingTime { get; set; } public double? SeedRatio { get; set; } - public OsPath OutputPath { get; set; } public string Message { get; set; } - public DownloadItemStatus Status { get; set; } public bool IsEncrypted { get; set; } - public bool CanMoveFiles { get; set; } public bool CanBeRemoved { get; set; } - public bool Removed { get; set; } } + + public class DownloadClientItemClientInfo + { + public DownloadProtocol Protocol { get; set; } + public string Type { get; set; } + public int Id { get; set; } + public string Name { get; set; } + + public static DownloadClientItemClientInfo FromDownloadClient(DownloadClientBase downloadClient) + where TSettings : IProviderConfig, new() + { + return new DownloadClientItemClientInfo + { + Protocol = downloadClient.Protocol, + Type = downloadClient.Name, + Id = downloadClient.Definition.Id, + Name = downloadClient.Definition.Name + }; + } + } } diff --git a/src/NzbDrone.Core/Download/DownloadEventHub.cs b/src/NzbDrone.Core/Download/DownloadEventHub.cs index fa7b6aabf..b63826ee8 100644 --- a/src/NzbDrone.Core/Download/DownloadEventHub.cs +++ b/src/NzbDrone.Core/Download/DownloadEventHub.cs @@ -1,4 +1,4 @@ -using System; +using System; using NLog; using NzbDrone.Common.Messaging; using NzbDrone.Core.Configuration; @@ -65,7 +65,7 @@ namespace NzbDrone.Core.Download var downloadClient = _downloadClientProvider.Get(trackedDownload.DownloadClient); try { - _logger.Debug("[{0}] Removing download from {1} history", trackedDownload.DownloadItem.Title, trackedDownload.DownloadItem.DownloadClient); + _logger.Debug("[{0}] Removing download from {1} history", trackedDownload.DownloadItem.Title, trackedDownload.DownloadItem.DownloadClientInfo.Name); downloadClient.RemoveItem(trackedDownload.DownloadItem.DownloadId, true); trackedDownload.DownloadItem.Removed = true; } @@ -84,7 +84,7 @@ namespace NzbDrone.Core.Download var downloadClient = _downloadClientProvider.Get(trackedDownload.DownloadClient); try { - _logger.Debug("[{0}] Marking download as imported from {1}", trackedDownload.DownloadItem.Title, trackedDownload.DownloadItem.DownloadClient); + _logger.Debug("[{0}] Marking download as imported from {1}", trackedDownload.DownloadItem.Title, trackedDownload.DownloadItem.DownloadClientInfo.Name); downloadClient.MarkItemAsImported(trackedDownload.DownloadItem); } catch (NotSupportedException e) diff --git a/src/NzbDrone.Core/Download/DownloadIgnoredEvent.cs b/src/NzbDrone.Core/Download/DownloadIgnoredEvent.cs index 023218336..9df6afbf8 100644 --- a/src/NzbDrone.Core/Download/DownloadIgnoredEvent.cs +++ b/src/NzbDrone.Core/Download/DownloadIgnoredEvent.cs @@ -11,7 +11,7 @@ namespace NzbDrone.Core.Download public List Languages { get; set; } public QualityModel Quality { get; set; } public string SourceTitle { get; set; } - public string DownloadClient { get; set; } + public DownloadClientItemClientInfo DownloadClientInfo { get; set; } public string DownloadId { get; set; } public string Message { get; set; } } diff --git a/src/NzbDrone.Core/Download/DownloadProcessingService.cs b/src/NzbDrone.Core/Download/DownloadProcessingService.cs index fd96a49a0..689fe0c20 100644 --- a/src/NzbDrone.Core/Download/DownloadProcessingService.cs +++ b/src/NzbDrone.Core/Download/DownloadProcessingService.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Linq; using NLog; using NzbDrone.Core.Configuration; @@ -33,18 +32,12 @@ namespace NzbDrone.Core.Download _logger = logger; } - private void RemoveCompletedDownloads(List trackedDownloads) - { - foreach (var trackedDownload in trackedDownloads.Where(c => c.DownloadItem.CanBeRemoved && c.State == TrackedDownloadState.Imported)) - { - _eventAggregator.PublishEvent(new DownloadCompletedEvent(trackedDownload)); - } - } - public void Execute(ProcessMonitoredDownloadsCommand message) { var enableCompletedDownloadHandling = _configService.EnableCompletedDownloadHandling; - var trackedDownloads = _trackedDownloadService.GetTrackedDownloads(); + var trackedDownloads = _trackedDownloadService.GetTrackedDownloads() + .Where(t => t.IsTrackable) + .ToList(); foreach (var trackedDownload in trackedDownloads) { @@ -66,12 +59,6 @@ namespace NzbDrone.Core.Download } } - if (enableCompletedDownloadHandling && _configService.RemoveCompletedDownloads) - { - // Remove tracked downloads that are now complete - RemoveCompletedDownloads(trackedDownloads); - } - _eventAggregator.PublishEvent(new DownloadsProcessedEvent()); } } diff --git a/src/NzbDrone.Core/Download/DownloadService.cs b/src/NzbDrone.Core/Download/DownloadService.cs index cdfc2bc2c..9a28915d2 100644 --- a/src/NzbDrone.Core/Download/DownloadService.cs +++ b/src/NzbDrone.Core/Download/DownloadService.cs @@ -96,6 +96,8 @@ namespace NzbDrone.Core.Download var movieGrabbedEvent = new MovieGrabbedEvent(remoteMovie); movieGrabbedEvent.DownloadClient = downloadClient.Name; + movieGrabbedEvent.DownloadClientId = downloadClient.Definition.Id; + movieGrabbedEvent.DownloadClientName = downloadClient.Definition.Name; if (!string.IsNullOrWhiteSpace(downloadClientId)) { diff --git a/src/NzbDrone.Core/Download/FailedDownloadService.cs b/src/NzbDrone.Core/Download/FailedDownloadService.cs index a1d9cb271..ff5f055e9 100644 --- a/src/NzbDrone.Core/Download/FailedDownloadService.cs +++ b/src/NzbDrone.Core/Download/FailedDownloadService.cs @@ -18,12 +18,15 @@ namespace NzbDrone.Core.Download public class FailedDownloadService : IFailedDownloadService { private readonly IHistoryService _historyService; + private readonly ITrackedDownloadService _trackedDownloadService; private readonly IEventAggregator _eventAggregator; public FailedDownloadService(IHistoryService historyService, + ITrackedDownloadService trackedDownloadService, IEventAggregator eventAggregator) { _historyService = historyService; + _trackedDownloadService = trackedDownloadService; _eventAggregator = eventAggregator; } @@ -34,22 +37,24 @@ namespace NzbDrone.Core.Download var downloadId = history.DownloadId; if (downloadId.IsNullOrWhiteSpace()) { - PublishDownloadFailedEvent(new List { history }, "Manually marked as failed"); + PublishDownloadFailedEvent(new List { history }, "Manually marked as failed"); } else { - var grabbedHistory = _historyService.Find(downloadId, HistoryEventType.Grabbed).ToList(); + var grabbedHistory = _historyService.Find(downloadId, MovieHistoryEventType.Grabbed).ToList(); PublishDownloadFailedEvent(grabbedHistory, "Manually marked as failed"); } } public void MarkAsFailed(string downloadId) { - var history = _historyService.Find(downloadId, HistoryEventType.Grabbed); + var history = _historyService.Find(downloadId, MovieHistoryEventType.Grabbed); if (history.Any()) { - PublishDownloadFailedEvent(history, "Manually marked as failed"); + var trackedDownload = _trackedDownloadService.Find(downloadId); + + PublishDownloadFailedEvent(history, "Manually marked as failed", trackedDownload); } } @@ -65,7 +70,7 @@ namespace NzbDrone.Core.Download trackedDownload.DownloadItem.Status == DownloadItemStatus.Failed) { var grabbedItems = _historyService - .Find(trackedDownload.DownloadItem.DownloadId, HistoryEventType.Grabbed) + .Find(trackedDownload.DownloadItem.DownloadId, MovieHistoryEventType.Grabbed) .ToList(); if (grabbedItems.Empty()) @@ -86,7 +91,7 @@ namespace NzbDrone.Core.Download } var grabbedItems = _historyService - .Find(trackedDownload.DownloadItem.DownloadId, HistoryEventType.Grabbed) + .Find(trackedDownload.DownloadItem.DownloadId, MovieHistoryEventType.Grabbed) .ToList(); if (grabbedItems.Empty()) @@ -109,7 +114,7 @@ namespace NzbDrone.Core.Download PublishDownloadFailedEvent(grabbedItems, failure, trackedDownload); } - private void PublishDownloadFailedEvent(List historyItems, string message, TrackedDownload trackedDownload = null) + private void PublishDownloadFailedEvent(List historyItems, string message, TrackedDownload trackedDownload = null) { var historyItem = historyItems.First(); @@ -118,7 +123,7 @@ namespace NzbDrone.Core.Download MovieId = historyItem.MovieId, Quality = historyItem.Quality, SourceTitle = historyItem.SourceTitle, - DownloadClient = historyItem.Data.GetValueOrDefault(History.History.DOWNLOAD_CLIENT), + DownloadClient = historyItem.Data.GetValueOrDefault(MovieHistory.DOWNLOAD_CLIENT), DownloadId = historyItem.DownloadId, Message = message, Data = historyItem.Data, diff --git a/src/NzbDrone.Core/Download/History/DownloadHistory.cs b/src/NzbDrone.Core/Download/History/DownloadHistory.cs new file mode 100644 index 000000000..434e91f18 --- /dev/null +++ b/src/NzbDrone.Core/Download/History/DownloadHistory.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using NzbDrone.Core.Datastore; +using NzbDrone.Core.Indexers; +using NzbDrone.Core.Parser.Model; + +namespace NzbDrone.Core.Download.History +{ + public class DownloadHistory : ModelBase + { + public DownloadHistoryEventType EventType { get; set; } + public int MovieId { get; set; } + public string DownloadId { get; set; } + public string SourceTitle { get; set; } + public DateTime Date { get; set; } + public DownloadProtocol Protocol { get; set; } + public int IndexerId { get; set; } + public int DownloadClientId { get; set; } + public ReleaseInfo Release { get; set; } + public Dictionary Data { get; set; } + public DownloadHistory() + { + Data = new Dictionary(); + } + } + + public enum DownloadHistoryEventType + { + DownloadGrabbed = 1, + DownloadImported = 2, + DownloadFailed = 3, + DownloadIgnored = 4, + FileImported = 5 + } +} diff --git a/src/NzbDrone.Core/Download/History/DownloadHistoryRepository.cs b/src/NzbDrone.Core/Download/History/DownloadHistoryRepository.cs new file mode 100644 index 000000000..e895bf315 --- /dev/null +++ b/src/NzbDrone.Core/Download/History/DownloadHistoryRepository.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using System.Linq; +using NzbDrone.Core.Datastore; +using NzbDrone.Core.Messaging.Events; + +namespace NzbDrone.Core.Download.History +{ + public interface IDownloadHistoryRepository : IBasicRepository + { + List FindByDownloadId(string downloadId); + void DeleteByMovieId(int movieId); + } + + public class DownloadHistoryRepository : BasicRepository, IDownloadHistoryRepository + { + public DownloadHistoryRepository(IMainDatabase database, IEventAggregator eventAggregator) + : base(database, eventAggregator) + { + } + + public List FindByDownloadId(string downloadId) + { + return Query(x => x.DownloadId == downloadId).OrderByDescending(h => h.Date).ToList(); + } + + public void DeleteByMovieId(int movieId) + { + Delete(r => r.MovieId == movieId); + } + } +} diff --git a/src/NzbDrone.Core/Download/History/DownloadHistoryService.cs b/src/NzbDrone.Core/Download/History/DownloadHistoryService.cs new file mode 100644 index 000000000..1293c6222 --- /dev/null +++ b/src/NzbDrone.Core/Download/History/DownloadHistoryService.cs @@ -0,0 +1,210 @@ +using System; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.History; +using NzbDrone.Core.MediaFiles.Events; +using NzbDrone.Core.Messaging.Events; +using NzbDrone.Core.Movies.Events; + +namespace NzbDrone.Core.Download.History +{ + public interface IDownloadHistoryService + { + bool DownloadAlreadyImported(string downloadId); + DownloadHistory GetLatestDownloadHistoryItem(string downloadId); + } + + public class DownloadHistoryService : IDownloadHistoryService, + IHandle, + IHandle, + IHandle, + IHandle, + IHandle, + IHandle + { + private readonly IDownloadHistoryRepository _repository; + private readonly IHistoryService _historyService; + + public DownloadHistoryService(IDownloadHistoryRepository repository, IHistoryService historyService) + { + _repository = repository; + _historyService = historyService; + } + + public bool DownloadAlreadyImported(string downloadId) + { + var events = _repository.FindByDownloadId(downloadId); + + // Events are ordered by date descending, if a grabbed event comes before an imported event then it was never imported + // or grabbed again after importing and should be reprocessed. + foreach (var e in events) + { + if (e.EventType == DownloadHistoryEventType.DownloadGrabbed) + { + return false; + } + + if (e.EventType == DownloadHistoryEventType.DownloadImported) + { + return true; + } + } + + return false; + } + + public DownloadHistory GetLatestDownloadHistoryItem(string downloadId) + { + var events = _repository.FindByDownloadId(downloadId); + + // Events are ordered by date descending. We'll return the most recent expected event. + foreach (var e in events) + { + if (e.EventType == DownloadHistoryEventType.DownloadGrabbed) + { + return e; + } + + if (e.EventType == DownloadHistoryEventType.DownloadImported) + { + return e; + } + + if (e.EventType == DownloadHistoryEventType.DownloadFailed) + { + return e; + } + } + + return null; + } + + public void Handle(MovieGrabbedEvent message) + { + var history = new DownloadHistory + { + EventType = DownloadHistoryEventType.DownloadGrabbed, + MovieId = message.Movie.Movie.Id, + DownloadId = message.DownloadId, + SourceTitle = message.Movie.Release.Title, + Date = DateTime.UtcNow, + Protocol = message.Movie.Release.DownloadProtocol, + IndexerId = message.Movie.Release.IndexerId, + DownloadClientId = message.DownloadClientId, + Release = message.Movie.Release + }; + + history.Data.Add("Indexer", message.Movie.Release.Indexer); + history.Data.Add("DownloadClient", message.DownloadClient); + history.Data.Add("DownloadClientName", message.DownloadClientName); + + history.Data.Add("CustomFormatScore", message.Movie.CustomFormatScore.ToString()); + _repository.Insert(history); + } + + public void Handle(MovieImportedEvent message) + { + if (!message.NewDownload) + { + return; + } + + var downloadId = message.DownloadId; + + // Try to find the downloadId if the user used manual import (from wanted: missing) or the + // API to import and downloadId wasn't provided. + if (downloadId.IsNullOrWhiteSpace()) + { + downloadId = _historyService.FindDownloadId(message); + } + + if (downloadId.IsNullOrWhiteSpace()) + { + return; + } + + var history = new DownloadHistory + { + EventType = DownloadHistoryEventType.FileImported, + MovieId = message.MovieInfo.Movie.Id, + DownloadId = downloadId, + SourceTitle = message.MovieInfo.Path, + Date = DateTime.UtcNow, + Protocol = message.DownloadClientInfo.Protocol, + DownloadClientId = message.DownloadClientInfo.Id + }; + + history.Data.Add("DownloadClient", message.DownloadClientInfo.Type); + history.Data.Add("DownloadClientName", message.DownloadClientInfo.Name); + + _repository.Insert(history); + } + + public void Handle(DownloadCompletedEvent message) + { + var history = new DownloadHistory + { + EventType = DownloadHistoryEventType.DownloadImported, + MovieId = message.TrackedDownload.RemoteMovie.Movie.Id, + DownloadId = message.TrackedDownload.DownloadItem.DownloadId, + SourceTitle = message.TrackedDownload.DownloadItem.OutputPath.ToString(), + Date = DateTime.UtcNow, + Protocol = message.TrackedDownload.Protocol, + DownloadClientId = message.TrackedDownload.DownloadClient + }; + + history.Data.Add("DownloadClient", message.TrackedDownload.DownloadItem.DownloadClientInfo.Type); + history.Data.Add("DownloadClientName", message.TrackedDownload.DownloadItem.DownloadClientInfo.Name); + + _repository.Insert(history); + } + + public void Handle(DownloadFailedEvent message) + { + // Don't track failed download for an unknown download + if (message.TrackedDownload == null) + { + return; + } + + var history = new DownloadHistory + { + EventType = DownloadHistoryEventType.DownloadFailed, + MovieId = message.MovieId, + DownloadId = message.DownloadId, + SourceTitle = message.SourceTitle, + Date = DateTime.UtcNow, + Protocol = message.TrackedDownload.Protocol, + DownloadClientId = message.TrackedDownload.DownloadClient + }; + + history.Data.Add("DownloadClient", message.TrackedDownload.DownloadItem.DownloadClientInfo.Type); + history.Data.Add("DownloadClientName", message.TrackedDownload.DownloadItem.DownloadClientInfo.Name); + + _repository.Insert(history); + } + + public void Handle(DownloadIgnoredEvent message) + { + var history = new DownloadHistory + { + EventType = DownloadHistoryEventType.DownloadIgnored, + MovieId = message.MovieId, + DownloadId = message.DownloadId, + SourceTitle = message.SourceTitle, + Date = DateTime.UtcNow, + Protocol = message.DownloadClientInfo.Protocol, + DownloadClientId = message.DownloadClientInfo.Id + }; + + history.Data.Add("DownloadClient", message.DownloadClientInfo.Type); + history.Data.Add("DownloadClientName", message.DownloadClientInfo.Name); + + _repository.Insert(history); + } + + public void Handle(MovieDeletedEvent message) + { + _repository.DeleteByMovieId(message.Movie.Id); + } + } +} diff --git a/src/NzbDrone.Core/Download/IDownloadClient.cs b/src/NzbDrone.Core/Download/IDownloadClient.cs index 168e22fe0..31eb310d3 100644 --- a/src/NzbDrone.Core/Download/IDownloadClient.cs +++ b/src/NzbDrone.Core/Download/IDownloadClient.cs @@ -8,7 +8,6 @@ namespace NzbDrone.Core.Download public interface IDownloadClient : IProvider { DownloadProtocol Protocol { get; } - string Download(RemoteMovie remoteMovie); IEnumerable GetItems(); void RemoveItem(string downloadId, bool deleteData); diff --git a/src/NzbDrone.Core/Download/IgnoredDownloadService.cs b/src/NzbDrone.Core/Download/IgnoredDownloadService.cs index efedd0896..29807ea26 100644 --- a/src/NzbDrone.Core/Download/IgnoredDownloadService.cs +++ b/src/NzbDrone.Core/Download/IgnoredDownloadService.cs @@ -37,7 +37,7 @@ namespace NzbDrone.Core.Download Languages = trackedDownload.RemoteMovie.ParsedMovieInfo.Languages, Quality = trackedDownload.RemoteMovie.ParsedMovieInfo.Quality, SourceTitle = trackedDownload.DownloadItem.Title, - DownloadClient = trackedDownload.DownloadItem.DownloadClient, + DownloadClientInfo = trackedDownload.DownloadItem.DownloadClientInfo, DownloadId = trackedDownload.DownloadItem.DownloadId, Message = "Manually ignored" }; diff --git a/src/NzbDrone.Core/Download/MovieGrabbedEvent.cs b/src/NzbDrone.Core/Download/MovieGrabbedEvent.cs index fb064a9c9..f7c8562ea 100644 --- a/src/NzbDrone.Core/Download/MovieGrabbedEvent.cs +++ b/src/NzbDrone.Core/Download/MovieGrabbedEvent.cs @@ -1,4 +1,4 @@ -using NzbDrone.Common.Messaging; +using NzbDrone.Common.Messaging; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.Download @@ -6,7 +6,9 @@ namespace NzbDrone.Core.Download public class MovieGrabbedEvent : IEvent { public RemoteMovie Movie { get; private set; } + public int DownloadClientId { get; set; } public string DownloadClient { get; set; } + public string DownloadClientName { get; set; } public string DownloadId { get; set; } public MovieGrabbedEvent(RemoteMovie movie) diff --git a/src/NzbDrone.Core/Download/RedownloadFailedDownloadService.cs b/src/NzbDrone.Core/Download/RedownloadFailedDownloadService.cs index 9f8565f7c..a36def4b4 100644 --- a/src/NzbDrone.Core/Download/RedownloadFailedDownloadService.cs +++ b/src/NzbDrone.Core/Download/RedownloadFailedDownloadService.cs @@ -5,7 +5,6 @@ using NzbDrone.Core.IndexerSearch; using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; -using NzbDrone.Core.Movies; namespace NzbDrone.Core.Download { diff --git a/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadAlreadyImported.cs b/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadAlreadyImported.cs index be3903a38..55e577b10 100644 --- a/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadAlreadyImported.cs +++ b/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadAlreadyImported.cs @@ -7,12 +7,12 @@ namespace NzbDrone.Core.Download.TrackedDownloads { public interface ITrackedDownloadAlreadyImported { - bool IsImported(TrackedDownload trackedDownload, List historyItems); + bool IsImported(TrackedDownload trackedDownload, List historyItems); } public class TrackedDownloadAlreadyImported : ITrackedDownloadAlreadyImported { - public bool IsImported(TrackedDownload trackedDownload, List historyItems) + public bool IsImported(TrackedDownload trackedDownload, List historyItems) { if (historyItems.Empty()) { @@ -28,9 +28,9 @@ namespace NzbDrone.Core.Download.TrackedDownloads return false; } - var allEpisodesImportedInHistory = lastHistoryItem.EventType == HistoryEventType.DownloadFolderImported; + var allMoviesImportedInHistory = lastHistoryItem.EventType == MovieHistoryEventType.DownloadFolderImported; - return allEpisodesImportedInHistory; + return allMoviesImportedInHistory; } } } diff --git a/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs b/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs index f016531aa..36eeaf4c3 100644 --- a/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs +++ b/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs @@ -6,6 +6,7 @@ using NzbDrone.Common.Cache; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.CustomFormats; +using NzbDrone.Core.Download.History; using NzbDrone.Core.History; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Parser; @@ -27,7 +28,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads private readonly IParsingService _parsingService; private readonly IHistoryService _historyService; private readonly IEventAggregator _eventAggregator; - private readonly ITrackedDownloadAlreadyImported _trackedDownloadAlreadyImported; + private readonly IDownloadHistoryService _downloadHistoryService; private readonly IConfigService _config; private readonly ICustomFormatCalculationService _formatCalculator; private readonly Logger _logger; @@ -39,7 +40,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads IConfigService config, ICustomFormatCalculationService formatCalculator, IEventAggregator eventAggregator, - ITrackedDownloadAlreadyImported trackedDownloadAlreadyImported, + IDownloadHistoryService downloadHistoryService, Logger logger) { _parsingService = parsingService; @@ -48,7 +49,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads _config = config; _formatCalculator = formatCalculator; _eventAggregator = eventAggregator; - _trackedDownloadAlreadyImported = trackedDownloadAlreadyImported; + _downloadHistoryService = downloadHistoryService; _logger = logger; } @@ -107,7 +108,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId) .OrderByDescending(h => h.Date) .ToList(); - var grabbedHistoryItem = historyItems.FirstOrDefault(h => h.EventType == HistoryEventType.Grabbed); + var grabbedHistoryItem = historyItems.FirstOrDefault(h => h.EventType == MovieHistoryEventType.Grabbed); //TODO: Create release info from history and use that here, so we don't loose indexer flags! var parsedMovieInfo = _parsingService.ParseMovieInfo(trackedDownload.DownloadItem.Title, new List { grabbedHistoryItem }); @@ -117,28 +118,19 @@ namespace NzbDrone.Core.Download.TrackedDownloads trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie; } + var downloadHistory = _downloadHistoryService.GetLatestDownloadHistoryItem(downloadItem.DownloadId); + + if (downloadHistory != null) + { + var state = GetStateFromHistory(downloadHistory.EventType); + trackedDownload.State = state; + } + if (historyItems.Any()) { var firstHistoryItem = historyItems.FirstOrDefault(); - var state = GetStateFromHistory(firstHistoryItem.EventType); + var grabbedEvent = historyItems.FirstOrDefault(v => v.EventType == MovieHistoryEventType.Grabbed); - trackedDownload.State = state; - - // TODO: Restore check to confirm all files were imported - // This will treat partially imported downloads as imported (as it was before), which means a partially imported download after a - // restart will get marked as imported without importing the restart of the files. - - //if (state == TrackedDownloadState.Imported) - //{ - // var allImported = _trackedDownloadAlreadyImported.IsImported(trackedDownload, historyItems); - - // trackedDownload.State = allImported ? TrackedDownloadState.Imported : TrackedDownloadState.Downloading; - //} - //else - //{ - // trackedDownload.State = state; - //} - var grabbedEvent = historyItems.FirstOrDefault(v => v.EventType == HistoryEventType.Grabbed); trackedDownload.Indexer = grabbedEvent?.Data["indexer"]; if (parsedMovieInfo == null || @@ -193,6 +185,21 @@ namespace NzbDrone.Core.Download.TrackedDownloads } } + private static TrackedDownloadState GetStateFromHistory(DownloadHistoryEventType eventType) + { + switch (eventType) + { + case DownloadHistoryEventType.DownloadImported: + return TrackedDownloadState.Imported; + case DownloadHistoryEventType.DownloadFailed: + return TrackedDownloadState.Failed; + case DownloadHistoryEventType.DownloadIgnored: + return TrackedDownloadState.Ignored; + default: + return TrackedDownloadState.Downloading; + } + } + private void LogItemChange(TrackedDownload trackedDownload, DownloadClientItem existingItem, DownloadClientItem downloadItem) { if (existingItem == null || @@ -201,7 +208,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads existingItem.CanMoveFiles != downloadItem.CanMoveFiles) { _logger.Debug("Tracking '{0}:{1}': ClientState={2}{3} SonarrStage={4} Episode='{5}' OutputPath={6}.", - downloadItem.DownloadClient, + downloadItem.DownloadClientInfo.Name, downloadItem.Title, downloadItem.Status, downloadItem.CanBeRemoved ? "" : downloadItem.CanMoveFiles ? " (busy)" : " (readonly)", @@ -210,20 +217,5 @@ namespace NzbDrone.Core.Download.TrackedDownloads downloadItem.OutputPath); } } - - private static TrackedDownloadState GetStateFromHistory(HistoryEventType eventType) - { - switch (eventType) - { - case HistoryEventType.DownloadFolderImported: - return TrackedDownloadState.Imported; - case HistoryEventType.DownloadFailed: - return TrackedDownloadState.Failed; - case HistoryEventType.DownloadIgnored: - return TrackedDownloadState.Ignored; - default: - return TrackedDownloadState.Downloading; - } - } } } diff --git a/src/NzbDrone.Core/History/History.cs b/src/NzbDrone.Core/History/History.cs index 5e0856513..3d5c37539 100644 --- a/src/NzbDrone.Core/History/History.cs +++ b/src/NzbDrone.Core/History/History.cs @@ -7,11 +7,11 @@ using NzbDrone.Core.Qualities; namespace NzbDrone.Core.History { - public class History : ModelBase + public class MovieHistory : ModelBase { public const string DOWNLOAD_CLIENT = "downloadClient"; - public History() + public MovieHistory() { Data = new Dictionary(StringComparer.OrdinalIgnoreCase); } @@ -21,14 +21,14 @@ namespace NzbDrone.Core.History public QualityModel Quality { get; set; } public DateTime Date { get; set; } public Movie Movie { get; set; } - public HistoryEventType EventType { get; set; } + public MovieHistoryEventType EventType { get; set; } public Dictionary Data { get; set; } public List Languages { get; set; } public string DownloadId { get; set; } } - public enum HistoryEventType + public enum MovieHistoryEventType { Unknown = 0, Grabbed = 1, diff --git a/src/NzbDrone.Core/History/HistoryRepository.cs b/src/NzbDrone.Core/History/HistoryRepository.cs index d547d4e49..d3c9da069 100644 --- a/src/NzbDrone.Core/History/HistoryRepository.cs +++ b/src/NzbDrone.Core/History/HistoryRepository.cs @@ -10,19 +10,19 @@ using NzbDrone.Core.Qualities; namespace NzbDrone.Core.History { - public interface IHistoryRepository : IBasicRepository + public interface IHistoryRepository : IBasicRepository { List GetBestQualityInHistory(int movieId); - History MostRecentForDownloadId(string downloadId); - List FindByDownloadId(string downloadId); - List FindDownloadHistory(int movieId, QualityModel quality); - List GetByMovieId(int movieId, HistoryEventType? eventType); + MovieHistory MostRecentForDownloadId(string downloadId); + List FindByDownloadId(string downloadId); + List FindDownloadHistory(int movieId, QualityModel quality); + List GetByMovieId(int movieId, MovieHistoryEventType? eventType); void DeleteForMovie(int movieId); - History MostRecentForMovie(int movieId); - List Since(DateTime date, HistoryEventType? eventType); + MovieHistory MostRecentForMovie(int movieId); + List Since(DateTime date, MovieHistoryEventType? eventType); } - public class HistoryRepository : BasicRepository, IHistoryRepository + public class HistoryRepository : BasicRepository, IHistoryRepository { public HistoryRepository(IMainDatabase database, IEventAggregator eventAggregator) : base(database, eventAggregator) @@ -36,28 +36,28 @@ namespace NzbDrone.Core.History return history.Select(h => h.Quality).ToList(); } - public History MostRecentForDownloadId(string downloadId) + public MovieHistory MostRecentForDownloadId(string downloadId) { return FindByDownloadId(downloadId) .OrderByDescending(h => h.Date) .FirstOrDefault(); } - public List FindByDownloadId(string downloadId) + public List FindByDownloadId(string downloadId) { return Query(x => x.DownloadId == downloadId); } - public List FindDownloadHistory(int movieId, QualityModel quality) + public List FindDownloadHistory(int movieId, QualityModel quality) { - var allowed = new[] { HistoryEventType.Grabbed, HistoryEventType.DownloadFailed, HistoryEventType.DownloadFolderImported }; + var allowed = new[] { MovieHistoryEventType.Grabbed, MovieHistoryEventType.DownloadFailed, MovieHistoryEventType.DownloadFolderImported }; return Query(h => h.MovieId == movieId && h.Quality == quality && allowed.Contains(h.EventType)); } - public List GetByMovieId(int movieId, HistoryEventType? eventType) + public List GetByMovieId(int movieId, MovieHistoryEventType? eventType) { var query = Query(x => x.MovieId == movieId); @@ -74,11 +74,11 @@ namespace NzbDrone.Core.History Delete(c => c.MovieId == movieId); } - private IEnumerable SelectJoined(SqlBuilder.Template sql) + private IEnumerable SelectJoined(SqlBuilder.Template sql) { using (var conn = _database.OpenConnection()) { - return conn.Query( + return conn.Query( sql.RawSql, (hist, movie, profile) => { @@ -92,25 +92,25 @@ namespace NzbDrone.Core.History } protected override SqlBuilder PagedBuilder() => new SqlBuilder() - .Join((h, m) => h.MovieId == m.Id) + .Join((h, m) => h.MovieId == m.Id) .Join((m, p) => m.ProfileId == p.Id); - protected override IEnumerable PagedSelector(SqlBuilder.Template sql) => SelectJoined(sql); + protected override IEnumerable PagedSelector(SqlBuilder.Template sql) => SelectJoined(sql); - public History MostRecentForMovie(int movieId) + public MovieHistory MostRecentForMovie(int movieId) { return Query(x => x.MovieId == movieId) .OrderByDescending(h => h.Date) .FirstOrDefault(); } - public List Since(DateTime date, HistoryEventType? eventType) + public List Since(DateTime date, MovieHistoryEventType? eventType) { - var builder = Builder().Where(x => x.Date >= date); + var builder = Builder().Where(x => x.Date >= date); if (eventType.HasValue) { - builder.Where(h => h.EventType == eventType); + builder.Where(h => h.EventType == eventType); } return Query(builder).OrderBy(h => h.Date).ToList(); diff --git a/src/NzbDrone.Core/History/HistoryService.cs b/src/NzbDrone.Core/History/HistoryService.cs index d417ac9bc..a2b1886d0 100644 --- a/src/NzbDrone.Core/History/HistoryService.cs +++ b/src/NzbDrone.Core/History/HistoryService.cs @@ -19,15 +19,16 @@ namespace NzbDrone.Core.History public interface IHistoryService { QualityModel GetBestQualityInHistory(Profile profile, int movieId); - PagingSpec Paged(PagingSpec pagingSpec); - History MostRecentForMovie(int movieId); - History MostRecentForDownloadId(string downloadId); - History Get(int historyId); - List Find(string downloadId, HistoryEventType eventType); - List FindByDownloadId(string downloadId); - List GetByMovieId(int movieId, HistoryEventType? eventType); - void UpdateMany(List toUpdate); - List Since(DateTime date, HistoryEventType? eventType); + PagingSpec Paged(PagingSpec pagingSpec); + MovieHistory MostRecentForMovie(int movieId); + MovieHistory MostRecentForDownloadId(string downloadId); + MovieHistory Get(int historyId); + List Find(string downloadId, MovieHistoryEventType eventType); + List FindByDownloadId(string downloadId); + List GetByMovieId(int movieId, MovieHistoryEventType? eventType); + void UpdateMany(List toUpdate); + string FindDownloadId(MovieImportedEvent trackedDownload); + List Since(DateTime date, MovieHistoryEventType? eventType); } public class HistoryService : IHistoryService, @@ -48,37 +49,37 @@ namespace NzbDrone.Core.History _logger = logger; } - public PagingSpec Paged(PagingSpec pagingSpec) + public PagingSpec Paged(PagingSpec pagingSpec) { return _historyRepository.GetPaged(pagingSpec); } - public History MostRecentForMovie(int movieId) + public MovieHistory MostRecentForMovie(int movieId) { return _historyRepository.MostRecentForMovie(movieId); } - public History MostRecentForDownloadId(string downloadId) + public MovieHistory MostRecentForDownloadId(string downloadId) { return _historyRepository.MostRecentForDownloadId(downloadId); } - public History Get(int historyId) + public MovieHistory Get(int historyId) { return _historyRepository.Get(historyId); } - public List Find(string downloadId, HistoryEventType eventType) + public List Find(string downloadId, MovieHistoryEventType eventType) { return _historyRepository.FindByDownloadId(downloadId).Where(c => c.EventType == eventType).ToList(); } - public List FindByDownloadId(string downloadId) + public List FindByDownloadId(string downloadId) { return _historyRepository.FindByDownloadId(downloadId); } - public List GetByMovieId(int movieId, HistoryEventType? eventType) + public List GetByMovieId(int movieId, MovieHistoryEventType? eventType) { return _historyRepository.GetByMovieId(movieId, eventType); } @@ -91,16 +92,16 @@ namespace NzbDrone.Core.History .FirstOrDefault(); } - public void UpdateMany(List toUpdate) + public void UpdateMany(List toUpdate) { _historyRepository.UpdateMany(toUpdate); } public void Handle(MovieGrabbedEvent message) { - var history = new History + var history = new MovieHistory { - EventType = HistoryEventType.Grabbed, + EventType = MovieHistoryEventType.Grabbed, Date = DateTime.UtcNow, Quality = message.Movie.ParsedMovieInfo.Quality, Languages = message.Movie.ParsedMovieInfo.Languages, @@ -117,6 +118,7 @@ namespace NzbDrone.Core.History history.Data.Add("AgeMinutes", message.Movie.Release.AgeMinutes.ToString()); history.Data.Add("PublishedDate", message.Movie.Release.PublishDate.ToString("s") + "Z"); history.Data.Add("DownloadClient", message.DownloadClient); + history.Data.Add("DownloadClientName", message.DownloadClientName); history.Data.Add("Size", message.Movie.Release.Size.ToString()); history.Data.Add("DownloadUrl", message.Movie.Release.DownloadUrl); history.Data.Add("Guid", message.Movie.Release.Guid); @@ -156,9 +158,9 @@ namespace NzbDrone.Core.History } var movie = message.MovieInfo.Movie; - var history = new History + var history = new MovieHistory { - EventType = HistoryEventType.DownloadFolderImported, + EventType = MovieHistoryEventType.DownloadFolderImported, Date = DateTime.UtcNow, Quality = message.MovieInfo.Quality, Languages = message.MovieInfo.Languages, @@ -171,7 +173,8 @@ namespace NzbDrone.Core.History //history.Data.Add("FileId", message.ImportedEpisode.Id.ToString()); history.Data.Add("DroppedPath", message.MovieInfo.Path); history.Data.Add("ImportedPath", Path.Combine(movie.Path, message.ImportedMovie.RelativePath)); - history.Data.Add("DownloadClient", message.DownloadClient); + history.Data.Add("DownloadClient", message.DownloadClientInfo?.Type); + history.Data.Add("DownloadClientName", message.DownloadClientInfo?.Name); _historyRepository.Insert(history); } @@ -184,9 +187,9 @@ namespace NzbDrone.Core.History return; } - var history = new History + var history = new MovieHistory { - EventType = HistoryEventType.MovieFileDeleted, + EventType = MovieHistoryEventType.MovieFileDeleted, Date = DateTime.UtcNow, Quality = message.MovieFile.Quality, Languages = message.MovieFile.Languages, @@ -206,9 +209,9 @@ namespace NzbDrone.Core.History var path = Path.Combine(message.Movie.Path, message.MovieFile.RelativePath); var relativePath = message.MovieFile.RelativePath; - var history = new History + var history = new MovieHistory { - EventType = HistoryEventType.MovieFileRenamed, + EventType = MovieHistoryEventType.MovieFileRenamed, Date = DateTime.UtcNow, Quality = message.MovieFile.Quality, Languages = message.MovieFile.Languages, @@ -226,9 +229,9 @@ namespace NzbDrone.Core.History public void Handle(DownloadIgnoredEvent message) { - var history = new History + var history = new MovieHistory { - EventType = HistoryEventType.DownloadIgnored, + EventType = MovieHistoryEventType.DownloadIgnored, Date = DateTime.UtcNow, Quality = message.Quality, SourceTitle = message.SourceTitle, @@ -237,7 +240,8 @@ namespace NzbDrone.Core.History Languages = message.Languages }; - history.Data.Add("DownloadClient", message.DownloadClient); + history.Data.Add("DownloadClient", message.DownloadClientInfo.Type); + history.Data.Add("DownloadClientName", message.DownloadClientInfo.Name); history.Data.Add("Message", message.Message); _historyRepository.Insert(history); @@ -248,19 +252,18 @@ namespace NzbDrone.Core.History _historyRepository.DeleteForMovie(message.Movie.Id); } - private string FindDownloadId(MovieImportedEvent trackedDownload) + public string FindDownloadId(MovieImportedEvent trackedDownload) { _logger.Debug("Trying to find downloadId for {0} from history", trackedDownload.ImportedMovie.Path); var movieId = trackedDownload.MovieInfo.Movie.Id; - var movieHistory = _historyRepository.FindDownloadHistory(movieId, trackedDownload.ImportedMovie.Quality); var processedDownloadId = movieHistory - .Where(c => c.EventType != HistoryEventType.Grabbed && c.DownloadId != null) + .Where(c => c.EventType != MovieHistoryEventType.Grabbed && c.DownloadId != null) .Select(c => c.DownloadId); - var stillDownloading = movieHistory.Where(c => c.EventType == HistoryEventType.Grabbed && !processedDownloadId.Contains(c.DownloadId)).ToList(); + var stillDownloading = movieHistory.Where(c => c.EventType == MovieHistoryEventType.Grabbed && !processedDownloadId.Contains(c.DownloadId)).ToList(); string downloadId = null; @@ -293,9 +296,9 @@ namespace NzbDrone.Core.History public void Handle(DownloadFailedEvent message) { - var history = new History + var history = new MovieHistory { - EventType = HistoryEventType.DownloadFailed, + EventType = MovieHistoryEventType.DownloadFailed, Date = DateTime.UtcNow, Quality = message.Quality, Languages = message.Languages, @@ -305,12 +308,13 @@ namespace NzbDrone.Core.History }; history.Data.Add("DownloadClient", message.DownloadClient); + history.Data.Add("DownloadClientName", message.TrackedDownload?.DownloadItem.DownloadClientInfo.Name); history.Data.Add("Message", message.Message); _historyRepository.Insert(history); } - public List Since(DateTime date, HistoryEventType? eventType) + public List Since(DateTime date, MovieHistoryEventType? eventType) { return _historyRepository.Since(date, eventType); } diff --git a/src/NzbDrone.Core/MediaFiles/Events/MovieImportFailedEvent.cs b/src/NzbDrone.Core/MediaFiles/Events/MovieImportFailedEvent.cs index f4bce4389..bc818dc22 100644 --- a/src/NzbDrone.Core/MediaFiles/Events/MovieImportFailedEvent.cs +++ b/src/NzbDrone.Core/MediaFiles/Events/MovieImportFailedEvent.cs @@ -1,4 +1,4 @@ -using System; +using System; using NzbDrone.Common.Messaging; using NzbDrone.Core.Download; using NzbDrone.Core.Parser.Model; @@ -10,7 +10,7 @@ namespace NzbDrone.Core.MediaFiles.Events public Exception Exception { get; set; } public LocalMovie MovieInfo { get; } public bool NewDownload { get; } - public string DownloadClient { get; } + public DownloadClientItemClientInfo DownloadClientInfo { get; } public string DownloadId { get; } public MovieImportFailedEvent(Exception exception, LocalMovie movieInfo, bool newDownload, DownloadClientItem downloadClientItem) @@ -21,7 +21,7 @@ namespace NzbDrone.Core.MediaFiles.Events if (downloadClientItem != null) { - DownloadClient = downloadClientItem.DownloadClient; + DownloadClientInfo = downloadClientItem.DownloadClientInfo; DownloadId = downloadClientItem.DownloadId; } } diff --git a/src/NzbDrone.Core/MediaFiles/Events/MovieImportedEvent.cs b/src/NzbDrone.Core/MediaFiles/Events/MovieImportedEvent.cs index b16a71f01..35ca83f8e 100644 --- a/src/NzbDrone.Core/MediaFiles/Events/MovieImportedEvent.cs +++ b/src/NzbDrone.Core/MediaFiles/Events/MovieImportedEvent.cs @@ -1,4 +1,5 @@ using NzbDrone.Common.Messaging; +using NzbDrone.Core.Download; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.MediaFiles.Events @@ -8,7 +9,7 @@ namespace NzbDrone.Core.MediaFiles.Events public LocalMovie MovieInfo { get; private set; } public MovieFile ImportedMovie { get; private set; } public bool NewDownload { get; private set; } - public string DownloadClient { get; private set; } + public DownloadClientItemClientInfo DownloadClientInfo { get; set; } public string DownloadId { get; private set; } public MovieImportedEvent(LocalMovie movieInfo, MovieFile importedMovie, bool newDownload) @@ -18,12 +19,12 @@ namespace NzbDrone.Core.MediaFiles.Events NewDownload = newDownload; } - public MovieImportedEvent(LocalMovie movieInfo, MovieFile importedMovie, bool newDownload, string downloadClient, string downloadId) + public MovieImportedEvent(LocalMovie movieInfo, MovieFile importedMovie, bool newDownload, DownloadClientItem downloadClientItem, string downloadId) { MovieInfo = movieInfo; ImportedMovie = importedMovie; NewDownload = newDownload; - DownloadClient = downloadClient; + DownloadClientInfo = downloadClientItem.DownloadClientInfo; DownloadId = downloadId; } } diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/ImportApprovedMovie.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportApprovedMovie.cs index 8fc65665a..cca006ab3 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/ImportApprovedMovie.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportApprovedMovie.cs @@ -93,7 +93,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport { var grabHistory = _historyService.FindByDownloadId(downloadClientItem.DownloadId) .OrderByDescending(h => h.Date) - .FirstOrDefault(h => h.EventType == HistoryEventType.Grabbed); + .FirstOrDefault(h => h.EventType == MovieHistoryEventType.Grabbed); if (Enum.TryParse(grabHistory?.Data.GetValueOrDefault("indexerFlags"), true, out IndexerFlags flags)) { @@ -139,7 +139,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport if (downloadClientItem != null) { - _eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, movieFile, newDownload, downloadClientItem.DownloadClient, downloadClientItem.DownloadId)); + _eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, movieFile, newDownload, downloadClientItem, downloadClientItem.DownloadId)); } else { diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/AlreadyImportedSpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/AlreadyImportedSpecification.cs index d58f61857..778f226e3 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/AlreadyImportedSpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/AlreadyImportedSpecification.cs @@ -39,8 +39,8 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Specifications } var movieImportedHistory = _historyService.GetByMovieId(movie.Id, null); - var lastImported = movieImportedHistory.FirstOrDefault(h => h.EventType == HistoryEventType.DownloadFolderImported); - var lastGrabbed = movieImportedHistory.FirstOrDefault(h => h.EventType == HistoryEventType.Grabbed); + var lastImported = movieImportedHistory.FirstOrDefault(h => h.EventType == MovieHistoryEventType.DownloadFolderImported); + var lastGrabbed = movieImportedHistory.FirstOrDefault(h => h.EventType == MovieHistoryEventType.Grabbed); if (lastImported == null) { diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/DifferentQualitySpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/DifferentQualitySpecification.cs new file mode 100644 index 000000000..28197a75f --- /dev/null +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/DifferentQualitySpecification.cs @@ -0,0 +1,52 @@ +using System.Linq; +using NLog; +using NzbDrone.Core.DecisionEngine; +using NzbDrone.Core.Download; +using NzbDrone.Core.History; +using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.Qualities; + +namespace NzbDrone.Core.MediaFiles.MovieImport.Specifications +{ + public class DifferentQualitySpecification : IImportDecisionEngineSpecification + { + private readonly IHistoryService _historyService; + private readonly Logger _logger; + + public DifferentQualitySpecification(IHistoryService historyService, Logger logger) + { + _historyService = historyService; + _logger = logger; + } + + public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) + { + if (downloadClientItem == null) + { + _logger.Debug("No download client item, skipping"); + return Decision.Accept(); + } + + var grabbedMovieHistory = _historyService.FindByDownloadId(downloadClientItem.DownloadId) + .OrderByDescending(h => h.Date) + .FirstOrDefault(h => h.EventType == MovieHistoryEventType.Grabbed); + + if (grabbedMovieHistory == null) + { + _logger.Debug("No grabbed history for this download item, skipping"); + return Decision.Accept(); + } + + var qualityComparer = new QualityModelComparer(localMovie.Movie.Profile); + var qualityCompare = qualityComparer.Compare(localMovie.Quality, grabbedMovieHistory.Quality); + + if (qualityCompare != 0) + { + _logger.Debug("Quality of file ({0}) does not match quality of grabbed history ({1})", localMovie.Quality, grabbedMovieHistory.Quality); + return Decision.Reject("Not an upgrade for existing movie file(s)"); + } + + return Decision.Accept(); + } + } +} diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/GrabbedReleaseQualitySpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/GrabbedReleaseQualitySpecification.cs index ca88939b3..b1829f708 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/GrabbedReleaseQualitySpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/GrabbedReleaseQualitySpecification.cs @@ -34,7 +34,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Specifications } var grabbedHistory = _historyService.FindByDownloadId(downloadClientItem.DownloadId) - .Where(h => h.EventType == HistoryEventType.Grabbed) + .Where(h => h.EventType == MovieHistoryEventType.Grabbed) .ToList(); if (grabbedHistory.Empty()) diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/SameFileSpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/SameFileSpecification.cs deleted file mode 100644 index 7fc8f7793..000000000 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/SameFileSpecification.cs +++ /dev/null @@ -1,44 +0,0 @@ -using NLog; -using NzbDrone.Core.DecisionEngine; -using NzbDrone.Core.Download; -using NzbDrone.Core.Parser.Model; - -namespace NzbDrone.Core.MediaFiles.MovieImport.Specifications -{ - public class SameFileSpecification : IImportDecisionEngineSpecification - { - private readonly Logger _logger; - - public SameFileSpecification(Logger logger) - { - _logger = logger; - } - - public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) - { - var movieFile = localMovie.Movie.MovieFile; - - if (localMovie.Movie.MovieFileId == 0) - { - _logger.Debug("No existing movie file, skipping"); - return Decision.Accept(); - } - - if (movieFile == null) - { - var movie = localMovie.Movie; - _logger.Trace("Unable to get movie file details from the DB. MovieId: {0} MovieFileId: {1}", movie.Id, movie.MovieFileId); - - return Decision.Accept(); - } - - if (movieFile.Size == localMovie.Size) - { - _logger.Debug("'{0}' Has the same filesize as existing file", localMovie.Path); - return Decision.Reject("Has the same filesize as existing file"); - } - - return Decision.Accept(); - } - } -} diff --git a/src/NzbDrone.Core/Parser/Augmenters/AugmentWithHistory.cs b/src/NzbDrone.Core/Parser/Augmenters/AugmentWithHistory.cs index daacb6d65..9ad19e56a 100644 --- a/src/NzbDrone.Core/Parser/Augmenters/AugmentWithHistory.cs +++ b/src/NzbDrone.Core/Parser/Augmenters/AugmentWithHistory.cs @@ -23,13 +23,13 @@ namespace NzbDrone.Core.Parser.Augmenters { get { - return typeof(History.History); + return typeof(MovieHistory); } } public ParsedMovieInfo AugmentMovieInfo(ParsedMovieInfo movieInfo, object helper) { - if (helper is History.History history && history.EventType == HistoryEventType.Grabbed) + if (helper is MovieHistory history && history.EventType == MovieHistoryEventType.Grabbed) { //First we create a release info from history data. var releaseInfo = new ReleaseInfo(); diff --git a/src/NzbDrone.Core/Queue/QueueService.cs b/src/NzbDrone.Core/Queue/QueueService.cs index 53b8acd0e..9c2718e5c 100644 --- a/src/NzbDrone.Core/Queue/QueueService.cs +++ b/src/NzbDrone.Core/Queue/QueueService.cs @@ -73,7 +73,7 @@ namespace NzbDrone.Core.Queue DownloadId = trackedDownload.DownloadItem.DownloadId, Protocol = trackedDownload.Protocol, Movie = movie, - DownloadClient = trackedDownload.DownloadItem.DownloadClient, + DownloadClient = trackedDownload.DownloadItem.DownloadClientInfo.Name, Indexer = trackedDownload.Indexer, OutputPath = trackedDownload.DownloadItem.OutputPath.ToString() }; diff --git a/src/Radarr.Api.V3/CustomFormats/CustomFormatModule.cs b/src/Radarr.Api.V3/CustomFormats/CustomFormatModule.cs index 922167557..2adde05a4 100644 --- a/src/Radarr.Api.V3/CustomFormats/CustomFormatModule.cs +++ b/src/Radarr.Api.V3/CustomFormats/CustomFormatModule.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using FluentValidation; diff --git a/src/Radarr.Api.V3/History/HistoryModule.cs b/src/Radarr.Api.V3/History/HistoryModule.cs index 6f7ecd084..599db3170 100644 --- a/src/Radarr.Api.V3/History/HistoryModule.cs +++ b/src/Radarr.Api.V3/History/HistoryModule.cs @@ -41,7 +41,7 @@ namespace Radarr.Api.V3.History Post("/failed", x => MarkAsFailed()); } - protected HistoryResource MapToResource(NzbDrone.Core.History.History model, bool includeMovie) + protected HistoryResource MapToResource(MovieHistory model, bool includeMovie) { if (model.Movie == null) { @@ -65,7 +65,7 @@ namespace Radarr.Api.V3.History private PagingResource GetHistory(PagingResource pagingResource) { - var pagingSpec = pagingResource.MapToPagingSpec("date", SortDirection.Descending); + var pagingSpec = pagingResource.MapToPagingSpec("date", SortDirection.Descending); var includeMovie = Request.GetBooleanQueryParameter("includeMovie"); var eventTypeFilter = pagingResource.Filters.FirstOrDefault(f => f.Key == "eventType"); @@ -73,7 +73,7 @@ namespace Radarr.Api.V3.History if (eventTypeFilter != null) { - var filterValue = (HistoryEventType)Convert.ToInt32(eventTypeFilter.Value); + var filterValue = (MovieHistoryEventType)Convert.ToInt32(eventTypeFilter.Value); pagingSpec.FilterExpressions.Add(v => v.EventType == filterValue); } @@ -97,12 +97,12 @@ namespace Radarr.Api.V3.History } DateTime date = DateTime.Parse(queryDate.Value); - HistoryEventType? eventType = null; + MovieHistoryEventType? eventType = null; var includeMovie = Request.GetBooleanQueryParameter("includeMovie"); if (queryEventType.HasValue) { - eventType = (HistoryEventType)Convert.ToInt32(queryEventType.Value); + eventType = (MovieHistoryEventType)Convert.ToInt32(queryEventType.Value); } return _historyService.Since(date, eventType).Select(h => MapToResource(h, includeMovie)).ToList(); @@ -119,12 +119,12 @@ namespace Radarr.Api.V3.History } int movieId = Convert.ToInt32(queryMovieId.Value); - HistoryEventType? eventType = null; + MovieHistoryEventType? eventType = null; var includeMovie = Request.GetBooleanQueryParameter("includeMovie"); if (queryEventType.HasValue) { - eventType = (HistoryEventType)Convert.ToInt32(queryEventType.Value); + eventType = (MovieHistoryEventType)Convert.ToInt32(queryEventType.Value); } return _historyService.GetByMovieId(movieId, eventType).Select(h => MapToResource(h, includeMovie)).ToList(); diff --git a/src/Radarr.Api.V3/History/HistoryResource.cs b/src/Radarr.Api.V3/History/HistoryResource.cs index 50b499e1a..50faa1b91 100644 --- a/src/Radarr.Api.V3/History/HistoryResource.cs +++ b/src/Radarr.Api.V3/History/HistoryResource.cs @@ -21,7 +21,7 @@ namespace Radarr.Api.V3.History public DateTime Date { get; set; } public string DownloadId { get; set; } - public HistoryEventType EventType { get; set; } + public MovieHistoryEventType EventType { get; set; } public Dictionary Data { get; set; } @@ -30,7 +30,7 @@ namespace Radarr.Api.V3.History public static class HistoryResourceMapper { - public static HistoryResource ToResource(this NzbDrone.Core.History.History model, ICustomFormatCalculationService formatCalculator) + public static HistoryResource ToResource(this MovieHistory model, ICustomFormatCalculationService formatCalculator) { if (model == null) { diff --git a/src/Radarr.Api.V3/Movies/MovieLookupModule.cs b/src/Radarr.Api.V3/Movies/MovieLookupModule.cs index b135c6834..6dca82736 100644 --- a/src/Radarr.Api.V3/Movies/MovieLookupModule.cs +++ b/src/Radarr.Api.V3/Movies/MovieLookupModule.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using Nancy; diff --git a/src/Radarr.Api.V3/Profiles/Quality/QualityProfileResource.cs b/src/Radarr.Api.V3/Profiles/Quality/QualityProfileResource.cs index 651b54a8f..c8a0ff899 100644 --- a/src/Radarr.Api.V3/Profiles/Quality/QualityProfileResource.cs +++ b/src/Radarr.Api.V3/Profiles/Quality/QualityProfileResource.cs @@ -3,7 +3,6 @@ using System.Linq; using NzbDrone.Core.CustomFormats; using NzbDrone.Core.Languages; using NzbDrone.Core.Profiles; -using Radarr.Api.V3.CustomFormats; using Radarr.Http.REST; namespace Radarr.Api.V3.Profiles.Quality diff --git a/src/Radarr.Api.V3/Queue/QueueActionModule.cs b/src/Radarr.Api.V3/Queue/QueueActionModule.cs index 05cdb142f..de6c411ed 100644 --- a/src/Radarr.Api.V3/Queue/QueueActionModule.cs +++ b/src/Radarr.Api.V3/Queue/QueueActionModule.cs @@ -149,12 +149,9 @@ namespace Radarr.Api.V3.Queue _failedDownloadService.MarkAsFailed(trackedDownload.DownloadItem.DownloadId); } - if (!removeFromClient && !blacklist) + if (!removeFromClient && !blacklist && !_ignoredDownloadService.IgnoreDownload(trackedDownload)) { - if (!_ignoredDownloadService.IgnoreDownload(trackedDownload)) - { - return null; - } + return null; } return trackedDownload;