Fixed: some issues around removing completed and failed downloads

This commit is contained in:
Keivan Beigi 2014-12-22 17:17:48 -08:00
parent 4ac9fd939a
commit e79a2c742a
18 changed files with 39 additions and 156 deletions

View File

@ -60,7 +60,7 @@ namespace NzbDrone.Api.Queue
throw new BadRequestException(); throw new BadRequestException();
} }
downloadClient.RemoveItem(trackedDownload.DownloadItem.DownloadId); downloadClient.RemoveItem(trackedDownload.DownloadItem.DownloadId, true);
return new object().AsResponse(); return new object().AsResponse();
} }

View File

@ -82,7 +82,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
[Test] [Test]
public void should_throw_item_is_removed() public void should_throw_item_is_removed()
{ {
Assert.Throws<NotSupportedException>(() => Subject.RemoveItem("")); Assert.Throws<NotSupportedException>(() => Subject.RemoveItem("", true));
} }
[Test] [Test]

View File

@ -5,7 +5,6 @@ using NzbDrone.Common.Disk;
using NzbDrone.Common.Http; using NzbDrone.Common.Http;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.MediaFiles.TorrentInfo; using NzbDrone.Core.MediaFiles.TorrentInfo;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
@ -25,10 +24,9 @@ namespace NzbDrone.Core.Download.Clients.Deluge
IHttpClient httpClient, IHttpClient httpClient,
IConfigService configService, IConfigService configService,
IDiskProvider diskProvider, IDiskProvider diskProvider,
IParsingService parsingService,
IRemotePathMappingService remotePathMappingService, IRemotePathMappingService remotePathMappingService,
Logger logger) Logger logger)
: base(torrentFileInfoReader, httpClient, configService, diskProvider, parsingService, remotePathMappingService, logger) : base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
{ {
_proxy = proxy; _proxy = proxy;
} }
@ -153,14 +151,9 @@ namespace NzbDrone.Core.Download.Clients.Deluge
return items; return items;
} }
public override void RemoveItem(String hash) public override void RemoveItem(string downloadId, bool deleteData)
{ {
_proxy.RemoveTorrent(hash.ToLower(), false, Settings); _proxy.RemoveTorrent(downloadId.ToLower(), deleteData, Settings);
}
public override String RetryDownload(String hash)
{
throw new NotSupportedException();
} }
public override DownloadClientStatus GetStatus() public override DownloadClientStatus GetStatus()
@ -245,7 +238,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
{ {
return null; return null;
} }
var enabledPlugins = _proxy.GetEnabledPlugins(Settings); var enabledPlugins = _proxy.GetEnabledPlugins(Settings);
if (!enabledPlugins.Contains("Label")) if (!enabledPlugins.Contains("Label"))

View File

@ -185,16 +185,9 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
return GetQueue().Concat(GetHistory()).Where(downloadClientItem => downloadClientItem.Category == Settings.TvCategory); 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); _proxy.RemoveItem(downloadId, Settings);
}
public override String RetryDownload(String id)
{
_proxy.RetryDownload(id, Settings);
return id;
} }
public override DownloadClientStatus GetStatus() public override DownloadClientStatus GetStatus()

View File

@ -105,12 +105,7 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic
} }
} }
public override void RemoveItem(String id) public override void RemoveItem(string downloadId, bool deleteData)
{
throw new NotSupportedException();
}
public override String RetryDownload(String id)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }

View File

@ -1,14 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
using FluentValidation.Results; using FluentValidation.Results;
using NLog; using NLog;
using NzbDrone.Common.Disk; using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http; using NzbDrone.Common.Http;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
using NzbDrone.Core.RemotePathMappings; using NzbDrone.Core.RemotePathMappings;
@ -23,7 +21,6 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
IHttpClient httpClient, IHttpClient httpClient,
IConfigService configService, IConfigService configService,
IDiskProvider diskProvider, IDiskProvider diskProvider,
IParsingService parsingService,
IRemotePathMappingService remotePathMappingService, IRemotePathMappingService remotePathMappingService,
Logger logger) Logger logger)
: base(httpClient, configService, diskProvider, remotePathMappingService, logger) : base(httpClient, configService, diskProvider, remotePathMappingService, logger)
@ -190,76 +187,18 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
} }
} }
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 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) protected IEnumerable<SabnzbdCategory> GetCategories(SabnzbdConfig config)
{ {
var completeDir = new OsPath(config.Misc.complete_dir); var completeDir = new OsPath(config.Misc.complete_dir);

View File

@ -12,7 +12,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
public interface ISabnzbdProxy public interface ISabnzbdProxy
{ {
SabnzbdAddResponse DownloadNzb(Byte[] nzbData, string name, string category, int priority, SabnzbdSettings settings); 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); string ProcessRequest(IRestRequest restRequest, string action, SabnzbdSettings settings);
SabnzbdVersionResponse GetVersion(SabnzbdSettings settings); SabnzbdVersionResponse GetVersion(SabnzbdSettings settings);
SabnzbdConfig GetConfig(SabnzbdSettings settings); SabnzbdConfig GetConfig(SabnzbdSettings settings);
@ -48,10 +48,11 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
return response; 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 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); ProcessRequest(request, action, settings);
} }

View File

@ -123,12 +123,7 @@ namespace NzbDrone.Core.Download.Clients.TorrentBlackhole
} }
} }
public override void RemoveItem(string id) public override void RemoveItem(string downloadId, bool deleteData)
{
throw new NotSupportedException();
}
public override String RetryDownload(string id)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }

View File

@ -26,10 +26,9 @@ namespace NzbDrone.Core.Download.Clients.Transmission
IHttpClient httpClient, IHttpClient httpClient,
IConfigService configService, IConfigService configService,
IDiskProvider diskProvider, IDiskProvider diskProvider,
IParsingService parsingService,
IRemotePathMappingService remotePathMappingService, IRemotePathMappingService remotePathMappingService,
Logger logger) Logger logger)
: base(torrentFileInfoReader, httpClient, configService, diskProvider, parsingService, remotePathMappingService, logger) : base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
{ {
_proxy = proxy; _proxy = proxy;
} }
@ -143,14 +142,9 @@ namespace NzbDrone.Core.Download.Clients.Transmission
return items; return items;
} }
public override void RemoveItem(String hash) public override void RemoveItem(string downloadId, bool deleteData)
{ {
_proxy.RemoveTorrent(hash.ToLower(), false, Settings); _proxy.RemoveTorrent(downloadId.ToLower(), deleteData, Settings);
}
public override String RetryDownload(String hash)
{
throw new NotSupportedException();
} }
public override DownloadClientStatus GetStatus() public override DownloadClientStatus GetStatus()

View File

@ -121,12 +121,7 @@ namespace NzbDrone.Core.Download.Clients.UsenetBlackhole
} }
} }
public override void RemoveItem(String id) public override void RemoveItem(string downloadId, bool deleteData)
{
throw new NotSupportedException();
}
public override String RetryDownload(String id)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }

View File

@ -6,7 +6,6 @@ using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http; using NzbDrone.Common.Http;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.MediaFiles.TorrentInfo; using NzbDrone.Core.MediaFiles.TorrentInfo;
using NzbDrone.Core.Parser;
using NLog; using NLog;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
using FluentValidation.Results; using FluentValidation.Results;
@ -25,10 +24,9 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
IHttpClient httpClient, IHttpClient httpClient,
IConfigService configService, IConfigService configService,
IDiskProvider diskProvider, IDiskProvider diskProvider,
IParsingService parsingService,
IRemotePathMappingService remotePathMappingService, IRemotePathMappingService remotePathMappingService,
Logger logger) Logger logger)
: base(torrentFileInfoReader, httpClient, configService, diskProvider, parsingService, remotePathMappingService, logger) : base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
{ {
_proxy = proxy; _proxy = proxy;
} }
@ -143,14 +141,9 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
return queueItems; return queueItems;
} }
public override void RemoveItem(String id) public override void RemoveItem(string downloadId, bool deleteData)
{ {
_proxy.RemoveTorrent(id, false, Settings); _proxy.RemoveTorrent(downloadId, deleteData, Settings);
}
public override String RetryDownload(String id)
{
throw new NotSupportedException();
} }
public override DownloadClientStatus GetStatus() public override DownloadClientStatus GetStatus()

View File

@ -70,8 +70,7 @@ namespace NzbDrone.Core.Download
public abstract String Download(RemoteEpisode remoteEpisode); public abstract String Download(RemoteEpisode remoteEpisode);
public abstract IEnumerable<DownloadClientItem> GetItems(); public abstract IEnumerable<DownloadClientItem> GetItems();
public abstract void RemoveItem(string id); public abstract void RemoveItem(string downloadId, bool deleteData);
public abstract String RetryDownload(string id);
public abstract DownloadClientStatus GetStatus(); public abstract DownloadClientStatus GetStatus();
public ValidationResult Test() public ValidationResult Test()

View File

@ -17,7 +17,6 @@ namespace NzbDrone.Core.Download
} }
} }
public class DownloadEventHub : IHandle<DownloadFailedEvent>, public class DownloadEventHub : IHandle<DownloadFailedEvent>,
IHandle<DownloadCompletedEvent> IHandle<DownloadCompletedEvent>
{ {
@ -52,7 +51,7 @@ namespace NzbDrone.Core.Download
var trackedDownload = _trackedDownloadService.Find(message.DownloadId); var trackedDownload = _trackedDownloadService.Find(message.DownloadId);
if (trackedDownload == null || trackedDownload.DownloadItem.IsReadOnly || !_configService.RemoveFailedDownloads) if (trackedDownload == null || trackedDownload.DownloadItem.IsReadOnly || _configService.RemoveFailedDownloads == false)
{ {
return; return;
} }
@ -67,7 +66,7 @@ namespace NzbDrone.Core.Download
try try
{ {
_logger.Debug("[{0}] Removing download from {1} history", trackedDownload.DownloadItem.DownloadClient); _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; trackedDownload.DownloadItem.Removed = true;
} }
catch (NotSupportedException) catch (NotSupportedException)

View File

@ -12,9 +12,7 @@ namespace NzbDrone.Core.Download
String Download(RemoteEpisode remoteEpisode); String Download(RemoteEpisode remoteEpisode);
IEnumerable<DownloadClientItem> GetItems(); IEnumerable<DownloadClientItem> GetItems();
void RemoveItem(String id); void RemoveItem(string downloadId, bool deleteData);
String RetryDownload(String id);
DownloadClientStatus GetStatus(); DownloadClientStatus GetStatus();
} }
} }

View File

@ -8,7 +8,6 @@ using NzbDrone.Core.Exceptions;
using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers;
using NzbDrone.Core.MediaFiles.TorrentInfo; using NzbDrone.Core.MediaFiles.TorrentInfo;
using NzbDrone.Core.Organizer; using NzbDrone.Core.Organizer;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
@ -27,7 +26,6 @@ namespace NzbDrone.Core.Download
IHttpClient httpClient, IHttpClient httpClient,
IConfigService configService, IConfigService configService,
IDiskProvider diskProvider, IDiskProvider diskProvider,
IParsingService parsingService,
IRemotePathMappingService remotePathMappingService, IRemotePathMappingService remotePathMappingService,
Logger logger) Logger logger)
: base(configService, diskProvider, remotePathMappingService, logger) : base(configService, diskProvider, remotePathMappingService, logger)

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NLog; using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.TPL; using NzbDrone.Common.TPL;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.MediaFiles.Events; using NzbDrone.Core.MediaFiles.Events;
@ -111,7 +112,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
} }
trackedDownloads.Add(trackedDownload); trackedDownloads.AddIfNotNull(trackedDownload);
} }
catch (Exception e) catch (Exception e)

View File

@ -1,9 +1,7 @@
using System; using System;
using NLog; using NLog;
using NzbDrone.Common.Cache; using NzbDrone.Common.Cache;
using NzbDrone.Core.DataAugmentation.Scene;
using NzbDrone.Core.History; using NzbDrone.Core.History;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Parser; using NzbDrone.Core.Parser;
namespace NzbDrone.Core.Download.TrackedDownloads namespace NzbDrone.Core.Download.TrackedDownloads
@ -14,8 +12,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem); TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem);
} }
public class TrackedDownloadService : ITrackedDownloadService, public class TrackedDownloadService : ITrackedDownloadService
IHandle<SceneMappingsUpdatedEvent>
{ {
private readonly IParsingService _parsingService; private readonly IParsingService _parsingService;
private readonly IHistoryService _historyService; private readonly IHistoryService _historyService;
@ -42,7 +39,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
{ {
var existingItem = Find(downloadItem.DownloadId); var existingItem = Find(downloadItem.DownloadId);
if (existingItem != null) if (existingItem != null && existingItem.State != TrackedDownloadStage.Downloading)
{ {
existingItem.DownloadItem = downloadItem; existingItem.DownloadItem = downloadItem;
return existingItem; return existingItem;
@ -56,12 +53,6 @@ namespace NzbDrone.Core.Download.TrackedDownloads
Protocol = downloadClient.Protocol Protocol = downloadClient.Protocol
}; };
var historyItem = _historyService.MostRecentForDownloadId(downloadItem.DownloadId);
if (historyItem != null)
{
trackedDownload.State = GetStateFromHistory(historyItem.EventType);
}
try try
{ {
var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title); var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title);
@ -81,11 +72,14 @@ namespace NzbDrone.Core.Download.TrackedDownloads
return null; 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; return trackedDownload;
} }
@ -102,9 +96,5 @@ namespace NzbDrone.Core.Download.TrackedDownloads
} }
} }
public void Handle(SceneMappingsUpdatedEvent message)
{
_cache.Clear();
}
} }
} }

View File

@ -32,7 +32,7 @@ namespace NzbDrone.Update.Test
Subject.Start(AppType.Service, targetFolder); 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); ExceptionVerification.ExpectedWarns(1);
} }