New: Added support to override Copy vs Move import logic for DownloadedEpisodesScan API and Manual Import UI.
This commit is contained in:
parent
db899a9bb8
commit
9fbe06ad68
|
@ -67,7 +67,7 @@ namespace NzbDrone.Core.Test.Download
|
||||||
{
|
{
|
||||||
Series = new Series(),
|
Series = new Series(),
|
||||||
Episodes = new List<Episode> { new Episode { Id = 1 } }
|
Episodes = new List<Episode> { new Episode { Id = 1 } }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,11 +77,11 @@ namespace NzbDrone.Core.Test.Download
|
||||||
.Setup(s => s.MostRecentForDownloadId(_trackedDownload.DownloadItem.DownloadId))
|
.Setup(s => s.MostRecentForDownloadId(_trackedDownload.DownloadItem.DownloadId))
|
||||||
.Returns((History.History)null);
|
.Returns((History.History)null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenSuccessfulImport()
|
private void GivenSuccessfulImport()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||||
.Returns(new List<ImportResult>
|
.Returns(new List<ImportResult>
|
||||||
{
|
{
|
||||||
new ImportResult(new ImportDecision(new LocalEpisode() { Path = @"C:\TestPath\Droned.S01E01.mkv" }))
|
new ImportResult(new ImportDecision(new LocalEpisode() { Path = @"C:\TestPath\Droned.S01E01.mkv" }))
|
||||||
|
@ -145,7 +145,7 @@ namespace NzbDrone.Core.Test.Download
|
||||||
GivenNoGrabbedHistory();
|
GivenNoGrabbedHistory();
|
||||||
GivenSeriesMatch();
|
GivenSeriesMatch();
|
||||||
GivenSuccessfulImport();
|
GivenSuccessfulImport();
|
||||||
|
|
||||||
Subject.Process(_trackedDownload);
|
Subject.Process(_trackedDownload);
|
||||||
|
|
||||||
AssertCompletedDownload();
|
AssertCompletedDownload();
|
||||||
|
@ -179,13 +179,13 @@ namespace NzbDrone.Core.Test.Download
|
||||||
public void should_mark_as_imported_if_all_episodes_were_imported()
|
public void should_mark_as_imported_if_all_episodes_were_imported()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||||
.Returns(new List<ImportResult>
|
.Returns(new List<ImportResult>
|
||||||
{
|
{
|
||||||
new ImportResult(
|
new ImportResult(
|
||||||
new ImportDecision(
|
new ImportDecision(
|
||||||
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"})),
|
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"})),
|
||||||
|
|
||||||
new ImportResult(
|
new ImportResult(
|
||||||
new ImportDecision(
|
new ImportDecision(
|
||||||
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E02.mkv"}))
|
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E02.mkv"}))
|
||||||
|
@ -200,13 +200,13 @@ namespace NzbDrone.Core.Test.Download
|
||||||
public void should_not_mark_as_imported_if_all_files_were_rejected()
|
public void should_not_mark_as_imported_if_all_files_were_rejected()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||||
.Returns(new List<ImportResult>
|
.Returns(new List<ImportResult>
|
||||||
{
|
{
|
||||||
new ImportResult(
|
new ImportResult(
|
||||||
new ImportDecision(
|
new ImportDecision(
|
||||||
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}, new Rejection("Rejected!")), "Test Failure"),
|
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}, new Rejection("Rejected!")), "Test Failure"),
|
||||||
|
|
||||||
new ImportResult(
|
new ImportResult(
|
||||||
new ImportDecision(
|
new ImportDecision(
|
||||||
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E02.mkv"},new Rejection("Rejected!")), "Test Failure")
|
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E02.mkv"},new Rejection("Rejected!")), "Test Failure")
|
||||||
|
@ -224,13 +224,13 @@ namespace NzbDrone.Core.Test.Download
|
||||||
public void should_not_mark_as_imported_if_no_episodes_were_parsed()
|
public void should_not_mark_as_imported_if_no_episodes_were_parsed()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||||
.Returns(new List<ImportResult>
|
.Returns(new List<ImportResult>
|
||||||
{
|
{
|
||||||
new ImportResult(
|
new ImportResult(
|
||||||
new ImportDecision(
|
new ImportDecision(
|
||||||
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}, new Rejection("Rejected!")), "Test Failure"),
|
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}, new Rejection("Rejected!")), "Test Failure"),
|
||||||
|
|
||||||
new ImportResult(
|
new ImportResult(
|
||||||
new ImportDecision(
|
new ImportDecision(
|
||||||
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E02.mkv"},new Rejection("Rejected!")), "Test Failure")
|
new LocalEpisode {Path = @"C:\TestPath\Droned.S01E02.mkv"},new Rejection("Rejected!")), "Test Failure")
|
||||||
|
@ -247,7 +247,7 @@ namespace NzbDrone.Core.Test.Download
|
||||||
public void should_not_mark_as_imported_if_all_files_were_skipped()
|
public void should_not_mark_as_imported_if_all_files_were_skipped()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||||
.Returns(new List<ImportResult>
|
.Returns(new List<ImportResult>
|
||||||
{
|
{
|
||||||
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}),"Test Failure"),
|
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}),"Test Failure"),
|
||||||
|
@ -271,7 +271,7 @@ namespace NzbDrone.Core.Test.Download
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||||
.Returns(new List<ImportResult>
|
.Returns(new List<ImportResult>
|
||||||
{
|
{
|
||||||
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"})),
|
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"})),
|
||||||
|
@ -294,7 +294,7 @@ namespace NzbDrone.Core.Test.Download
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||||
.Returns(new List<ImportResult>
|
.Returns(new List<ImportResult>
|
||||||
{
|
{
|
||||||
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"})),
|
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"})),
|
||||||
|
@ -314,7 +314,7 @@ namespace NzbDrone.Core.Test.Download
|
||||||
GivenABadlyNamedDownload();
|
GivenABadlyNamedDownload();
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||||
.Returns(new List<ImportResult>
|
.Returns(new List<ImportResult>
|
||||||
{
|
{
|
||||||
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}))
|
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}))
|
||||||
|
@ -323,7 +323,7 @@ namespace NzbDrone.Core.Test.Download
|
||||||
Mocker.GetMock<ISeriesService>()
|
Mocker.GetMock<ISeriesService>()
|
||||||
.Setup(v => v.GetSeries(It.IsAny<int>()))
|
.Setup(v => v.GetSeries(It.IsAny<int>()))
|
||||||
.Returns(BuildRemoteEpisode().Series);
|
.Returns(BuildRemoteEpisode().Series);
|
||||||
|
|
||||||
Subject.Process(_trackedDownload);
|
Subject.Process(_trackedDownload);
|
||||||
|
|
||||||
AssertCompletedDownload();
|
AssertCompletedDownload();
|
||||||
|
@ -335,7 +335,7 @@ namespace NzbDrone.Core.Test.Download
|
||||||
GivenABadlyNamedDownload();
|
GivenABadlyNamedDownload();
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||||
.Returns(new List<ImportResult>
|
.Returns(new List<ImportResult>
|
||||||
{
|
{
|
||||||
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}))
|
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}))
|
||||||
|
@ -370,7 +370,7 @@ namespace NzbDrone.Core.Test.Download
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||||
.Returns(new List<ImportResult>
|
.Returns(new List<ImportResult>
|
||||||
{
|
{
|
||||||
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}))
|
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}))
|
||||||
|
@ -408,7 +408,7 @@ namespace NzbDrone.Core.Test.Download
|
||||||
private void AssertNoAttemptedImport()
|
private void AssertNoAttemptedImport()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Verify(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()), Times.Never());
|
.Verify(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()), Times.Never());
|
||||||
|
|
||||||
AssertNoCompletedDownload();
|
AssertNoCompletedDownload();
|
||||||
}
|
}
|
||||||
|
@ -424,7 +424,7 @@ namespace NzbDrone.Core.Test.Download
|
||||||
private void AssertCompletedDownload()
|
private void AssertCompletedDownload()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Verify(v => v.ProcessPath(_trackedDownload.DownloadItem.OutputPath.FullPath, _trackedDownload.RemoteEpisode.Series, _trackedDownload.DownloadItem), Times.Once());
|
.Verify(v => v.ProcessPath(_trackedDownload.DownloadItem.OutputPath.FullPath, ImportMode.Auto, _trackedDownload.RemoteEpisode.Series, _trackedDownload.DownloadItem), Times.Once());
|
||||||
|
|
||||||
Mocker.GetMock<IEventAggregator>()
|
Mocker.GetMock<IEventAggregator>()
|
||||||
.Verify(v => v.PublishEvent(It.IsAny<DownloadCompletedEvent>()), Times.Once());
|
.Verify(v => v.PublishEvent(It.IsAny<DownloadCompletedEvent>()), Times.Once());
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
.Returns(new List<ImportResult>());
|
.Returns(new List<ImportResult>());
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<ImportMode>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||||
.Returns(new List<ImportResult>());
|
.Returns(new List<ImportResult>());
|
||||||
|
|
||||||
var downloadItem = Builder<DownloadClientItem>.CreateNew()
|
var downloadItem = Builder<DownloadClientItem>.CreateNew()
|
||||||
|
@ -113,7 +113,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
|
|
||||||
Subject.Execute(new DownloadedEpisodesScanCommand() { Path = _downloadFolder });
|
Subject.Execute(new DownloadedEpisodesScanCommand() { Path = _downloadFolder });
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>().Verify(c => c.ProcessPath(It.IsAny<string>(), null, null), Times.Once());
|
Mocker.GetMock<IDownloadedEpisodesImportService>().Verify(c => c.ProcessPath(It.IsAny<string>(), ImportMode.Auto, null, null), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -123,7 +123,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
|
|
||||||
Subject.Execute(new DownloadedEpisodesScanCommand() { Path = _downloadFile });
|
Subject.Execute(new DownloadedEpisodesScanCommand() { Path = _downloadFile });
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>().Verify(c => c.ProcessPath(It.IsAny<string>(), null, null), Times.Once());
|
Mocker.GetMock<IDownloadedEpisodesImportService>().Verify(c => c.ProcessPath(It.IsAny<string>(), ImportMode.Auto, null, null), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -134,7 +134,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
|
|
||||||
Subject.Execute(new DownloadedEpisodesScanCommand() { Path = _downloadFolder, DownloadClientId = "sab1" });
|
Subject.Execute(new DownloadedEpisodesScanCommand() { Path = _downloadFolder, DownloadClientId = "sab1" });
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>().Verify(c => c.ProcessPath(_downloadFolder, _trackedDownload.RemoteEpisode.Series, _trackedDownload.DownloadItem), Times.Once());
|
Mocker.GetMock<IDownloadedEpisodesImportService>().Verify(c => c.ProcessPath(_downloadFolder, ImportMode.Auto, _trackedDownload.RemoteEpisode.Series, _trackedDownload.DownloadItem), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -144,7 +144,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
|
|
||||||
Subject.Execute(new DownloadedEpisodesScanCommand() { Path = _downloadFolder, DownloadClientId = "sab1" });
|
Subject.Execute(new DownloadedEpisodesScanCommand() { Path = _downloadFolder, DownloadClientId = "sab1" });
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>().Verify(c => c.ProcessPath(_downloadFolder, null, null), Times.Once());
|
Mocker.GetMock<IDownloadedEpisodesImportService>().Verify(c => c.ProcessPath(_downloadFolder, ImportMode.Auto, null, null), Times.Once());
|
||||||
|
|
||||||
ExceptionVerification.ExpectedWarns(1);
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
}
|
}
|
||||||
|
@ -154,9 +154,19 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
{
|
{
|
||||||
Subject.Execute(new DownloadedEpisodesScanCommand() { Path = _downloadFolder });
|
Subject.Execute(new DownloadedEpisodesScanCommand() { Path = _downloadFolder });
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>().Verify(c => c.ProcessPath(It.IsAny<string>(), null, null), Times.Never());
|
Mocker.GetMock<IDownloadedEpisodesImportService>().Verify(c => c.ProcessPath(It.IsAny<string>(), ImportMode.Auto, null, null), Times.Never());
|
||||||
|
|
||||||
ExceptionVerification.ExpectedWarns(1);
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_override_import_mode()
|
||||||
|
{
|
||||||
|
GivenExistingFile(_downloadFile);
|
||||||
|
|
||||||
|
Subject.Execute(new DownloadedEpisodesScanCommand() { Path = _downloadFile, ImportMode = ImportMode.Copy });
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadedEpisodesImportService>().Verify(c => c.ProcessPath(It.IsAny<string>(), ImportMode.Copy, null, null), Times.Once());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
Mocker.GetMock<IImportApprovedEpisodes>()
|
Mocker.GetMock<IImportApprovedEpisodes>()
|
||||||
.Setup(s => s.Import(It.IsAny<List<ImportDecision>>(), true, null))
|
.Setup(s => s.Import(It.IsAny<List<ImportDecision>>(), true, null, ImportMode.Auto))
|
||||||
.Returns(new List<ImportResult>());
|
.Returns(new List<ImportResult>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
Subject.ProcessRootFolder(new DirectoryInfo(_droneFactory));
|
Subject.ProcessRootFolder(new DirectoryInfo(_droneFactory));
|
||||||
|
|
||||||
VerifyNoImport();
|
VerifyNoImport();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
public void should_not_delete_folder_if_no_files_were_imported()
|
public void should_not_delete_folder_if_no_files_were_imported()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IImportApprovedEpisodes>()
|
Mocker.GetMock<IImportApprovedEpisodes>()
|
||||||
.Setup(s => s.Import(It.IsAny<List<ImportDecision>>(), false, null))
|
.Setup(s => s.Import(It.IsAny<List<ImportDecision>>(), false, null, ImportMode.Auto))
|
||||||
.Returns(new List<ImportResult>());
|
.Returns(new List<ImportResult>());
|
||||||
|
|
||||||
Subject.ProcessRootFolder(new DirectoryInfo(_droneFactory));
|
Subject.ProcessRootFolder(new DirectoryInfo(_droneFactory));
|
||||||
|
@ -133,7 +133,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
.Returns(imported);
|
.Returns(imported);
|
||||||
|
|
||||||
Mocker.GetMock<IImportApprovedEpisodes>()
|
Mocker.GetMock<IImportApprovedEpisodes>()
|
||||||
.Setup(s => s.Import(It.IsAny<List<ImportDecision>>(), true, null))
|
.Setup(s => s.Import(It.IsAny<List<ImportDecision>>(), true, null, ImportMode.Auto))
|
||||||
.Returns(imported.Select(i => new ImportResult(i)).ToList());
|
.Returns(imported.Select(i => new ImportResult(i)).ToList());
|
||||||
|
|
||||||
Subject.ProcessRootFolder(new DirectoryInfo(_droneFactory));
|
Subject.ProcessRootFolder(new DirectoryInfo(_droneFactory));
|
||||||
|
@ -159,7 +159,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
.Returns(imported);
|
.Returns(imported);
|
||||||
|
|
||||||
Mocker.GetMock<IImportApprovedEpisodes>()
|
Mocker.GetMock<IImportApprovedEpisodes>()
|
||||||
.Setup(s => s.Import(It.IsAny<List<ImportDecision>>(), true, null))
|
.Setup(s => s.Import(It.IsAny<List<ImportDecision>>(), true, null, ImportMode.Auto))
|
||||||
.Returns(imported.Select(i => new ImportResult(i)).ToList());
|
.Returns(imported.Select(i => new ImportResult(i)).ToList());
|
||||||
|
|
||||||
Mocker.GetMock<IDetectSample>()
|
Mocker.GetMock<IDetectSample>()
|
||||||
|
@ -231,7 +231,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
.Returns(imported);
|
.Returns(imported);
|
||||||
|
|
||||||
Mocker.GetMock<IImportApprovedEpisodes>()
|
Mocker.GetMock<IImportApprovedEpisodes>()
|
||||||
.Setup(s => s.Import(It.IsAny<List<ImportDecision>>(), true, null))
|
.Setup(s => s.Import(It.IsAny<List<ImportDecision>>(), true, null, ImportMode.Auto))
|
||||||
.Returns(imported.Select(i => new ImportResult(i)).ToList());
|
.Returns(imported.Select(i => new ImportResult(i)).ToList());
|
||||||
|
|
||||||
Mocker.GetMock<IDetectSample>()
|
Mocker.GetMock<IDetectSample>()
|
||||||
|
@ -342,7 +342,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
.Returns(imported);
|
.Returns(imported);
|
||||||
|
|
||||||
Mocker.GetMock<IImportApprovedEpisodes>()
|
Mocker.GetMock<IImportApprovedEpisodes>()
|
||||||
.Setup(s => s.Import(It.IsAny<List<ImportDecision>>(), true, null))
|
.Setup(s => s.Import(It.IsAny<List<ImportDecision>>(), true, null, ImportMode.Auto))
|
||||||
.Returns(new List<ImportResult>());
|
.Returns(new List<ImportResult>());
|
||||||
|
|
||||||
Mocker.GetMock<IDetectSample>()
|
Mocker.GetMock<IDetectSample>()
|
||||||
|
@ -365,14 +365,14 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
|
|
||||||
private void VerifyNoImport()
|
private void VerifyNoImport()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IImportApprovedEpisodes>().Verify(c => c.Import(It.IsAny<List<ImportDecision>>(), true, null),
|
Mocker.GetMock<IImportApprovedEpisodes>().Verify(c => c.Import(It.IsAny<List<ImportDecision>>(), true, null, ImportMode.Auto),
|
||||||
Times.Never());
|
Times.Never());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VerifyImport()
|
private void VerifyImport()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IImportApprovedEpisodes>().Verify(c => c.Import(It.IsAny<List<ImportDecision>>(), true, null),
|
Mocker.GetMock<IImportApprovedEpisodes>().Verify(c => c.Import(It.IsAny<List<ImportDecision>>(), true, null, ImportMode.Auto),
|
||||||
Times.Once());
|
Times.Once());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
Mocker.GetMock<IUpgradeMediaFiles>()
|
Mocker.GetMock<IUpgradeMediaFiles>()
|
||||||
.Setup(s => s.UpgradeEpisodeFile(It.IsAny<EpisodeFile>(), It.IsAny<LocalEpisode>(), false))
|
.Setup(s => s.UpgradeEpisodeFile(It.IsAny<EpisodeFile>(), It.IsAny<LocalEpisode>(), It.IsAny<bool>()))
|
||||||
.Returns(new EpisodeFileMoveResult());
|
.Returns(new EpisodeFileMoveResult());
|
||||||
|
|
||||||
_downloadClientItem = Builder<DownloadClientItem>.CreateNew().Build();
|
_downloadClientItem = Builder<DownloadClientItem>.CreateNew().Build();
|
||||||
|
@ -95,7 +95,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
all.AddRange(_approvedDecisions);
|
all.AddRange(_approvedDecisions);
|
||||||
|
|
||||||
var result = Subject.Import(all, false);
|
var result = Subject.Import(all, false);
|
||||||
|
|
||||||
result.Should().HaveCount(all.Count);
|
result.Should().HaveCount(all.Count);
|
||||||
result.Where(i => i.Result == ImportResultType.Imported).Should().HaveCount(_approvedDecisions.Count);
|
result.Where(i => i.Result == ImportResultType.Imported).Should().HaveCount(_approvedDecisions.Count);
|
||||||
}
|
}
|
||||||
|
@ -223,5 +223,23 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
results.Should().ContainSingle(d => d.Result == ImportResultType.Imported);
|
results.Should().ContainSingle(d => d.Result == ImportResultType.Imported);
|
||||||
results.Should().ContainSingle(d => d.Result == ImportResultType.Imported && d.ImportDecision.LocalEpisode.Size == fileDecision.LocalEpisode.Size);
|
results.Should().ContainSingle(d => d.Result == ImportResultType.Imported && d.ImportDecision.LocalEpisode.Size == fileDecision.LocalEpisode.Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_copy_readonly_downloads()
|
||||||
|
{
|
||||||
|
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true, new DownloadClientItem { Title = "30.Rock.S01E01", IsReadOnly = true });
|
||||||
|
|
||||||
|
Mocker.GetMock<IUpgradeMediaFiles>()
|
||||||
|
.Verify(v => v.UpgradeEpisodeFile(It.IsAny<EpisodeFile>(), _approvedDecisions.First().LocalEpisode, true), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_use_override_importmode()
|
||||||
|
{
|
||||||
|
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true, new DownloadClientItem { Title = "30.Rock.S01E01", IsReadOnly = true }, ImportMode.Move);
|
||||||
|
|
||||||
|
Mocker.GetMock<IUpgradeMediaFiles>()
|
||||||
|
.Verify(v => v.UpgradeEpisodeFile(It.IsAny<EpisodeFile>(), _approvedDecisions.First().LocalEpisode, false), Times.Once());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ namespace NzbDrone.Core.Download
|
||||||
private void Import(TrackedDownload trackedDownload)
|
private void Import(TrackedDownload trackedDownload)
|
||||||
{
|
{
|
||||||
var outputPath = trackedDownload.DownloadItem.OutputPath.FullPath;
|
var outputPath = trackedDownload.DownloadItem.OutputPath.FullPath;
|
||||||
var importResults = _downloadedEpisodesImportService.ProcessPath(outputPath, trackedDownload.RemoteEpisode.Series, trackedDownload.DownloadItem);
|
var importResults = _downloadedEpisodesImportService.ProcessPath(outputPath, ImportMode.Auto, trackedDownload.RemoteEpisode.Series, trackedDownload.DownloadItem);
|
||||||
|
|
||||||
if (importResults.Empty())
|
if (importResults.Empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MediaFiles.Commands
|
namespace NzbDrone.Core.MediaFiles.Commands
|
||||||
|
@ -18,5 +19,6 @@ namespace NzbDrone.Core.MediaFiles.Commands
|
||||||
// Properties used by third-party apps, do not modify.
|
// Properties used by third-party apps, do not modify.
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
public string DownloadClientId { get; set; }
|
public string DownloadClientId { get; set; }
|
||||||
|
public ImportMode ImportMode { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,17 +70,17 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
{
|
{
|
||||||
_logger.Debug("External directory scan request for known download {0}. [{1}]", message.DownloadClientId, message.Path);
|
_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);
|
return _downloadedEpisodesImportService.ProcessPath(message.Path, message.ImportMode, trackedDownload.RemoteEpisode.Series, trackedDownload.DownloadItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Warn("External directory scan request for unknown download {0}, attempting normal import. [{1}]", message.DownloadClientId, message.Path);
|
_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, message.ImportMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _downloadedEpisodesImportService.ProcessPath(message.Path);
|
return _downloadedEpisodesImportService.ProcessPath(message.Path, message.ImportMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(DownloadedEpisodesScanCommand message)
|
public void Execute(DownloadedEpisodesScanCommand message)
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
public interface IDownloadedEpisodesImportService
|
public interface IDownloadedEpisodesImportService
|
||||||
{
|
{
|
||||||
List<ImportResult> ProcessRootFolder(DirectoryInfo directoryInfo);
|
List<ImportResult> ProcessRootFolder(DirectoryInfo directoryInfo);
|
||||||
List<ImportResult> ProcessPath(string path, Series series = null, DownloadClientItem downloadClientItem = null);
|
List<ImportResult> ProcessPath(string path, ImportMode importMode = ImportMode.Auto, Series series = null, DownloadClientItem downloadClientItem = null);
|
||||||
bool ShouldDeleteFolder(DirectoryInfo directoryInfo, Series series);
|
bool ShouldDeleteFolder(DirectoryInfo directoryInfo, Series series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,20 +56,20 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
|
|
||||||
foreach (var subFolder in _diskProvider.GetDirectories(directoryInfo.FullName))
|
foreach (var subFolder in _diskProvider.GetDirectories(directoryInfo.FullName))
|
||||||
{
|
{
|
||||||
var folderResults = ProcessFolder(new DirectoryInfo(subFolder));
|
var folderResults = ProcessFolder(new DirectoryInfo(subFolder), ImportMode.Auto, null);
|
||||||
results.AddRange(folderResults);
|
results.AddRange(folderResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var videoFile in _diskScanService.GetVideoFiles(directoryInfo.FullName, false))
|
foreach (var videoFile in _diskScanService.GetVideoFiles(directoryInfo.FullName, false))
|
||||||
{
|
{
|
||||||
var fileResults = ProcessFile(new FileInfo(videoFile));
|
var fileResults = ProcessFile(new FileInfo(videoFile), ImportMode.Auto, null);
|
||||||
results.AddRange(fileResults);
|
results.AddRange(fileResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ImportResult> ProcessPath(string path, Series series = null, DownloadClientItem downloadClientItem = null)
|
public List<ImportResult> ProcessPath(string path, ImportMode importMode = ImportMode.Auto, Series series = null, DownloadClientItem downloadClientItem = null)
|
||||||
{
|
{
|
||||||
if (_diskProvider.FolderExists(path))
|
if (_diskProvider.FolderExists(path))
|
||||||
{
|
{
|
||||||
|
@ -77,10 +77,10 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
|
|
||||||
if (series == null)
|
if (series == null)
|
||||||
{
|
{
|
||||||
return ProcessFolder(directoryInfo, downloadClientItem);
|
return ProcessFolder(directoryInfo, importMode, downloadClientItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProcessFolder(directoryInfo, series, downloadClientItem);
|
return ProcessFolder(directoryInfo, importMode, series, downloadClientItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_diskProvider.FileExists(path))
|
if (_diskProvider.FileExists(path))
|
||||||
|
@ -89,10 +89,10 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
|
|
||||||
if (series == null)
|
if (series == null)
|
||||||
{
|
{
|
||||||
return ProcessFile(fileInfo, downloadClientItem);
|
return ProcessFile(fileInfo, importMode, downloadClientItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProcessFile(fileInfo, series, downloadClientItem);
|
return ProcessFile(fileInfo, importMode, series, downloadClientItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Error("Import failed, path does not exist or is not accessible by Sonarr: {0}", path);
|
_logger.Error("Import failed, path does not exist or is not accessible by Sonarr: {0}", path);
|
||||||
|
@ -133,7 +133,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ImportResult> ProcessFolder(DirectoryInfo directoryInfo, DownloadClientItem downloadClientItem = null)
|
private List<ImportResult> ProcessFolder(DirectoryInfo directoryInfo, ImportMode importMode, DownloadClientItem downloadClientItem)
|
||||||
{
|
{
|
||||||
var cleanedUpName = GetCleanedUpFolderName(directoryInfo.Name);
|
var cleanedUpName = GetCleanedUpFolderName(directoryInfo.Name);
|
||||||
var series = _parsingService.GetSeries(cleanedUpName);
|
var series = _parsingService.GetSeries(cleanedUpName);
|
||||||
|
@ -148,11 +148,10 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProcessFolder(directoryInfo, series, downloadClientItem);
|
return ProcessFolder(directoryInfo, importMode, series, downloadClientItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ImportResult> ProcessFolder(DirectoryInfo directoryInfo, Series series,
|
private List<ImportResult> ProcessFolder(DirectoryInfo directoryInfo, ImportMode importMode, Series series, DownloadClientItem downloadClientItem)
|
||||||
DownloadClientItem downloadClientItem = null)
|
|
||||||
{
|
{
|
||||||
if (_seriesService.SeriesPathExists(directoryInfo.FullName))
|
if (_seriesService.SeriesPathExists(directoryInfo.FullName))
|
||||||
{
|
{
|
||||||
|
@ -185,7 +184,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
var decisions = _importDecisionMaker.GetImportDecisions(videoFiles.ToList(), series, folderInfo, true);
|
var decisions = _importDecisionMaker.GetImportDecisions(videoFiles.ToList(), series, folderInfo, true);
|
||||||
var importResults = _importApprovedEpisodes.Import(decisions, true, downloadClientItem);
|
var importResults = _importApprovedEpisodes.Import(decisions, true, downloadClientItem, importMode);
|
||||||
|
|
||||||
if ((downloadClientItem == null || !downloadClientItem.IsReadOnly) &&
|
if ((downloadClientItem == null || !downloadClientItem.IsReadOnly) &&
|
||||||
importResults.Any(i => i.Result == ImportResultType.Imported) &&
|
importResults.Any(i => i.Result == ImportResultType.Imported) &&
|
||||||
|
@ -198,7 +197,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
return importResults;
|
return importResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ImportResult> ProcessFile(FileInfo fileInfo, DownloadClientItem downloadClientItem = null)
|
private List<ImportResult> ProcessFile(FileInfo fileInfo, ImportMode importMode, DownloadClientItem downloadClientItem)
|
||||||
{
|
{
|
||||||
var series = _parsingService.GetSeries(Path.GetFileNameWithoutExtension(fileInfo.Name));
|
var series = _parsingService.GetSeries(Path.GetFileNameWithoutExtension(fileInfo.Name));
|
||||||
|
|
||||||
|
@ -212,10 +211,10 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProcessFile(fileInfo, series, downloadClientItem);
|
return ProcessFile(fileInfo, importMode, series, downloadClientItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ImportResult> ProcessFile(FileInfo fileInfo, Series series, DownloadClientItem downloadClientItem = null)
|
private List<ImportResult> ProcessFile(FileInfo fileInfo, ImportMode importMode, Series series, DownloadClientItem downloadClientItem)
|
||||||
{
|
{
|
||||||
if (Path.GetFileNameWithoutExtension(fileInfo.Name).StartsWith("._"))
|
if (Path.GetFileNameWithoutExtension(fileInfo.Name).StartsWith("._"))
|
||||||
{
|
{
|
||||||
|
@ -240,7 +239,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
|
|
||||||
var decisions = _importDecisionMaker.GetImportDecisions(new List<string>() { fileInfo.FullName }, series, null, true);
|
var decisions = _importDecisionMaker.GetImportDecisions(new List<string>() { fileInfo.FullName }, series, null, true);
|
||||||
|
|
||||||
return _importApprovedEpisodes.Import(decisions, true, downloadClientItem);
|
return _importApprovedEpisodes.Import(decisions, true, downloadClientItem, importMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetCleanedUpFolderName(string folder)
|
private string GetCleanedUpFolderName(string folder)
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
{
|
{
|
||||||
public interface IImportApprovedEpisodes
|
public interface IImportApprovedEpisodes
|
||||||
{
|
{
|
||||||
List<ImportResult> Import(List<ImportDecision> decisions, bool newDownload, DownloadClientItem downloadClientItem = null);
|
List<ImportResult> Import(List<ImportDecision> decisions, bool newDownload, DownloadClientItem downloadClientItem = null, ImportMode importMode = ImportMode.Auto);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ImportApprovedEpisodes : IImportApprovedEpisodes
|
public class ImportApprovedEpisodes : IImportApprovedEpisodes
|
||||||
|
@ -45,7 +45,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ImportResult> Import(List<ImportDecision> decisions, bool newDownload, DownloadClientItem downloadClientItem = null)
|
public List<ImportResult> Import(List<ImportDecision> decisions, bool newDownload, DownloadClientItem downloadClientItem = null, ImportMode importMode = ImportMode.Auto)
|
||||||
{
|
{
|
||||||
var qualifiedImports = decisions.Where(c => c.Approved)
|
var qualifiedImports = decisions.Where(c => c.Approved)
|
||||||
.GroupBy(c => c.LocalEpisode.Series.Id, (i, s) => s
|
.GroupBy(c => c.LocalEpisode.Series.Id, (i, s) => s
|
||||||
|
@ -85,10 +85,23 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
episodeFile.Episodes = localEpisode.Episodes;
|
episodeFile.Episodes = localEpisode.Episodes;
|
||||||
episodeFile.ReleaseGroup = localEpisode.ParsedEpisodeInfo.ReleaseGroup;
|
episodeFile.ReleaseGroup = localEpisode.ParsedEpisodeInfo.ReleaseGroup;
|
||||||
|
|
||||||
|
bool copyOnly;
|
||||||
|
switch (importMode)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case ImportMode.Auto:
|
||||||
|
copyOnly = downloadClientItem != null && downloadClientItem.IsReadOnly;
|
||||||
|
break;
|
||||||
|
case ImportMode.Move:
|
||||||
|
copyOnly = false;
|
||||||
|
break;
|
||||||
|
case ImportMode.Copy:
|
||||||
|
copyOnly = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (newDownload)
|
if (newDownload)
|
||||||
{
|
{
|
||||||
bool copyOnly = downloadClientItem != null && downloadClientItem.IsReadOnly;
|
|
||||||
|
|
||||||
episodeFile.SceneName = GetSceneName(downloadClientItem, localEpisode);
|
episodeFile.SceneName = GetSceneName(downloadClientItem, localEpisode);
|
||||||
|
|
||||||
var moveResult = _episodeFileUpgrader.UpgradeEpisodeFile(episodeFile, localEpisode, copyOnly);
|
var moveResult = _episodeFileUpgrader.UpgradeEpisodeFile(episodeFile, localEpisode, copyOnly);
|
||||||
|
@ -104,7 +117,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
|
|
||||||
if (newDownload)
|
if (newDownload)
|
||||||
{
|
{
|
||||||
_extraService.ImportExtraFiles(localEpisode, episodeFile, downloadClientItem != null && downloadClientItem.IsReadOnly);
|
_extraService.ImportExtraFiles(localEpisode, episodeFile, copyOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (downloadClientItem != null)
|
if (downloadClientItem != null)
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
|
{
|
||||||
|
public enum ImportMode
|
||||||
|
{
|
||||||
|
Auto = 0,
|
||||||
|
Move = 1,
|
||||||
|
Copy = 2
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,5 +14,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ImportMode ImportMode { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,7 +189,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
|
|
||||||
public void Execute(ManualImportCommand message)
|
public void Execute(ManualImportCommand message)
|
||||||
{
|
{
|
||||||
_logger.ProgressTrace("Manually importing {0} files", message.Files.Count);
|
_logger.ProgressTrace("Manually importing {0} files using mode {1}", message.Files.Count, message.ImportMode);
|
||||||
|
|
||||||
var imported = new List<ImportResult>();
|
var imported = new List<ImportResult>();
|
||||||
var importedTrackedDownload = new List<ManuallyImportedFile>();
|
var importedTrackedDownload = new List<ManuallyImportedFile>();
|
||||||
|
@ -217,20 +217,19 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
Size = 0
|
Size = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
//TODO: Option to copy instead of import
|
|
||||||
//TODO: Cleanup non-tracked downloads
|
//TODO: Cleanup non-tracked downloads
|
||||||
|
|
||||||
var importDecision = new ImportDecision(localEpisode);
|
var importDecision = new ImportDecision(localEpisode);
|
||||||
|
|
||||||
if (file.DownloadId.IsNullOrWhiteSpace())
|
if (file.DownloadId.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
imported.AddRange(_importApprovedEpisodes.Import(new List<ImportDecision> { importDecision }, !existingFile));
|
imported.AddRange(_importApprovedEpisodes.Import(new List<ImportDecision> { importDecision }, !existingFile, null, message.ImportMode));
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var trackedDownload = _trackedDownloadService.Find(file.DownloadId);
|
var trackedDownload = _trackedDownloadService.Find(file.DownloadId);
|
||||||
var importResult = _importApprovedEpisodes.Import(new List<ImportDecision> { importDecision }, true, trackedDownload.DownloadItem).First();
|
var importResult = _importApprovedEpisodes.Import(new List<ImportDecision> { importDecision }, true, trackedDownload.DownloadItem, message.ImportMode).First();
|
||||||
|
|
||||||
imported.Add(importResult);
|
imported.Add(importResult);
|
||||||
|
|
||||||
|
|
|
@ -693,6 +693,7 @@
|
||||||
<Compile Include="MediaFiles\Commands\BackendCommandAttribute.cs" />
|
<Compile Include="MediaFiles\Commands\BackendCommandAttribute.cs" />
|
||||||
<Compile Include="MediaFiles\Commands\CleanUpRecycleBinCommand.cs" />
|
<Compile Include="MediaFiles\Commands\CleanUpRecycleBinCommand.cs" />
|
||||||
<Compile Include="MediaFiles\Commands\DownloadedEpisodesScanCommand.cs" />
|
<Compile Include="MediaFiles\Commands\DownloadedEpisodesScanCommand.cs" />
|
||||||
|
<Compile Include="MediaFiles\EpisodeImport\ImportMode.cs" />
|
||||||
<Compile Include="MediaFiles\Commands\RenameFilesCommand.cs" />
|
<Compile Include="MediaFiles\Commands\RenameFilesCommand.cs" />
|
||||||
<Compile Include="MediaFiles\Commands\RenameSeriesCommand.cs" />
|
<Compile Include="MediaFiles\Commands\RenameSeriesCommand.cs" />
|
||||||
<Compile Include="MediaFiles\Commands\RescanSeriesCommand.cs" />
|
<Compile Include="MediaFiles\Commands\RescanSeriesCommand.cs" />
|
||||||
|
|
|
@ -27,7 +27,8 @@ module.exports = Marionette.Layout.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
ui : {
|
ui : {
|
||||||
importButton : '.x-import'
|
importButton : '.x-import',
|
||||||
|
importMode : '.x-importmode'
|
||||||
},
|
},
|
||||||
|
|
||||||
events : {
|
events : {
|
||||||
|
@ -94,6 +95,7 @@ module.exports = Marionette.Layout.extend({
|
||||||
this.folder = options.folder;
|
this.folder = options.folder;
|
||||||
this.downloadId = options.downloadId;
|
this.downloadId = options.downloadId;
|
||||||
this.title = options.title;
|
this.title = options.title;
|
||||||
|
this.importMode = options.importMode || 'Move';
|
||||||
|
|
||||||
this.templateHelpers = {
|
this.templateHelpers = {
|
||||||
title : this.title || this.folder
|
title : this.title || this.folder
|
||||||
|
@ -105,11 +107,13 @@ module.exports = Marionette.Layout.extend({
|
||||||
if (this.folder || this.downloadId) {
|
if (this.folder || this.downloadId) {
|
||||||
this._showLoading();
|
this._showLoading();
|
||||||
this._loadCollection();
|
this._loadCollection();
|
||||||
|
this.ui.importMode.val(this.importMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
this._showSelectFolder();
|
this._showSelectFolder();
|
||||||
this.ui.importButton.hide();
|
this.ui.importButton.hide();
|
||||||
|
this.ui.importMode.hide();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -196,6 +200,8 @@ module.exports = Marionette.Layout.extend({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var importMode = this.ui.importMode.val();
|
||||||
|
|
||||||
CommandController.Execute('manualImport', {
|
CommandController.Execute('manualImport', {
|
||||||
name : 'manualImport',
|
name : 'manualImport',
|
||||||
files : _.map(selected, function (file) {
|
files : _.map(selected, function (file) {
|
||||||
|
@ -206,7 +212,8 @@ module.exports = Marionette.Layout.extend({
|
||||||
quality : file.get('quality'),
|
quality : file.get('quality'),
|
||||||
downloadId : file.get('downloadId')
|
downloadId : file.get('downloadId')
|
||||||
};
|
};
|
||||||
})
|
}),
|
||||||
|
importMode : importMode
|
||||||
});
|
});
|
||||||
|
|
||||||
vent.trigger(vent.Commands.CloseModalCommand);
|
vent.trigger(vent.Commands.CloseModalCommand);
|
||||||
|
|
|
@ -13,6 +13,12 @@
|
||||||
<div class="x-footer"></div>
|
<div class="x-footer"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
<div class="col-md-2 pull-left">
|
||||||
|
<select class="form-control x-importmode">
|
||||||
|
<option value="Move">Move Files</option>
|
||||||
|
<option value="Copy">Copy Files</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<button class="btn btn-default" data-dismiss="modal">Cancel</button>
|
<button class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||||
<button class="btn btn-success x-import" disabled="disabled">Import</button>
|
<button class="btn btn-success x-import" disabled="disabled">Import</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue