From 2f048f42172056c851f8ab8c21e87689f5df535f Mon Sep 17 00:00:00 2001 From: Taloth Saldono Date: Thu, 22 Jan 2015 01:29:52 +0100 Subject: [PATCH] Fixed: DownloadEpisodesScan api command regressed during a refactoring causing nzbToMedia to fail. --- ...DownloadedEpisodesCommandServiceFixture.cs | 73 ++++++++++++++++++- .../Commands/DownloadedEpisodesScanCommand.cs | 4 + .../DownloadedEpisodesCommandService.cs | 48 +++++++++++- 3 files changed, 122 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core.Test/MediaFiles/DownloadedEpisodesCommandServiceFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/DownloadedEpisodesCommandServiceFixture.cs index 244cdd92e..058ec9686 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/DownloadedEpisodesCommandServiceFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/DownloadedEpisodesCommandServiceFixture.cs @@ -6,10 +6,13 @@ using NUnit.Framework; using NzbDrone.Common.Disk; using NzbDrone.Core.Configuration; using NzbDrone.Core.Download; +using NzbDrone.Core.Download.TrackedDownloads; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles.Commands; using NzbDrone.Core.MediaFiles.EpisodeImport; +using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.Tv; using NzbDrone.Test.Common; namespace NzbDrone.Core.Test.MediaFiles @@ -18,6 +21,9 @@ namespace NzbDrone.Core.Test.MediaFiles public class DownloadedEpisodesCommandServiceFixture : CoreTest { private string _droneFactory = "c:\\drop\\".AsOsAgnostic(); + private string _downloadFolder = "c:\\drop_other\\Show.S01E01\\".AsOsAgnostic(); + + private TrackedDownload _trackedDownload; [SetUp] public void Setup() @@ -31,6 +37,33 @@ namespace NzbDrone.Core.Test.MediaFiles Mocker.GetMock() .Setup(v => v.ProcessRootFolder(It.IsAny())) .Returns(new List()); + + Mocker.GetMock() + .Setup(v => v.ProcessPath(It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(new List()); + + var downloadItem = Builder.CreateNew() + .With(v => v.DownloadId = "sab1") + .With(v => v.Status = DownloadItemStatus.Downloading) + .Build(); + + var remoteEpisode = Builder.CreateNew() + .With(v => v.Series = new Series()) + .Build(); + + _trackedDownload = new TrackedDownload + { + DownloadItem = downloadItem, + RemoteEpisode = remoteEpisode, + State = TrackedDownloadStage.Downloading + }; + } + + private void GivenValidQueueItem() + { + Mocker.GetMock() + .Setup(s => s.Find("sab1")) + .Returns(_trackedDownload); } [Test] @@ -51,6 +84,42 @@ namespace NzbDrone.Core.Test.MediaFiles Mocker.GetMock().Verify(c => c.ProcessRootFolder(It.IsAny()), Times.Never()); ExceptionVerification.ExpectedWarns(1); - } + } + + [Test] + public void should_ignore_downloadclientid_if_path_is_not_specified() + { + Subject.Execute(new DownloadedEpisodesScanCommand() { DownloadClientId = "sab1" }); + + Mocker.GetMock().Verify(c => c.ProcessRootFolder(It.IsAny()), Times.Once()); + } + + [Test] + public void should_process_folder_if_downloadclientid_is_not_specified() + { + Subject.Execute(new DownloadedEpisodesScanCommand() { Path = _downloadFolder }); + + Mocker.GetMock().Verify(c => c.ProcessPath(It.IsAny(), null, null), Times.Once()); + } + + [Test] + public void should_process_folder_with_downloadclientitem_if_available() + { + GivenValidQueueItem(); + + Subject.Execute(new DownloadedEpisodesScanCommand() { Path = _downloadFolder, DownloadClientId = "sab1" }); + + Mocker.GetMock().Verify(c => c.ProcessPath(_downloadFolder, _trackedDownload.RemoteEpisode.Series, _trackedDownload.DownloadItem), Times.Once()); + } + + [Test] + public void should_process_folder_without_downloadclientitem_if_not_available() + { + Subject.Execute(new DownloadedEpisodesScanCommand() { Path = _downloadFolder, DownloadClientId = "sab1" }); + + Mocker.GetMock().Verify(c => c.ProcessPath(_downloadFolder, null, null), Times.Once()); + + ExceptionVerification.ExpectedWarns(1); + } } -} +} \ No newline at end of file diff --git a/src/NzbDrone.Core/MediaFiles/Commands/DownloadedEpisodesScanCommand.cs b/src/NzbDrone.Core/MediaFiles/Commands/DownloadedEpisodesScanCommand.cs index 4d09685e8..b59664629 100644 --- a/src/NzbDrone.Core/MediaFiles/Commands/DownloadedEpisodesScanCommand.cs +++ b/src/NzbDrone.Core/MediaFiles/Commands/DownloadedEpisodesScanCommand.cs @@ -14,5 +14,9 @@ namespace NzbDrone.Core.MediaFiles.Commands } public Boolean SendUpdates { get; set; } + + // Properties used by third-party apps, do not modify. + public String Path { get; set; } + public String DownloadClientId { get; set; } } } \ No newline at end of file diff --git a/src/NzbDrone.Core/MediaFiles/DownloadedEpisodesCommandService.cs b/src/NzbDrone.Core/MediaFiles/DownloadedEpisodesCommandService.cs index 9b33ac9bb..732e76902 100644 --- a/src/NzbDrone.Core/MediaFiles/DownloadedEpisodesCommandService.cs +++ b/src/NzbDrone.Core/MediaFiles/DownloadedEpisodesCommandService.cs @@ -4,7 +4,10 @@ using System.IO; using System.Linq; using NLog; using NzbDrone.Common.Disk; +using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Download; +using NzbDrone.Core.Download.TrackedDownloads; using NzbDrone.Core.MediaFiles.Commands; using NzbDrone.Core.MediaFiles.EpisodeImport; using NzbDrone.Core.Messaging.Commands; @@ -14,16 +17,19 @@ namespace NzbDrone.Core.MediaFiles public class DownloadedEpisodesCommandService : IExecute { private readonly IDownloadedEpisodesImportService _downloadedEpisodesImportService; + private readonly ITrackedDownloadService _trackedDownloadService; private readonly IDiskProvider _diskProvider; private readonly IConfigService _configService; private readonly Logger _logger; public DownloadedEpisodesCommandService(IDownloadedEpisodesImportService downloadedEpisodesImportService, + ITrackedDownloadService trackedDownloadService, IDiskProvider diskProvider, IConfigService configService, Logger logger) { _downloadedEpisodesImportService = downloadedEpisodesImportService; + _trackedDownloadService = trackedDownloadService; _diskProvider = diskProvider; _configService = configService; _logger = logger; @@ -48,9 +54,49 @@ namespace NzbDrone.Core.MediaFiles return _downloadedEpisodesImportService.ProcessRootFolder(new DirectoryInfo(downloadedEpisodesFolder)); } + private List ProcessFolder(DownloadedEpisodesScanCommand message) + { + if (!_diskProvider.FolderExists(message.Path)) + { + _logger.Warn("Folder specified for import scan [{0}] doesn't exist.", message.Path); + return new List(); + } + + if (message.DownloadClientId.IsNotNullOrWhiteSpace()) + { + + var trackedDownload = _trackedDownloadService.Find(message.DownloadClientId); + + if (trackedDownload != null) + { + _logger.Debug("External directory scan request for known download {0}. [{1}]", message.DownloadClientId, message.Path); + + return _downloadedEpisodesImportService.ProcessPath(message.Path, trackedDownload.RemoteEpisode.Series, trackedDownload.DownloadItem); + } + else + { + _logger.Warn("External directory scan request for unknown download {0}, attempting normal import. [{1}]", message.DownloadClientId, message.Path); + + return _downloadedEpisodesImportService.ProcessPath(message.Path); + } + } + + return _downloadedEpisodesImportService.ProcessPath(message.Path); + } + public void Execute(DownloadedEpisodesScanCommand message) { - var importResults = ProcessDroneFactoryFolder(); + List importResults; + + if (message.Path.IsNotNullOrWhiteSpace()) + { + importResults = ProcessFolder(message); + } + else + { + importResults = ProcessDroneFactoryFolder(); + } + if (importResults == null || importResults.All(v => v.Result != ImportResultType.Imported)) { // Atm we don't report it as a command failure, coz that would cause the download to be failed.