mirror of
https://github.com/lidarr/lidarr.git
synced 2025-08-19 13:10:13 -07:00
Fixed: Get actual file names from QBittorrent API (#5226)
* Fixed: Get actual file names from QBittorrent API Previously we were assuming that the output filename was the category output dir + the torrent name. This isn't true if the torrent has been renamed or sanitized.
This commit is contained in:
parent
0232e8c93e
commit
39b57cfe6e
15 changed files with 272 additions and 14 deletions
|
@ -37,6 +37,7 @@ namespace NzbDrone.Core.Test.Download.CompletedDownloadServiceTests
|
||||||
|
|
||||||
_trackedDownload = Builder<TrackedDownload>.CreateNew()
|
_trackedDownload = Builder<TrackedDownload>.CreateNew()
|
||||||
.With(c => c.State = TrackedDownloadState.Downloading)
|
.With(c => c.State = TrackedDownloadState.Downloading)
|
||||||
|
.With(c => c.ImportItem = completed)
|
||||||
.With(c => c.DownloadItem = completed)
|
.With(c => c.DownloadItem = completed)
|
||||||
.With(c => c.RemoteAlbum = remoteAlbum)
|
.With(c => c.RemoteAlbum = remoteAlbum)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
|
@ -45,6 +45,10 @@ namespace NzbDrone.Core.Test.Download.CompletedDownloadServiceTests
|
||||||
.Setup(c => c.Get(It.IsAny<int>()))
|
.Setup(c => c.Get(It.IsAny<int>()))
|
||||||
.Returns(Mocker.GetMock<IDownloadClient>().Object);
|
.Returns(Mocker.GetMock<IDownloadClient>().Object);
|
||||||
|
|
||||||
|
Mocker.GetMock<IProvideImportItemService>()
|
||||||
|
.Setup(c => c.ProvideImportItem(It.IsAny<DownloadClientItem>(), It.IsAny<DownloadClientItem>()))
|
||||||
|
.Returns((DownloadClientItem item, DownloadClientItem previous) => item);
|
||||||
|
|
||||||
Mocker.GetMock<IHistoryService>()
|
Mocker.GetMock<IHistoryService>()
|
||||||
.Setup(s => s.MostRecentForDownloadId(_trackedDownload.DownloadItem.DownloadId))
|
.Setup(s => s.MostRecentForDownloadId(_trackedDownload.DownloadItem.DownloadId))
|
||||||
.Returns(new History.History());
|
.Returns(new History.History());
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Download.Clients.QBittorrent;
|
using NzbDrone.Core.Download.Clients.QBittorrent;
|
||||||
|
@ -124,6 +126,24 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
||||||
Mocker.GetMock<IQBittorrentProxy>()
|
Mocker.GetMock<IQBittorrentProxy>()
|
||||||
.Setup(s => s.GetTorrents(It.IsAny<QBittorrentSettings>()))
|
.Setup(s => s.GetTorrents(It.IsAny<QBittorrentSettings>()))
|
||||||
.Returns(torrents);
|
.Returns(torrents);
|
||||||
|
|
||||||
|
foreach (var torrent in torrents)
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IQBittorrentProxy>()
|
||||||
|
.Setup(s => s.GetTorrentProperties(torrent.Hash.ToLower(), It.IsAny<QBittorrentSettings>()))
|
||||||
|
.Returns(new QBittorrentTorrentProperties { SavePath = torrent.SavePath });
|
||||||
|
|
||||||
|
Mocker.GetMock<IQBittorrentProxy>()
|
||||||
|
.Setup(s => s.GetTorrentFiles(torrent.Hash.ToLower(), It.IsAny<QBittorrentSettings>()))
|
||||||
|
.Returns(new List<QBittorrentTorrentFile> { new QBittorrentTorrentFile { Name = torrent.Name } });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTorrentFiles(string hash, List<QBittorrentTorrentFile> files)
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IQBittorrentProxy>()
|
||||||
|
.Setup(s => s.GetTorrentFiles(hash.ToLower(), It.IsAny<QBittorrentSettings>()))
|
||||||
|
.Returns(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -259,6 +279,78 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
public void single_file_torrent_outputpath_should_have_sanitised_name()
|
||||||
|
{
|
||||||
|
var torrent = new QBittorrentTorrent
|
||||||
|
{
|
||||||
|
Hash = "HASH",
|
||||||
|
Name = @"Droned.S01E01.Test\'s.1080p.WEB-DL-DRONE.mkv",
|
||||||
|
Size = 1000,
|
||||||
|
Progress = 0.7,
|
||||||
|
Eta = 8640000,
|
||||||
|
State = "stalledDL",
|
||||||
|
Label = "",
|
||||||
|
SavePath = @"C:\Torrents".AsOsAgnostic()
|
||||||
|
};
|
||||||
|
|
||||||
|
var file = new QBittorrentTorrentFile
|
||||||
|
{
|
||||||
|
Name = "Droned.S01E01.Tests.1080p.WEB-DL-DRONE.mkv"
|
||||||
|
};
|
||||||
|
|
||||||
|
GivenTorrents(new List<QBittorrentTorrent> { torrent });
|
||||||
|
GivenTorrentFiles(torrent.Hash, new List<QBittorrentTorrentFile> { file });
|
||||||
|
|
||||||
|
var item = new DownloadClientItem
|
||||||
|
{
|
||||||
|
DownloadId = torrent.Hash
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = Subject.GetImportItem(item, null);
|
||||||
|
|
||||||
|
result.OutputPath.FullPath.Should().Be(Path.Combine(torrent.SavePath, file.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void multi_file_torrent_outputpath_should_have_sanitised_name()
|
||||||
|
{
|
||||||
|
var torrent = new QBittorrentTorrent
|
||||||
|
{
|
||||||
|
Hash = "HASH",
|
||||||
|
Name = @"Droned.S01.\1/2",
|
||||||
|
Size = 1000,
|
||||||
|
Progress = 0.7,
|
||||||
|
Eta = 8640000,
|
||||||
|
State = "stalledDL",
|
||||||
|
Label = "",
|
||||||
|
SavePath = @"C:\Torrents".AsOsAgnostic()
|
||||||
|
};
|
||||||
|
|
||||||
|
var files = new List<QBittorrentTorrentFile>
|
||||||
|
{
|
||||||
|
new QBittorrentTorrentFile
|
||||||
|
{
|
||||||
|
Name = @"Droned.S01.12\E01.mkv".AsOsAgnostic()
|
||||||
|
},
|
||||||
|
new QBittorrentTorrentFile
|
||||||
|
{
|
||||||
|
Name = @"Droned.S01.12\E02.mkv".AsOsAgnostic()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GivenTorrents(new List<QBittorrentTorrent> { torrent });
|
||||||
|
GivenTorrentFiles(torrent.Hash, files);
|
||||||
|
|
||||||
|
var item = new DownloadClientItem
|
||||||
|
{
|
||||||
|
DownloadId = torrent.Hash
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = Subject.GetImportItem(item, null);
|
||||||
|
|
||||||
|
result.OutputPath.FullPath.Should().Be(Path.Combine(torrent.SavePath, "Droned.S01.12"));
|
||||||
|
}
|
||||||
|
|
||||||
public void missingFiles_item_should_have_required_properties()
|
public void missingFiles_item_should_have_required_properties()
|
||||||
{
|
{
|
||||||
var torrent = new QBittorrentTorrent
|
var torrent = new QBittorrentTorrent
|
||||||
|
@ -279,6 +371,39 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
||||||
item.RemainingTime.Should().NotHaveValue();
|
item.RemainingTime.Should().NotHaveValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void api_261_should_use_content_path()
|
||||||
|
{
|
||||||
|
var torrent = new QBittorrentTorrent
|
||||||
|
{
|
||||||
|
Hash = "HASH",
|
||||||
|
Name = @"Droned.S01.\1/2",
|
||||||
|
Size = 1000,
|
||||||
|
Progress = 0.7,
|
||||||
|
Eta = 8640000,
|
||||||
|
State = "stalledDL",
|
||||||
|
Label = "",
|
||||||
|
SavePath = @"C:\Torrents".AsOsAgnostic(),
|
||||||
|
ContentPath = @"C:\Torrents\Droned.S01.12".AsOsAgnostic()
|
||||||
|
};
|
||||||
|
|
||||||
|
GivenTorrents(new List<QBittorrentTorrent> { torrent });
|
||||||
|
|
||||||
|
Mocker.GetMock<IQBittorrentProxy>()
|
||||||
|
.Setup(v => v.GetApiVersion(It.IsAny<QBittorrentSettings>()))
|
||||||
|
.Returns(new Version(2, 6, 1));
|
||||||
|
|
||||||
|
var item = new DownloadClientItem
|
||||||
|
{
|
||||||
|
DownloadId = torrent.Hash,
|
||||||
|
OutputPath = new OsPath(torrent.ContentPath)
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = Subject.GetImportItem(item, null);
|
||||||
|
|
||||||
|
result.OutputPath.FullPath.Should().Be(torrent.ContentPath);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Download_should_return_unique_id()
|
public void Download_should_return_unique_id()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
@ -122,6 +123,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
|
|
||||||
public override IEnumerable<DownloadClientItem> GetItems()
|
public override IEnumerable<DownloadClientItem> GetItems()
|
||||||
{
|
{
|
||||||
|
var version = Proxy.GetApiVersion(Settings);
|
||||||
var config = Proxy.GetConfig(Settings);
|
var config = Proxy.GetConfig(Settings);
|
||||||
var torrents = Proxy.GetTorrents(Settings);
|
var torrents = Proxy.GetTorrents(Settings);
|
||||||
|
|
||||||
|
@ -138,19 +140,18 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
DownloadClient = Definition.Name,
|
DownloadClient = Definition.Name,
|
||||||
RemainingSize = (long)(torrent.Size * (1.0 - torrent.Progress)),
|
RemainingSize = (long)(torrent.Size * (1.0 - torrent.Progress)),
|
||||||
RemainingTime = GetRemainingTime(torrent),
|
RemainingTime = GetRemainingTime(torrent),
|
||||||
SeedRatio = torrent.Ratio,
|
SeedRatio = torrent.Ratio
|
||||||
OutputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, new OsPath(torrent.SavePath)),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (version >= new Version("2.6.1"))
|
||||||
|
{
|
||||||
|
item.OutputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, new OsPath(torrent.ContentPath));
|
||||||
|
}
|
||||||
|
|
||||||
// Avoid removing torrents that haven't reached the global max ratio.
|
// Avoid removing torrents that haven't reached the global max ratio.
|
||||||
// Removal also requires the torrent to be paused, in case a higher max ratio was set on the torrent itself (which is not exposed by the api).
|
// Removal also requires the torrent to be paused, in case a higher max ratio was set on the torrent itself (which is not exposed by the api).
|
||||||
item.CanMoveFiles = item.CanBeRemoved = torrent.State == "pausedUP" && HasReachedSeedLimit(torrent, config);
|
item.CanMoveFiles = item.CanBeRemoved = torrent.State == "pausedUP" && HasReachedSeedLimit(torrent, config);
|
||||||
|
|
||||||
if (!item.OutputPath.IsEmpty && item.OutputPath.FileName != torrent.Name)
|
|
||||||
{
|
|
||||||
item.OutputPath += torrent.Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (torrent.State)
|
switch (torrent.State)
|
||||||
{
|
{
|
||||||
case "error": // some error occurred, applies to paused torrents
|
case "error": // some error occurred, applies to paused torrents
|
||||||
|
@ -224,6 +225,49 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
Proxy.RemoveTorrent(hash.ToLower(), deleteData, Settings);
|
Proxy.RemoveTorrent(hash.ToLower(), deleteData, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override DownloadClientItem GetImportItem(DownloadClientItem item, DownloadClientItem previousImportAttempt)
|
||||||
|
{
|
||||||
|
// On API version >= 2.6.1 this is already set correctly
|
||||||
|
if (!item.OutputPath.IsEmpty)
|
||||||
|
{
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
var files = Proxy.GetTorrentFiles(item.DownloadId.ToLower(), Settings);
|
||||||
|
if (!files.Any())
|
||||||
|
{
|
||||||
|
_logger.Debug($"No files found for torrent {item.Title} in qBittorrent");
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
var properties = Proxy.GetTorrentProperties(item.DownloadId.ToLower(), Settings);
|
||||||
|
var savePath = new OsPath(properties.SavePath);
|
||||||
|
|
||||||
|
var result = item.Clone();
|
||||||
|
|
||||||
|
OsPath outputPath;
|
||||||
|
if (files.Count == 1)
|
||||||
|
{
|
||||||
|
outputPath = savePath + files[0].Name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we have multiple files in the torrent so just get
|
||||||
|
// the first subdirectory
|
||||||
|
var relativePath = new OsPath(files[0].Name);
|
||||||
|
while (!relativePath.Directory.IsEmpty)
|
||||||
|
{
|
||||||
|
relativePath = relativePath.Directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
outputPath = savePath + relativePath.FileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.OutputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, outputPath);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public override DownloadClientInfo GetStatus()
|
public override DownloadClientInfo GetStatus()
|
||||||
{
|
{
|
||||||
var config = Proxy.GetConfig(Settings);
|
var config = Proxy.GetConfig(Settings);
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
QBittorrentPreferences GetConfig(QBittorrentSettings settings);
|
QBittorrentPreferences GetConfig(QBittorrentSettings settings);
|
||||||
List<QBittorrentTorrent> GetTorrents(QBittorrentSettings settings);
|
List<QBittorrentTorrent> GetTorrents(QBittorrentSettings settings);
|
||||||
QBittorrentTorrentProperties GetTorrentProperties(string hash, QBittorrentSettings settings);
|
QBittorrentTorrentProperties GetTorrentProperties(string hash, QBittorrentSettings settings);
|
||||||
|
List<QBittorrentTorrentFile> GetTorrentFiles(string hash, QBittorrentSettings settings);
|
||||||
|
|
||||||
void AddTorrentFromUrl(string torrentUrl, QBittorrentSettings settings);
|
void AddTorrentFromUrl(string torrentUrl, QBittorrentSettings settings);
|
||||||
void AddTorrentFromFile(string fileName, byte[] fileContent, QBittorrentSettings settings);
|
void AddTorrentFromFile(string fileName, byte[] fileContent, QBittorrentSettings settings);
|
||||||
|
|
|
@ -107,6 +107,14 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<QBittorrentTorrentFile> GetTorrentFiles(string hash, QBittorrentSettings settings)
|
||||||
|
{
|
||||||
|
var request = BuildRequest(settings).Resource($"/query/propertiesFiles/{hash}");
|
||||||
|
var response = ProcessRequest<List<QBittorrentTorrentFile>>(request, settings);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
public void AddTorrentFromUrl(string torrentUrl, QBittorrentSettings settings)
|
public void AddTorrentFromUrl(string torrentUrl, QBittorrentSettings settings)
|
||||||
{
|
{
|
||||||
var request = BuildRequest(settings).Resource("/command/download")
|
var request = BuildRequest(settings).Resource("/command/download")
|
||||||
|
|
|
@ -105,6 +105,15 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<QBittorrentTorrentFile> GetTorrentFiles(string hash, QBittorrentSettings settings)
|
||||||
|
{
|
||||||
|
var request = BuildRequest(settings).Resource("/api/v2/torrents/files")
|
||||||
|
.AddQueryParam("hash", hash);
|
||||||
|
var response = ProcessRequest<List<QBittorrentTorrentFile>>(request, settings);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
public void AddTorrentFromUrl(string torrentUrl, QBittorrentSettings settings)
|
public void AddTorrentFromUrl(string torrentUrl, QBittorrentSettings settings)
|
||||||
{
|
{
|
||||||
var request = BuildRequest(settings).Resource("/api/v2/torrents/add")
|
var request = BuildRequest(settings).Resource("/api/v2/torrents/add")
|
||||||
|
|
|
@ -24,6 +24,9 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
[JsonProperty(PropertyName = "save_path")]
|
[JsonProperty(PropertyName = "save_path")]
|
||||||
public string SavePath { get; set; } // Torrent save path
|
public string SavePath { get; set; } // Torrent save path
|
||||||
|
|
||||||
|
[JsonProperty(PropertyName = "content_path")]
|
||||||
|
public string ContentPath { get; set; } // Torrent save path
|
||||||
|
|
||||||
public float Ratio { get; set; } // Torrent share ratio
|
public float Ratio { get; set; } // Torrent share ratio
|
||||||
|
|
||||||
[JsonProperty(PropertyName = "ratio_limit")] // Per torrent seeding ratio limit (-2 = use global, -1 = unlimited)
|
[JsonProperty(PropertyName = "ratio_limit")] // Per torrent seeding ratio limit (-2 = use global, -1 = unlimited)
|
||||||
|
@ -40,7 +43,15 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
{
|
{
|
||||||
public string Hash { get; set; } // Torrent hash
|
public string Hash { get; set; } // Torrent hash
|
||||||
|
|
||||||
|
[JsonProperty(PropertyName = "save_path")]
|
||||||
|
public string SavePath { get; set; }
|
||||||
|
|
||||||
[JsonProperty(PropertyName = "seeding_time")]
|
[JsonProperty(PropertyName = "seeding_time")]
|
||||||
public long SeedingTime { get; set; } // Torrent seeding time
|
public long SeedingTime { get; set; } // Torrent seeding time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class QBittorrentTorrentFile
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
@ -25,16 +26,19 @@ namespace NzbDrone.Core.Download
|
||||||
private readonly IHistoryService _historyService;
|
private readonly IHistoryService _historyService;
|
||||||
private readonly IDownloadedTracksImportService _downloadedTracksImportService;
|
private readonly IDownloadedTracksImportService _downloadedTracksImportService;
|
||||||
private readonly IArtistService _artistService;
|
private readonly IArtistService _artistService;
|
||||||
|
private readonly IProvideImportItemService _importItemService;
|
||||||
private readonly ITrackedDownloadAlreadyImported _trackedDownloadAlreadyImported;
|
private readonly ITrackedDownloadAlreadyImported _trackedDownloadAlreadyImported;
|
||||||
|
|
||||||
public CompletedDownloadService(IEventAggregator eventAggregator,
|
public CompletedDownloadService(IEventAggregator eventAggregator,
|
||||||
IHistoryService historyService,
|
IHistoryService historyService,
|
||||||
|
IProvideImportItemService importItemService,
|
||||||
IDownloadedTracksImportService downloadedTracksImportService,
|
IDownloadedTracksImportService downloadedTracksImportService,
|
||||||
IArtistService artistService,
|
IArtistService artistService,
|
||||||
ITrackedDownloadAlreadyImported trackedDownloadAlreadyImported)
|
ITrackedDownloadAlreadyImported trackedDownloadAlreadyImported)
|
||||||
{
|
{
|
||||||
_eventAggregator = eventAggregator;
|
_eventAggregator = eventAggregator;
|
||||||
_historyService = historyService;
|
_historyService = historyService;
|
||||||
|
_importItemService = importItemService;
|
||||||
_downloadedTracksImportService = downloadedTracksImportService;
|
_downloadedTracksImportService = downloadedTracksImportService;
|
||||||
_artistService = artistService;
|
_artistService = artistService;
|
||||||
_trackedDownloadAlreadyImported = trackedDownloadAlreadyImported;
|
_trackedDownloadAlreadyImported = trackedDownloadAlreadyImported;
|
||||||
|
@ -48,6 +52,8 @@ namespace NzbDrone.Core.Download
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trackedDownload.ImportItem = _importItemService.ProvideImportItem(trackedDownload.DownloadItem, trackedDownload.ImportItem);
|
||||||
|
|
||||||
// Only process tracked downloads that are still downloading
|
// Only process tracked downloads that are still downloading
|
||||||
if (trackedDownload.State != TrackedDownloadState.Downloading)
|
if (trackedDownload.State != TrackedDownloadState.Downloading)
|
||||||
{
|
{
|
||||||
|
@ -62,7 +68,7 @@ namespace NzbDrone.Core.Download
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var downloadItemOutputPath = trackedDownload.DownloadItem.OutputPath;
|
var downloadItemOutputPath = trackedDownload.ImportItem.OutputPath;
|
||||||
|
|
||||||
if (downloadItemOutputPath.IsEmpty)
|
if (downloadItemOutputPath.IsEmpty)
|
||||||
{
|
{
|
||||||
|
@ -100,7 +106,7 @@ namespace NzbDrone.Core.Download
|
||||||
{
|
{
|
||||||
trackedDownload.State = TrackedDownloadState.Importing;
|
trackedDownload.State = TrackedDownloadState.Importing;
|
||||||
|
|
||||||
var outputPath = trackedDownload.DownloadItem.OutputPath.FullPath;
|
var outputPath = trackedDownload.ImportItem.OutputPath.FullPath;
|
||||||
var importResults = _downloadedTracksImportService.ProcessPath(outputPath, ImportMode.Auto, trackedDownload.RemoteAlbum.Artist, trackedDownload.DownloadItem);
|
var importResults = _downloadedTracksImportService.ProcessPath(outputPath, ImportMode.Auto, trackedDownload.RemoteAlbum.Artist, trackedDownload.DownloadItem);
|
||||||
|
|
||||||
if (importResults.Empty())
|
if (importResults.Empty())
|
||||||
|
|
|
@ -62,6 +62,12 @@ namespace NzbDrone.Core.Download
|
||||||
|
|
||||||
public abstract string Download(RemoteAlbum remoteAlbum);
|
public abstract string Download(RemoteAlbum remoteAlbum);
|
||||||
public abstract IEnumerable<DownloadClientItem> GetItems();
|
public abstract IEnumerable<DownloadClientItem> GetItems();
|
||||||
|
|
||||||
|
public virtual DownloadClientItem GetImportItem(DownloadClientItem item, DownloadClientItem previousImportAttempt)
|
||||||
|
{
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void RemoveItem(string downloadId, bool deleteData);
|
public abstract void RemoveItem(string downloadId, bool deleteData);
|
||||||
public abstract DownloadClientInfo GetStatus();
|
public abstract DownloadClientInfo GetStatus();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Core.Indexers;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download
|
namespace NzbDrone.Core.Download
|
||||||
{
|
{
|
||||||
|
@ -25,6 +26,20 @@ namespace NzbDrone.Core.Download
|
||||||
|
|
||||||
public bool CanMoveFiles { get; set; }
|
public bool CanMoveFiles { get; set; }
|
||||||
public bool CanBeRemoved { get; set; }
|
public bool CanBeRemoved { get; set; }
|
||||||
|
public bool Removed { get; set; }
|
||||||
|
|
||||||
|
public DownloadClientItem Clone()
|
||||||
|
{
|
||||||
|
return MemberwiseClone() as DownloadClientItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DownloadClientItemClientInfo
|
||||||
|
{
|
||||||
|
public DownloadProtocol Protocol { get; set; }
|
||||||
|
public string Type { get; set; }
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
public bool Removed { get; set; }
|
public bool Removed { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
@ -11,6 +11,7 @@ namespace NzbDrone.Core.Download
|
||||||
|
|
||||||
string Download(RemoteAlbum remoteAlbum);
|
string Download(RemoteAlbum remoteAlbum);
|
||||||
IEnumerable<DownloadClientItem> GetItems();
|
IEnumerable<DownloadClientItem> GetItems();
|
||||||
|
DownloadClientItem GetImportItem(DownloadClientItem item, DownloadClientItem previousImportAttempt);
|
||||||
void RemoveItem(string downloadId, bool deleteData);
|
void RemoveItem(string downloadId, bool deleteData);
|
||||||
DownloadClientInfo GetStatus();
|
DownloadClientInfo GetStatus();
|
||||||
void MarkItemAsImported(DownloadClientItem downloadClientItem);
|
void MarkItemAsImported(DownloadClientItem downloadClientItem);
|
||||||
|
|
24
src/NzbDrone.Core/Download/PrepareImportService.cs
Normal file
24
src/NzbDrone.Core/Download/PrepareImportService.cs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
namespace NzbDrone.Core.Download
|
||||||
|
{
|
||||||
|
public interface IProvideImportItemService
|
||||||
|
{
|
||||||
|
DownloadClientItem ProvideImportItem(DownloadClientItem item, DownloadClientItem previousImportAttempt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ProvideImportItemService : IProvideImportItemService
|
||||||
|
{
|
||||||
|
private readonly IProvideDownloadClient _downloadClientProvider;
|
||||||
|
|
||||||
|
public ProvideImportItemService(IProvideDownloadClient downloadClientProvider)
|
||||||
|
{
|
||||||
|
_downloadClientProvider = downloadClientProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadClientItem ProvideImportItem(DownloadClientItem item, DownloadClientItem previousImportAttempt)
|
||||||
|
{
|
||||||
|
var client = _downloadClientProvider.Get(item.DownloadClientInfo.Id);
|
||||||
|
|
||||||
|
return client.GetImportItem(item, previousImportAttempt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
|
||||||
{
|
{
|
||||||
public int DownloadClient { get; set; }
|
public int DownloadClient { get; set; }
|
||||||
public DownloadClientItem DownloadItem { get; set; }
|
public DownloadClientItem DownloadItem { get; set; }
|
||||||
|
public DownloadClientItem ImportItem { get; set; }
|
||||||
public TrackedDownloadState State { get; set; }
|
public TrackedDownloadState State { get; set; }
|
||||||
public TrackedDownloadStatus Status { get; private set; }
|
public TrackedDownloadStatus Status { get; private set; }
|
||||||
public RemoteAlbum RemoteAlbum { get; set; }
|
public RemoteAlbum RemoteAlbum { get; set; }
|
||||||
|
|
|
@ -89,7 +89,7 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Manual
|
||||||
return new List<ManualImportItem>();
|
return new List<ManualImportItem>();
|
||||||
}
|
}
|
||||||
|
|
||||||
path = trackedDownload.DownloadItem.OutputPath.FullPath;
|
path = trackedDownload.ImportItem.OutputPath.FullPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_diskProvider.FolderExists(path))
|
if (!_diskProvider.FolderExists(path))
|
||||||
|
@ -363,13 +363,15 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Manual
|
||||||
{
|
{
|
||||||
var trackedDownload = groupedTrackedDownload.First().TrackedDownload;
|
var trackedDownload = groupedTrackedDownload.First().TrackedDownload;
|
||||||
|
|
||||||
if (_diskProvider.FolderExists(trackedDownload.DownloadItem.OutputPath.FullPath))
|
var outputPath = trackedDownload.ImportItem.OutputPath.FullPath;
|
||||||
|
|
||||||
|
if (_diskProvider.FolderExists(outputPath))
|
||||||
{
|
{
|
||||||
if (_downloadedTracksImportService.ShouldDeleteFolder(
|
if (_downloadedTracksImportService.ShouldDeleteFolder(
|
||||||
_diskProvider.GetDirectoryInfo(trackedDownload.DownloadItem.OutputPath.FullPath),
|
_diskProvider.GetDirectoryInfo(outputPath),
|
||||||
trackedDownload.RemoteAlbum.Artist) && trackedDownload.DownloadItem.CanMoveFiles)
|
trackedDownload.RemoteAlbum.Artist) && trackedDownload.DownloadItem.CanMoveFiles)
|
||||||
{
|
{
|
||||||
_diskProvider.DeleteFolder(trackedDownload.DownloadItem.OutputPath.FullPath, true);
|
_diskProvider.DeleteFolder(outputPath, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue