Show title mismatches, but don't import them automaticallys
Fixed: Show Series title mismatches in the UI Fixed: Force import from Queue for title mismatches
This commit is contained in:
parent
7f27507ef6
commit
2bbce39faa
|
@ -72,7 +72,7 @@ namespace NzbDrone.Api.Queue
|
||||||
var resource = Request.Body.FromJson<QueueResource>();
|
var resource = Request.Body.FromJson<QueueResource>();
|
||||||
var trackedDownload = GetTrackedDownload(resource.Id);
|
var trackedDownload = GetTrackedDownload(resource.Id);
|
||||||
|
|
||||||
_completedDownloadService.Process(trackedDownload);
|
_completedDownloadService.Process(trackedDownload, true);
|
||||||
|
|
||||||
return resource.AsResponse();
|
return resource.AsResponse();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ using NzbDrone.Core.History;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
@ -65,18 +66,24 @@ 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<DownloadClientItem>()))
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), 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" }))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void GivenSeriesMatch()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IParsingService>()
|
||||||
|
.Setup(s => s.GetSeries(It.IsAny<string>()))
|
||||||
|
.Returns(_trackedDownload.RemoteEpisode.Series);
|
||||||
|
}
|
||||||
|
|
||||||
[TestCase(DownloadItemStatus.Downloading)]
|
[TestCase(DownloadItemStatus.Downloading)]
|
||||||
[TestCase(DownloadItemStatus.Failed)]
|
[TestCase(DownloadItemStatus.Failed)]
|
||||||
[TestCase(DownloadItemStatus.Queued)]
|
[TestCase(DownloadItemStatus.Queued)]
|
||||||
|
@ -107,8 +114,9 @@ namespace NzbDrone.Core.Test.Download
|
||||||
{
|
{
|
||||||
_trackedDownload.DownloadItem.Category = "tv";
|
_trackedDownload.DownloadItem.Category = "tv";
|
||||||
GivenNoGrabbedHistory();
|
GivenNoGrabbedHistory();
|
||||||
|
GivenSeriesMatch();
|
||||||
GivenSuccessfulImport();
|
GivenSuccessfulImport();
|
||||||
|
|
||||||
Subject.Process(_trackedDownload);
|
Subject.Process(_trackedDownload);
|
||||||
|
|
||||||
AssertCompletedDownload();
|
AssertCompletedDownload();
|
||||||
|
@ -142,7 +150,7 @@ 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<DownloadClientItem>()))
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), 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"}, "Rejected!"),"Test Failure"),
|
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}, "Rejected!"),"Test Failure"),
|
||||||
|
@ -161,7 +169,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<DownloadClientItem>()))
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), 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"),
|
||||||
|
@ -177,6 +185,7 @@ namespace NzbDrone.Core.Test.Download
|
||||||
[Test]
|
[Test]
|
||||||
public void should_mark_as_imported_if_all_episodes_were_imported_but_extra_files_were_not()
|
public void should_mark_as_imported_if_all_episodes_were_imported_but_extra_files_were_not()
|
||||||
{
|
{
|
||||||
|
GivenSeriesMatch();
|
||||||
|
|
||||||
_trackedDownload.RemoteEpisode.Episodes = new List<Episode>
|
_trackedDownload.RemoteEpisode.Episodes = new List<Episode>
|
||||||
{
|
{
|
||||||
|
@ -184,14 +193,13 @@ namespace NzbDrone.Core.Test.Download
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<DownloadClientItem>()))
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), 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"})),
|
||||||
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")
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
Subject.Process(_trackedDownload);
|
Subject.Process(_trackedDownload);
|
||||||
|
|
||||||
AssertCompletedDownload();
|
AssertCompletedDownload();
|
||||||
|
@ -208,7 +216,7 @@ namespace NzbDrone.Core.Test.Download
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<DownloadClientItem>()))
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), 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"})),
|
||||||
|
@ -222,11 +230,38 @@ namespace NzbDrone.Core.Test.Download
|
||||||
AssertNoCompletedDownload();
|
AssertNoCompletedDownload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_import_when_there_is_a_title_mismatch()
|
||||||
|
{
|
||||||
|
Subject.Process(_trackedDownload);
|
||||||
|
|
||||||
|
AssertNoCompletedDownload();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_mark_as_import_title_mismatch_if_ignore_warnings_is_true()
|
||||||
|
{
|
||||||
|
_trackedDownload.RemoteEpisode.Episodes = new List<Episode>
|
||||||
|
{
|
||||||
|
new Episode()
|
||||||
|
};
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
|
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||||
|
.Returns(new List<ImportResult>
|
||||||
|
{
|
||||||
|
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}))
|
||||||
|
});
|
||||||
|
|
||||||
|
Subject.Process(_trackedDownload, true);
|
||||||
|
|
||||||
|
AssertCompletedDownload();
|
||||||
|
}
|
||||||
|
|
||||||
private void AssertNoAttemptedImport()
|
private void AssertNoAttemptedImport()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Verify(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<DownloadClientItem>()), Times.Never());
|
.Verify(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()), Times.Never());
|
||||||
|
|
||||||
AssertNoCompletedDownload();
|
AssertNoCompletedDownload();
|
||||||
}
|
}
|
||||||
|
@ -242,7 +277,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.DownloadItem), Times.Once());
|
.Verify(v => v.ProcessPath(_trackedDownload.DownloadItem.OutputPath.FullPath, _trackedDownload.RemoteEpisode.Series, _trackedDownload.DownloadItem), Times.Once());
|
||||||
|
|
||||||
_trackedDownload.State.Should().Be(TrackedDownloadStage.Imported);
|
_trackedDownload.State.Should().Be(TrackedDownloadStage.Imported);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
{
|
{
|
||||||
private string _droneFactory = "c:\\drop\\".AsOsAgnostic();
|
private string _droneFactory = "c:\\drop\\".AsOsAgnostic();
|
||||||
|
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
|
@ -32,11 +31,6 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||||
.Setup(v => v.ProcessRootFolder(It.IsAny<DirectoryInfo>()))
|
.Setup(v => v.ProcessRootFolder(It.IsAny<DirectoryInfo>()))
|
||||||
.Returns(new List<ImportResult>());
|
.Returns(new List<ImportResult>());
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
|
||||||
.Setup(v => v.ProcessFolder(It.IsAny<DirectoryInfo>(), It.IsAny<DownloadClientItem>()))
|
|
||||||
.Returns(new List<ImportResult>());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -48,7 +42,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_skip_import_if_dropfolder_doesnt_exist()
|
public void should_skip_import_if_dronefactory_doesnt_exist()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IDiskProvider>().Setup(c => c.FolderExists(It.IsAny<string>())).Returns(false);
|
Mocker.GetMock<IDiskProvider>().Setup(c => c.FolderExists(It.IsAny<string>())).Returns(false);
|
||||||
|
|
||||||
|
@ -57,7 +51,6 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
Mocker.GetMock<IDownloadedEpisodesImportService>().Verify(c => c.ProcessRootFolder(It.IsAny<DirectoryInfo>()), Times.Never());
|
Mocker.GetMock<IDownloadedEpisodesImportService>().Verify(c => c.ProcessRootFolder(It.IsAny<DirectoryInfo>()), Times.Never());
|
||||||
|
|
||||||
ExceptionVerification.ExpectedWarns(1);
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,9 +199,12 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_importresult_on_unknown_series()
|
public void should_return_importresult_on_unknown_series()
|
||||||
{
|
{
|
||||||
|
Mocker.GetMock<IDiskProvider>().Setup(c => c.FolderExists(It.IsAny<string>()))
|
||||||
|
.Returns(false);
|
||||||
|
|
||||||
var fileName = @"C:\folder\file.mkv".AsOsAgnostic();
|
var fileName = @"C:\folder\file.mkv".AsOsAgnostic();
|
||||||
|
|
||||||
var result = Subject.ProcessFile(new FileInfo(fileName));
|
var result = Subject.ProcessPath(fileName);
|
||||||
|
|
||||||
result.Should().HaveCount(1);
|
result.Should().HaveCount(1);
|
||||||
result.First().ImportDecision.Should().NotBeNull();
|
result.First().ImportDecision.Should().NotBeNull();
|
||||||
|
|
|
@ -9,12 +9,13 @@ using NzbDrone.Core.History;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download
|
namespace NzbDrone.Core.Download
|
||||||
{
|
{
|
||||||
public interface ICompletedDownloadService
|
public interface ICompletedDownloadService
|
||||||
{
|
{
|
||||||
void Process(TrackedDownload trackedDownload);
|
void Process(TrackedDownload trackedDownload, bool ignoreWarnings = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CompletedDownloadService : ICompletedDownloadService
|
public class CompletedDownloadService : ICompletedDownloadService
|
||||||
|
@ -23,46 +24,64 @@ namespace NzbDrone.Core.Download
|
||||||
private readonly IEventAggregator _eventAggregator;
|
private readonly IEventAggregator _eventAggregator;
|
||||||
private readonly IHistoryService _historyService;
|
private readonly IHistoryService _historyService;
|
||||||
private readonly IDownloadedEpisodesImportService _downloadedEpisodesImportService;
|
private readonly IDownloadedEpisodesImportService _downloadedEpisodesImportService;
|
||||||
|
private readonly IParsingService _parsingService;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public CompletedDownloadService(IConfigService configService,
|
public CompletedDownloadService(IConfigService configService,
|
||||||
IEventAggregator eventAggregator,
|
IEventAggregator eventAggregator,
|
||||||
IHistoryService historyService,
|
IHistoryService historyService,
|
||||||
IDownloadedEpisodesImportService downloadedEpisodesImportService)
|
IDownloadedEpisodesImportService downloadedEpisodesImportService,
|
||||||
|
IParsingService parsingService,
|
||||||
|
Logger logger)
|
||||||
{
|
{
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
_eventAggregator = eventAggregator;
|
_eventAggregator = eventAggregator;
|
||||||
_historyService = historyService;
|
_historyService = historyService;
|
||||||
_downloadedEpisodesImportService = downloadedEpisodesImportService;
|
_downloadedEpisodesImportService = downloadedEpisodesImportService;
|
||||||
|
_parsingService = parsingService;
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(TrackedDownload trackedDownload)
|
public void Process(TrackedDownload trackedDownload, bool ignoreWarnings = false)
|
||||||
{
|
{
|
||||||
if (trackedDownload.DownloadItem.Status != DownloadItemStatus.Completed)
|
if (trackedDownload.DownloadItem.Status != DownloadItemStatus.Completed)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var historyItem = _historyService.MostRecentForDownloadId(trackedDownload.DownloadItem.DownloadId);
|
if (!ignoreWarnings)
|
||||||
|
|
||||||
if (historyItem == null && trackedDownload.DownloadItem.Category.IsNullOrWhiteSpace())
|
|
||||||
{
|
{
|
||||||
trackedDownload.Warn("Download wasn't grabbed by Sonarr and not in a category, Skipping.");
|
var historyItem = _historyService.MostRecentForDownloadId(trackedDownload.DownloadItem.DownloadId);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var downloadItemOutputPath = trackedDownload.DownloadItem.OutputPath;
|
if (historyItem == null && trackedDownload.DownloadItem.Category.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
trackedDownload.Warn("Download wasn't grabbed by Sonarr and not in a category, Skipping.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (downloadItemOutputPath.IsEmpty)
|
var downloadItemOutputPath = trackedDownload.DownloadItem.OutputPath;
|
||||||
{
|
|
||||||
trackedDownload.Warn("Download doesn't contain intermediate path, Skipping.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var downloadedEpisodesFolder = new OsPath(_configService.DownloadedEpisodesFolder);
|
if (downloadItemOutputPath.IsEmpty)
|
||||||
if (downloadedEpisodesFolder.Contains(downloadItemOutputPath))
|
{
|
||||||
{
|
trackedDownload.Warn("Download doesn't contain intermediate path, Skipping.");
|
||||||
trackedDownload.Warn("Intermediate Download path inside drone factory, Skipping.");
|
return;
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
var downloadedEpisodesFolder = new OsPath(_configService.DownloadedEpisodesFolder);
|
||||||
|
|
||||||
|
if (downloadedEpisodesFolder.Contains(downloadItemOutputPath))
|
||||||
|
{
|
||||||
|
trackedDownload.Warn("Intermediate Download path inside drone factory, Skipping.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var series = _parsingService.GetSeries(trackedDownload.DownloadItem.Title);
|
||||||
|
|
||||||
|
if (series == null)
|
||||||
|
{
|
||||||
|
trackedDownload.Warn("Series title mismatch, automatic import is not possible.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Import(trackedDownload);
|
Import(trackedDownload);
|
||||||
|
@ -71,7 +90,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.DownloadItem);
|
var importResults = _downloadedEpisodesImportService.ProcessPath(outputPath, trackedDownload.RemoteEpisode.Series, trackedDownload.DownloadItem);
|
||||||
|
|
||||||
if (importResults.Empty())
|
if (importResults.Empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -78,7 +78,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
|
||||||
trackedDownloads.AddRange(newItems);
|
trackedDownloads.AddRange(newItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_configService.RemoveCompletedDownloads)
|
if (_configService.EnableCompletedDownloadHandling && _configService.RemoveCompletedDownloads)
|
||||||
{
|
{
|
||||||
RemoveCompletedDownloads(trackedDownloads);
|
RemoveCompletedDownloads(trackedDownloads);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Cache;
|
using NzbDrone.Common.Cache;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.History;
|
using NzbDrone.Core.History;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
|
@ -59,9 +61,17 @@ namespace NzbDrone.Core.Download.TrackedDownloads
|
||||||
if (parsedEpisodeInfo == null) return null;
|
if (parsedEpisodeInfo == null) return null;
|
||||||
|
|
||||||
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo);
|
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo);
|
||||||
|
|
||||||
if (remoteEpisode.Series == null)
|
if (remoteEpisode.Series == null)
|
||||||
{
|
{
|
||||||
return null;
|
var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId);
|
||||||
|
|
||||||
|
if (historyItems.Empty())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteEpisode = _parsingService.Map(parsedEpisodeInfo, historyItems.First().SeriesId, historyItems.Select(h => h.EpisodeId));
|
||||||
}
|
}
|
||||||
|
|
||||||
trackedDownload.RemoteEpisode = remoteEpisode;
|
trackedDownload.RemoteEpisode = remoteEpisode;
|
||||||
|
@ -73,6 +83,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
|
||||||
}
|
}
|
||||||
|
|
||||||
var historyItem = _historyService.MostRecentForDownloadId(downloadItem.DownloadId);
|
var historyItem = _historyService.MostRecentForDownloadId(downloadItem.DownloadId);
|
||||||
|
|
||||||
if (historyItem != null)
|
if (historyItem != null)
|
||||||
{
|
{
|
||||||
trackedDownload.State = GetStateFromHistory(historyItem.EventType);
|
trackedDownload.State = GetStateFromHistory(historyItem.EventType);
|
||||||
|
|
|
@ -22,6 +22,7 @@ namespace NzbDrone.Core.History
|
||||||
History MostRecentForDownloadId(string downloadId);
|
History MostRecentForDownloadId(string downloadId);
|
||||||
History Get(int historyId);
|
History Get(int historyId);
|
||||||
List<History> Find(string downloadId, HistoryEventType eventType);
|
List<History> Find(string downloadId, HistoryEventType eventType);
|
||||||
|
List<History> FindByDownloadId(string downloadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class HistoryService : IHistoryService,
|
public class HistoryService : IHistoryService,
|
||||||
|
@ -64,6 +65,10 @@ namespace NzbDrone.Core.History
|
||||||
return _historyRepository.FindByDownloadId(downloadId).Where(c => c.EventType == eventType).ToList();
|
return _historyRepository.FindByDownloadId(downloadId).Where(c => c.EventType == eventType).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<History> FindByDownloadId(string downloadId)
|
||||||
|
{
|
||||||
|
return _historyRepository.FindByDownloadId(downloadId);
|
||||||
|
}
|
||||||
|
|
||||||
public QualityModel GetBestQualityInHistory(Profile profile, int episodeId)
|
public QualityModel GetBestQualityInHistory(Profile profile, int episodeId)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,8 +15,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
public interface IDownloadedEpisodesImportService
|
public interface IDownloadedEpisodesImportService
|
||||||
{
|
{
|
||||||
List<ImportResult> ProcessRootFolder(DirectoryInfo directoryInfo);
|
List<ImportResult> ProcessRootFolder(DirectoryInfo directoryInfo);
|
||||||
List<ImportResult> ProcessFolder(DirectoryInfo directoryInfo, DownloadClientItem downloadClientItem = null);
|
List<ImportResult> ProcessPath(string path, Series series = null, DownloadClientItem downloadClientItem = null);
|
||||||
List<ImportResult> ProcessPath(string path, DownloadClientItem downloadClientItem = null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DownloadedEpisodesImportService : IDownloadedEpisodesImportService
|
public class DownloadedEpisodesImportService : IDownloadedEpisodesImportService
|
||||||
|
@ -31,13 +30,13 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public DownloadedEpisodesImportService(IDiskProvider diskProvider,
|
public DownloadedEpisodesImportService(IDiskProvider diskProvider,
|
||||||
IDiskScanService diskScanService,
|
IDiskScanService diskScanService,
|
||||||
ISeriesService seriesService,
|
ISeriesService seriesService,
|
||||||
IParsingService parsingService,
|
IParsingService parsingService,
|
||||||
IMakeImportDecision importDecisionMaker,
|
IMakeImportDecision importDecisionMaker,
|
||||||
IImportApprovedEpisodes importApprovedEpisodes,
|
IImportApprovedEpisodes importApprovedEpisodes,
|
||||||
ISampleService sampleService,
|
ISampleService sampleService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
_diskScanService = diskScanService;
|
_diskScanService = diskScanService;
|
||||||
|
@ -68,7 +67,27 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ImportResult> ProcessFolder(DirectoryInfo directoryInfo, DownloadClientItem downloadClientItem = null)
|
public List<ImportResult> ProcessPath(string path, Series series = null, DownloadClientItem downloadClientItem = null)
|
||||||
|
{
|
||||||
|
if (_diskProvider.FolderExists(path))
|
||||||
|
{
|
||||||
|
if (series == null)
|
||||||
|
{
|
||||||
|
return ProcessFolder(new DirectoryInfo(path), downloadClientItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProcessFolder(new DirectoryInfo(path), series, downloadClientItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (series == null)
|
||||||
|
{
|
||||||
|
return ProcessFile(new FileInfo(path), downloadClientItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProcessFile(new FileInfo(path), series, downloadClientItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ImportResult> ProcessFolder(DirectoryInfo directoryInfo, DownloadClientItem downloadClientItem = null)
|
||||||
{
|
{
|
||||||
var cleanedUpName = GetCleanedUpFolderName(directoryInfo.Name);
|
var cleanedUpName = GetCleanedUpFolderName(directoryInfo.Name);
|
||||||
var series = _parsingService.GetSeries(cleanedUpName);
|
var series = _parsingService.GetSeries(cleanedUpName);
|
||||||
|
@ -87,7 +106,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ImportResult> ProcessFolder(DirectoryInfo directoryInfo, Series series,
|
private List<ImportResult> ProcessFolder(DirectoryInfo directoryInfo, Series series,
|
||||||
DownloadClientItem downloadClientItem = null)
|
DownloadClientItem downloadClientItem = null)
|
||||||
{
|
{
|
||||||
if (_seriesService.SeriesPathExists(directoryInfo.FullName))
|
if (_seriesService.SeriesPathExists(directoryInfo.FullName))
|
||||||
{
|
{
|
||||||
|
@ -128,7 +147,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
return importResults;
|
return importResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ImportResult> ProcessFile(FileInfo fileInfo, DownloadClientItem downloadClientItem = null)
|
private List<ImportResult> ProcessFile(FileInfo fileInfo, DownloadClientItem downloadClientItem = null)
|
||||||
{
|
{
|
||||||
var series = _parsingService.GetSeries(Path.GetFileNameWithoutExtension(fileInfo.Name));
|
var series = _parsingService.GetSeries(Path.GetFileNameWithoutExtension(fileInfo.Name));
|
||||||
|
|
||||||
|
@ -162,16 +181,6 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
return _importApprovedEpisodes.Import(decisions, true, downloadClientItem);
|
return _importApprovedEpisodes.Import(decisions, true, downloadClientItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ImportResult> ProcessPath(string path, DownloadClientItem downloadClientItem = null)
|
|
||||||
{
|
|
||||||
if (_diskProvider.FolderExists(path))
|
|
||||||
{
|
|
||||||
return ProcessFolder(new DirectoryInfo(path), downloadClientItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ProcessFile(new FileInfo(path), downloadClientItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetCleanedUpFolderName(string folder)
|
private string GetCleanedUpFolderName(string folder)
|
||||||
{
|
{
|
||||||
folder = folder.Replace("_UNPACK_", "")
|
folder = folder.Replace("_UNPACK_", "")
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace NzbDrone.Core.Parser
|
||||||
LocalEpisode GetLocalEpisode(string filename, Series series, bool sceneSource);
|
LocalEpisode GetLocalEpisode(string filename, Series series, bool sceneSource);
|
||||||
Series GetSeries(string title);
|
Series GetSeries(string title);
|
||||||
RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, Int32 tvRageId = 0, SearchCriteriaBase searchCriteria = null);
|
RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, Int32 tvRageId = 0, SearchCriteriaBase searchCriteria = null);
|
||||||
|
RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, Int32 seriesId, IEnumerable<Int32> episodeIds);
|
||||||
List<Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series series, bool sceneSource, SearchCriteriaBase searchCriteria = null);
|
List<Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series series, bool sceneSource, SearchCriteriaBase searchCriteria = null);
|
||||||
ParsedEpisodeInfo ParseSpecialEpisodeTitle(string title, int tvRageId, SearchCriteriaBase searchCriteria = null);
|
ParsedEpisodeInfo ParseSpecialEpisodeTitle(string title, int tvRageId, SearchCriteriaBase searchCriteria = null);
|
||||||
}
|
}
|
||||||
|
@ -118,6 +119,16 @@ namespace NzbDrone.Core.Parser
|
||||||
return remoteEpisode;
|
return remoteEpisode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int seriesId, IEnumerable<int> episodeIds)
|
||||||
|
{
|
||||||
|
return new RemoteEpisode
|
||||||
|
{
|
||||||
|
ParsedEpisodeInfo = parsedEpisodeInfo,
|
||||||
|
Series = _seriesService.GetSeries(seriesId),
|
||||||
|
Episodes = _episodeService.GetEpisodes(episodeIds)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public List<Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series series, bool sceneSource, SearchCriteriaBase searchCriteria = null)
|
public List<Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series series, bool sceneSource, SearchCriteriaBase searchCriteria = null)
|
||||||
{
|
{
|
||||||
var result = new List<Episode>();
|
var result = new List<Episode>();
|
||||||
|
|
Loading…
Reference in New Issue