mirror of
https://github.com/lidarr/Lidarr
synced 2025-02-19 12:41:07 +00:00
Fixed: some issues around removing completed and failed downloads
This commit is contained in:
parent
4ac9fd939a
commit
e79a2c742a
18 changed files with 39 additions and 156 deletions
src
NzbDrone.Api/Queue
NzbDrone.Core.Test/Download/DownloadClientTests
NzbDrone.Core/Download
Clients
Deluge
Nzbget
Pneumatic
Sabnzbd
TorrentBlackhole
Transmission
UsenetBlackhole
uTorrent
TrackedDownloads
NzbDrone.Update.Test
|
@ -60,7 +60,7 @@ private Response Remove(int id)
|
|||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
downloadClient.RemoveItem(trackedDownload.DownloadItem.DownloadId);
|
||||
downloadClient.RemoveItem(trackedDownload.DownloadItem.DownloadId, true);
|
||||
|
||||
return new object().AsResponse();
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ public void should_throw_if_full_season_download()
|
|||
[Test]
|
||||
public void should_throw_item_is_removed()
|
||||
{
|
||||
Assert.Throws<NotSupportedException>(() => Subject.RemoveItem(""));
|
||||
Assert.Throws<NotSupportedException>(() => Subject.RemoveItem("", true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
@ -25,10 +24,9 @@ public Deluge(IDelugeProxy proxy,
|
|||
IHttpClient httpClient,
|
||||
IConfigService configService,
|
||||
IDiskProvider diskProvider,
|
||||
IParsingService parsingService,
|
||||
IRemotePathMappingService remotePathMappingService,
|
||||
Logger logger)
|
||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, parsingService, remotePathMappingService, logger)
|
||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
||||
{
|
||||
_proxy = proxy;
|
||||
}
|
||||
|
@ -153,14 +151,9 @@ public override IEnumerable<DownloadClientItem> GetItems()
|
|||
return items;
|
||||
}
|
||||
|
||||
public override void RemoveItem(String hash)
|
||||
public override void RemoveItem(string downloadId, bool deleteData)
|
||||
{
|
||||
_proxy.RemoveTorrent(hash.ToLower(), false, Settings);
|
||||
}
|
||||
|
||||
public override String RetryDownload(String hash)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
_proxy.RemoveTorrent(downloadId.ToLower(), deleteData, Settings);
|
||||
}
|
||||
|
||||
public override DownloadClientStatus GetStatus()
|
||||
|
@ -245,7 +238,7 @@ private ValidationFailure TestCategory()
|
|||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
var enabledPlugins = _proxy.GetEnabledPlugins(Settings);
|
||||
|
||||
if (!enabledPlugins.Contains("Label"))
|
||||
|
|
|
@ -185,16 +185,9 @@ public override IEnumerable<DownloadClientItem> GetItems()
|
|||
return GetQueue().Concat(GetHistory()).Where(downloadClientItem => downloadClientItem.Category == Settings.TvCategory);
|
||||
}
|
||||
|
||||
public override void RemoveItem(String id)
|
||||
public override void RemoveItem(string downloadId, bool deleteData)
|
||||
{
|
||||
_proxy.RemoveItem(id, Settings);
|
||||
}
|
||||
|
||||
public override String RetryDownload(String id)
|
||||
{
|
||||
_proxy.RetryDownload(id, Settings);
|
||||
|
||||
return id;
|
||||
_proxy.RemoveItem(downloadId, Settings);
|
||||
}
|
||||
|
||||
public override DownloadClientStatus GetStatus()
|
||||
|
|
|
@ -105,12 +105,7 @@ public override IEnumerable<DownloadClientItem> GetItems()
|
|||
}
|
||||
}
|
||||
|
||||
public override void RemoveItem(String id)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override String RetryDownload(String id)
|
||||
public override void RemoveItem(string downloadId, bool deleteData)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Validation;
|
||||
using NzbDrone.Core.RemotePathMappings;
|
||||
|
@ -23,7 +21,6 @@ public Sabnzbd(ISabnzbdProxy proxy,
|
|||
IHttpClient httpClient,
|
||||
IConfigService configService,
|
||||
IDiskProvider diskProvider,
|
||||
IParsingService parsingService,
|
||||
IRemotePathMappingService remotePathMappingService,
|
||||
Logger logger)
|
||||
: base(httpClient, configService, diskProvider, remotePathMappingService, logger)
|
||||
|
@ -190,76 +187,18 @@ public override IEnumerable<DownloadClientItem> GetItems()
|
|||
}
|
||||
}
|
||||
|
||||
public override void RemoveItem(String id)
|
||||
public override void RemoveItem(string downloadId, bool deleteData)
|
||||
{
|
||||
if (GetQueue().Any(v => v.DownloadId == id))
|
||||
if (GetQueue().Any(v => v.DownloadId == downloadId))
|
||||
{
|
||||
_proxy.RemoveFrom("queue", id, Settings);
|
||||
_proxy.RemoveFrom("queue", downloadId, deleteData, Settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
_proxy.RemoveFrom("history", id, Settings);
|
||||
_proxy.RemoveFrom("history", downloadId, deleteData, Settings);
|
||||
}
|
||||
}
|
||||
|
||||
public override String RetryDownload(String id)
|
||||
{
|
||||
// Sabnzbd changed the nzo_id for retried downloads without reporting it back to us. We need to try to determine the new ID.
|
||||
// Check both the queue and history because sometimes SAB keeps item in history to retry post processing (depends on failure reason)
|
||||
|
||||
var currentHistory = GetHistory().ToList();
|
||||
var currentHistoryItems = currentHistory.Where(v => v.DownloadId == id).ToList();
|
||||
|
||||
if (currentHistoryItems.Count != 1)
|
||||
{
|
||||
_logger.Warn("History item missing. Couldn't get the new nzoid.");
|
||||
return id;
|
||||
}
|
||||
|
||||
var currentHistoryItem = currentHistoryItems.First();
|
||||
var otherItemsWithSameTitle = currentHistory.Where(h => h.Title == currentHistoryItem.Title &&
|
||||
h.DownloadId != currentHistoryItem.DownloadId).ToList();
|
||||
|
||||
var newId = _proxy.RetryDownload(id, Settings);
|
||||
|
||||
if (newId.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
return newId;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
var queue = GetQueue().Where(v => v.Category == currentHistoryItem.Category &&
|
||||
v.Title == currentHistoryItem.Title).ToList();
|
||||
|
||||
var history = GetHistory().Where(v => v.Category == currentHistoryItem.Category &&
|
||||
v.Title == currentHistoryItem.Title &&
|
||||
!otherItemsWithSameTitle.Select(h => h.DownloadId)
|
||||
.Contains(v.DownloadId)).ToList();
|
||||
|
||||
if (queue.Count == 1)
|
||||
{
|
||||
return queue.First().DownloadId;
|
||||
}
|
||||
|
||||
if (history.Count == 1)
|
||||
{
|
||||
return history.First().DownloadId;
|
||||
}
|
||||
|
||||
if (queue.Count > 1 || history.Count > 1)
|
||||
{
|
||||
_logger.Warn("Multiple items with the correct title. Couldn't get the new nzoid.");
|
||||
return id;
|
||||
}
|
||||
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
_logger.Warn("No items with the correct title. Couldn't get the new nzoid.");
|
||||
return id;
|
||||
}
|
||||
|
||||
protected IEnumerable<SabnzbdCategory> GetCategories(SabnzbdConfig config)
|
||||
{
|
||||
var completeDir = new OsPath(config.Misc.complete_dir);
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
|||
public interface ISabnzbdProxy
|
||||
{
|
||||
SabnzbdAddResponse DownloadNzb(Byte[] nzbData, string name, string category, int priority, SabnzbdSettings settings);
|
||||
void RemoveFrom(string source, string id, SabnzbdSettings settings);
|
||||
void RemoveFrom(string source, string id,bool deleteData, SabnzbdSettings settings);
|
||||
string ProcessRequest(IRestRequest restRequest, string action, SabnzbdSettings settings);
|
||||
SabnzbdVersionResponse GetVersion(SabnzbdSettings settings);
|
||||
SabnzbdConfig GetConfig(SabnzbdSettings settings);
|
||||
|
@ -48,10 +48,11 @@ public SabnzbdAddResponse DownloadNzb(Byte[] nzbData, string title, string categ
|
|||
return response;
|
||||
}
|
||||
|
||||
public void RemoveFrom(string source, string id, SabnzbdSettings settings)
|
||||
public void RemoveFrom(string source, string id, bool deleteData, SabnzbdSettings settings)
|
||||
{
|
||||
var request = new RestRequest();
|
||||
var action = String.Format("mode={0}&name=delete&del_files=1&value={1}", source, id);
|
||||
|
||||
var action = String.Format("mode={0}&name=delete&del_files={1}&value={2}", source, deleteData ? 1 : 0, id);
|
||||
|
||||
ProcessRequest(request, action, settings);
|
||||
}
|
||||
|
|
|
@ -123,12 +123,7 @@ public override IEnumerable<DownloadClientItem> GetItems()
|
|||
}
|
||||
}
|
||||
|
||||
public override void RemoveItem(string id)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override String RetryDownload(string id)
|
||||
public override void RemoveItem(string downloadId, bool deleteData)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
|
|
@ -26,10 +26,9 @@ public Transmission(ITransmissionProxy proxy,
|
|||
IHttpClient httpClient,
|
||||
IConfigService configService,
|
||||
IDiskProvider diskProvider,
|
||||
IParsingService parsingService,
|
||||
IRemotePathMappingService remotePathMappingService,
|
||||
Logger logger)
|
||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, parsingService, remotePathMappingService, logger)
|
||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
||||
{
|
||||
_proxy = proxy;
|
||||
}
|
||||
|
@ -143,14 +142,9 @@ public override IEnumerable<DownloadClientItem> GetItems()
|
|||
return items;
|
||||
}
|
||||
|
||||
public override void RemoveItem(String hash)
|
||||
public override void RemoveItem(string downloadId, bool deleteData)
|
||||
{
|
||||
_proxy.RemoveTorrent(hash.ToLower(), false, Settings);
|
||||
}
|
||||
|
||||
public override String RetryDownload(String hash)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
_proxy.RemoveTorrent(downloadId.ToLower(), deleteData, Settings);
|
||||
}
|
||||
|
||||
public override DownloadClientStatus GetStatus()
|
||||
|
|
|
@ -121,12 +121,7 @@ public override IEnumerable<DownloadClientItem> GetItems()
|
|||
}
|
||||
}
|
||||
|
||||
public override void RemoveItem(String id)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override String RetryDownload(String id)
|
||||
public override void RemoveItem(string downloadId, bool deleteData)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Validation;
|
||||
using FluentValidation.Results;
|
||||
|
@ -25,10 +24,9 @@ public UTorrent(IUTorrentProxy proxy,
|
|||
IHttpClient httpClient,
|
||||
IConfigService configService,
|
||||
IDiskProvider diskProvider,
|
||||
IParsingService parsingService,
|
||||
IRemotePathMappingService remotePathMappingService,
|
||||
Logger logger)
|
||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, parsingService, remotePathMappingService, logger)
|
||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
|
||||
{
|
||||
_proxy = proxy;
|
||||
}
|
||||
|
@ -143,14 +141,9 @@ public override IEnumerable<DownloadClientItem> GetItems()
|
|||
return queueItems;
|
||||
}
|
||||
|
||||
public override void RemoveItem(String id)
|
||||
public override void RemoveItem(string downloadId, bool deleteData)
|
||||
{
|
||||
_proxy.RemoveTorrent(id, false, Settings);
|
||||
}
|
||||
|
||||
public override String RetryDownload(String id)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
_proxy.RemoveTorrent(downloadId, deleteData, Settings);
|
||||
}
|
||||
|
||||
public override DownloadClientStatus GetStatus()
|
||||
|
|
|
@ -70,8 +70,7 @@ public abstract DownloadProtocol Protocol
|
|||
|
||||
public abstract String Download(RemoteEpisode remoteEpisode);
|
||||
public abstract IEnumerable<DownloadClientItem> GetItems();
|
||||
public abstract void RemoveItem(string id);
|
||||
public abstract String RetryDownload(string id);
|
||||
public abstract void RemoveItem(string downloadId, bool deleteData);
|
||||
public abstract DownloadClientStatus GetStatus();
|
||||
|
||||
public ValidationResult Test()
|
||||
|
|
|
@ -17,7 +17,6 @@ public DownloadCompletedEvent(TrackedDownload trackedDownload)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public class DownloadEventHub : IHandle<DownloadFailedEvent>,
|
||||
IHandle<DownloadCompletedEvent>
|
||||
{
|
||||
|
@ -52,7 +51,7 @@ public void Handle(DownloadFailedEvent message)
|
|||
var trackedDownload = _trackedDownloadService.Find(message.DownloadId);
|
||||
|
||||
|
||||
if (trackedDownload == null || trackedDownload.DownloadItem.IsReadOnly || !_configService.RemoveFailedDownloads)
|
||||
if (trackedDownload == null || trackedDownload.DownloadItem.IsReadOnly || _configService.RemoveFailedDownloads == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -67,7 +66,7 @@ private void RemoveFromDownloadClient(TrackedDownload trackedDownload)
|
|||
try
|
||||
{
|
||||
_logger.Debug("[{0}] Removing download from {1} history", trackedDownload.DownloadItem.DownloadClient);
|
||||
downloadClient.RemoveItem(trackedDownload.DownloadItem.DownloadId);
|
||||
downloadClient.RemoveItem(trackedDownload.DownloadItem.DownloadId, true);
|
||||
trackedDownload.DownloadItem.Removed = true;
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
|
|
|
@ -12,9 +12,7 @@ public interface IDownloadClient : IProvider
|
|||
|
||||
String Download(RemoteEpisode remoteEpisode);
|
||||
IEnumerable<DownloadClientItem> GetItems();
|
||||
void RemoveItem(String id);
|
||||
String RetryDownload(String id);
|
||||
|
||||
void RemoveItem(string downloadId, bool deleteData);
|
||||
DownloadClientStatus GetStatus();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||
using NzbDrone.Core.Organizer;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
@ -27,7 +26,6 @@ protected TorrentClientBase(ITorrentFileInfoReader torrentFileInfoReader,
|
|||
IHttpClient httpClient,
|
||||
IConfigService configService,
|
||||
IDiskProvider diskProvider,
|
||||
IParsingService parsingService,
|
||||
IRemotePathMappingService remotePathMappingService,
|
||||
Logger logger)
|
||||
: base(configService, diskProvider, remotePathMappingService, logger)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.TPL;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.MediaFiles.Events;
|
||||
|
@ -111,7 +112,7 @@ private List<TrackedDownload> ProcessClientItems(IDownloadClient downloadClient,
|
|||
|
||||
}
|
||||
|
||||
trackedDownloads.Add(trackedDownload);
|
||||
trackedDownloads.AddIfNotNull(trackedDownload);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
using System;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Core.DataAugmentation.Scene;
|
||||
using NzbDrone.Core.History;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Parser;
|
||||
|
||||
namespace NzbDrone.Core.Download.TrackedDownloads
|
||||
|
@ -14,8 +12,7 @@ public interface ITrackedDownloadService
|
|||
TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem);
|
||||
}
|
||||
|
||||
public class TrackedDownloadService : ITrackedDownloadService,
|
||||
IHandle<SceneMappingsUpdatedEvent>
|
||||
public class TrackedDownloadService : ITrackedDownloadService
|
||||
{
|
||||
private readonly IParsingService _parsingService;
|
||||
private readonly IHistoryService _historyService;
|
||||
|
@ -42,7 +39,7 @@ public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, Do
|
|||
{
|
||||
var existingItem = Find(downloadItem.DownloadId);
|
||||
|
||||
if (existingItem != null)
|
||||
if (existingItem != null && existingItem.State != TrackedDownloadStage.Downloading)
|
||||
{
|
||||
existingItem.DownloadItem = downloadItem;
|
||||
return existingItem;
|
||||
|
@ -56,12 +53,6 @@ public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, Do
|
|||
Protocol = downloadClient.Protocol
|
||||
};
|
||||
|
||||
var historyItem = _historyService.MostRecentForDownloadId(downloadItem.DownloadId);
|
||||
if (historyItem != null)
|
||||
{
|
||||
trackedDownload.State = GetStateFromHistory(historyItem.EventType);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title);
|
||||
|
@ -81,11 +72,14 @@ public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, Do
|
|||
return null;
|
||||
}
|
||||
|
||||
if (trackedDownload.State != TrackedDownloadStage.Downloading)
|
||||
var historyItem = _historyService.MostRecentForDownloadId(downloadItem.DownloadId);
|
||||
if (historyItem != null)
|
||||
{
|
||||
_cache.Set(downloadItem.DownloadId, trackedDownload);
|
||||
trackedDownload.State = GetStateFromHistory(historyItem.EventType);
|
||||
}
|
||||
|
||||
_cache.Set(downloadItem.DownloadId, trackedDownload);
|
||||
|
||||
return trackedDownload;
|
||||
}
|
||||
|
||||
|
@ -102,9 +96,5 @@ private static TrackedDownloadStage GetStateFromHistory(HistoryEventType eventTy
|
|||
}
|
||||
}
|
||||
|
||||
public void Handle(SceneMappingsUpdatedEvent message)
|
||||
{
|
||||
_cache.Clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,7 +32,7 @@ public void should_start_console_if_app_type_was_service_but_start_failed_becaus
|
|||
|
||||
Subject.Start(AppType.Service, targetFolder);
|
||||
|
||||
Mocker.GetMock<IProcessProvider>().Verify(c => c.SpawnNewProcess("c:\\NzbDrone\\NzbDrone.Console.exe", "--" + StartupContext.NO_BROWSER), Times.Once());
|
||||
Mocker.GetMock<IProcessProvider>().Verify(c => c.SpawnNewProcess("c:\\NzbDrone\\NzbDrone.Console.exe", "/" + StartupContext.NO_BROWSER), Times.Once());
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue