mirror of
https://github.com/lidarr/Lidarr
synced 2025-02-21 13:37:19 +00:00
Failed downloads are removed from queue/history (opt out)
This commit is contained in:
parent
769fcdfc80
commit
d634dd1e5c
10 changed files with 174 additions and 28 deletions
|
@ -268,6 +268,13 @@ public Boolean AutoRedownloadFailed
|
||||||
set { SetValue("AutoRedownloadFailed", value); }
|
set { SetValue("AutoRedownloadFailed", value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Boolean RemoveFailedDownloads
|
||||||
|
{
|
||||||
|
get { return GetValueBoolean("RemoveFailedDownloads", true); }
|
||||||
|
|
||||||
|
set { SetValue("RemoveFailedDownloads", value); }
|
||||||
|
}
|
||||||
|
|
||||||
public string DownloadClientWorkingFolders
|
public string DownloadClientWorkingFolders
|
||||||
{
|
{
|
||||||
get { return GetValue("DownloadClientWorkingFolders", "_UNPACK_|_FAILED_"); }
|
get { return GetValue("DownloadClientWorkingFolders", "_UNPACK_|_FAILED_"); }
|
||||||
|
|
|
@ -40,6 +40,7 @@ public interface IConfigService
|
||||||
Boolean AutoDownloadPropers { get; set; }
|
Boolean AutoDownloadPropers { get; set; }
|
||||||
String DownloadClientWorkingFolders { get; set; }
|
String DownloadClientWorkingFolders { get; set; }
|
||||||
Boolean AutoRedownloadFailed { get; set; }
|
Boolean AutoRedownloadFailed { get; set; }
|
||||||
|
Boolean RemoveFailedDownloads { get; set; }
|
||||||
void SaveValues(Dictionary<string, object> configValues);
|
void SaveValues(Dictionary<string, object> configValues);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,5 +57,13 @@ public IEnumerable<HistoryItem> GetHistory(int start = 0, int limit = 0)
|
||||||
{
|
{
|
||||||
return new HistoryItem[0];
|
return new HistoryItem[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RemoveFromQueue(string id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveFromHistory(string id)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,16 @@ public IEnumerable<HistoryItem> GetHistory(int start = 0, int limit = 0)
|
||||||
return new HistoryItem[0];
|
return new HistoryItem[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RemoveFromQueue(string id)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveFromHistory(string id)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public virtual VersionModel GetVersion(string host = null, int port = 0, string username = null, string password = null)
|
public virtual VersionModel GetVersion(string host = null, int port = 0, string username = null, string password = null)
|
||||||
{
|
{
|
||||||
//Get saved values if any of these are defaults
|
//Get saved values if any of these are defaults
|
||||||
|
|
|
@ -70,6 +70,14 @@ public IEnumerable<HistoryItem> GetHistory(int start = 0, int limit = 0)
|
||||||
return new HistoryItem[0];
|
return new HistoryItem[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RemoveFromQueue(string id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveFromHistory(string id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public virtual bool IsInQueue(RemoteEpisode newEpisode)
|
public virtual bool IsInQueue(RemoteEpisode newEpisode)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -9,6 +9,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
public interface ISabCommunicationProxy
|
public interface ISabCommunicationProxy
|
||||||
{
|
{
|
||||||
string DownloadNzb(Stream nzb, string name, string category, int priority);
|
string DownloadNzb(Stream nzb, string name, string category, int priority);
|
||||||
|
void RemoveFrom(string source, string id);
|
||||||
string ProcessRequest(IRestRequest restRequest, string action);
|
string ProcessRequest(IRestRequest restRequest, string action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +32,14 @@ public string DownloadNzb(Stream nzb, string title, string category, int priorit
|
||||||
return ProcessRequest(request, action);
|
return ProcessRequest(request, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RemoveFrom(string source, string id)
|
||||||
|
{
|
||||||
|
var request = new RestRequest();
|
||||||
|
var action = String.Format("mode={0}&name=delete&del_files=1&value={1}", source, id);
|
||||||
|
|
||||||
|
ProcessRequest(request, action);
|
||||||
|
}
|
||||||
|
|
||||||
public string ProcessRequest(IRestRequest restRequest, string action)
|
public string ProcessRequest(IRestRequest restRequest, string action)
|
||||||
{
|
{
|
||||||
var client = BuildClient(action);
|
var client = BuildClient(action);
|
||||||
|
|
|
@ -89,7 +89,7 @@ public IEnumerable<QueueItem> GetQueue()
|
||||||
queueItem.Timeleft = sabQueueItem.Timeleft;
|
queueItem.Timeleft = sabQueueItem.Timeleft;
|
||||||
queueItem.Status = sabQueueItem.Status;
|
queueItem.Status = sabQueueItem.Status;
|
||||||
|
|
||||||
var parsedEpisodeInfo = Parser.Parser.ParseTitle(queueItem.Title);
|
var parsedEpisodeInfo = Parser.Parser.ParseTitle(queueItem.Title.Replace("ENCRYPTED / ", ""));
|
||||||
if (parsedEpisodeInfo == null) continue;
|
if (parsedEpisodeInfo == null) continue;
|
||||||
|
|
||||||
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0);
|
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0);
|
||||||
|
@ -133,6 +133,16 @@ public IEnumerable<HistoryItem> GetHistory(int start = 0, int limit = 0)
|
||||||
return historyItems;
|
return historyItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RemoveFromQueue(string id)
|
||||||
|
{
|
||||||
|
_sabCommunicationProxy.RemoveFrom("queue", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveFromHistory(string id)
|
||||||
|
{
|
||||||
|
_sabCommunicationProxy.RemoveFrom("history", id);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual SabCategoryModel GetCategories(string host = null, int port = 0, string apiKey = null, string username = null, string password = null)
|
public virtual SabCategoryModel GetCategories(string host = null, int port = 0, string apiKey = null, string username = null, string password = null)
|
||||||
{
|
{
|
||||||
//Get saved values if any of these are defaults
|
//Get saved values if any of these are defaults
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.History;
|
using NzbDrone.Core.History;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
@ -12,44 +14,53 @@ public class FailedDownloadService : IExecute<FailedDownloadCommand>
|
||||||
private readonly IProvideDownloadClient _downloadClientProvider;
|
private readonly IProvideDownloadClient _downloadClientProvider;
|
||||||
private readonly IHistoryService _historyService;
|
private readonly IHistoryService _historyService;
|
||||||
private readonly IEventAggregator _eventAggregator;
|
private readonly IEventAggregator _eventAggregator;
|
||||||
|
private readonly IConfigService _configService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
private readonly IDownloadClient _downloadClient;
|
||||||
|
|
||||||
private static string DOWNLOAD_CLIENT = "downloadClient";
|
private static string DOWNLOAD_CLIENT = "downloadClient";
|
||||||
private static string DOWNLOAD_CLIENT_ID = "downloadClientId";
|
private static string DOWNLOAD_CLIENT_ID = "downloadClientId";
|
||||||
|
|
||||||
public FailedDownloadService(IProvideDownloadClient downloadClientProvider,
|
public FailedDownloadService(IProvideDownloadClient downloadClientProvider,
|
||||||
IHistoryService historyService,
|
IHistoryService historyService,
|
||||||
IEventAggregator eventAggregator,
|
IEventAggregator eventAggregator,
|
||||||
|
IConfigService configService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_downloadClientProvider = downloadClientProvider;
|
_downloadClientProvider = downloadClientProvider;
|
||||||
_historyService = historyService;
|
_historyService = historyService;
|
||||||
_eventAggregator = eventAggregator;
|
_eventAggregator = eventAggregator;
|
||||||
|
_configService = configService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
|
_downloadClient = _downloadClientProvider.GetDownloadClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckForFailedDownloads()
|
private void CheckForFailedDownloads()
|
||||||
{
|
{
|
||||||
var downloadClient = _downloadClientProvider.GetDownloadClient();
|
var grabbedHistory = _historyService.Grabbed();
|
||||||
var downloadClientHistory = downloadClient.GetHistory(0, 20).ToList();
|
var failedHistory = _historyService.Failed();
|
||||||
|
|
||||||
var failedItems = downloadClientHistory.Where(h => h.Status == HistoryStatus.Failed).ToList();
|
CheckQueue(grabbedHistory, failedHistory);
|
||||||
|
CheckHistory(grabbedHistory, failedHistory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckQueue(List<History.History> grabbedHistory, List<History.History> failedHistory)
|
||||||
|
{
|
||||||
|
var downloadClientQueue = _downloadClient.GetQueue().ToList();
|
||||||
|
var failedItems = downloadClientQueue.Where(q => q.Title.StartsWith("ENCRYPTED / ")).ToList();
|
||||||
|
|
||||||
if (!failedItems.Any())
|
if (!failedItems.Any())
|
||||||
{
|
{
|
||||||
_logger.Trace("Yay! No failed downloads");
|
_logger.Trace("Yay! No encrypted downloads");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var grabbedHistory = _historyService.Grabbed();
|
|
||||||
var failedHistory = _historyService.Failed();
|
|
||||||
|
|
||||||
foreach (var failedItem in failedItems)
|
foreach (var failedItem in failedItems)
|
||||||
{
|
{
|
||||||
var failedLocal = failedItem;
|
var failedLocal = failedItem;
|
||||||
var historyItems = grabbedHistory.Where(h => h.Data.ContainsKey(DOWNLOAD_CLIENT) &&
|
var historyItems = GetHistoryItems(grabbedHistory, failedLocal.Id);
|
||||||
h.Data[DOWNLOAD_CLIENT_ID].Equals(failedLocal.Id))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (!historyItems.Any())
|
if (!historyItems.Any())
|
||||||
{
|
{
|
||||||
|
@ -64,8 +75,65 @@ private void CheckForFailedDownloads()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var historyItem = historyItems.First();
|
PublishDownloadFailedEvent(historyItems, "Encypted download detected");
|
||||||
|
|
||||||
|
if (_configService.RemoveFailedDownloads)
|
||||||
|
{
|
||||||
|
_logger.Info("Removing encrypted download from queue: {0}", failedItem.Title.Replace("ENCRYPTED / ", ""));
|
||||||
|
_downloadClient.RemoveFromQueue(failedItem.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckHistory(List<History.History> grabbedHistory, List<History.History> failedHistory)
|
||||||
|
{
|
||||||
|
var downloadClientHistory = _downloadClient.GetHistory(0, 20).ToList();
|
||||||
|
var failedItems = downloadClientHistory.Where(h => h.Status == HistoryStatus.Failed).ToList();
|
||||||
|
|
||||||
|
if (!failedItems.Any())
|
||||||
|
{
|
||||||
|
_logger.Trace("Yay! No failed downloads");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var failedItem in failedItems)
|
||||||
|
{
|
||||||
|
var failedLocal = failedItem;
|
||||||
|
var historyItems = GetHistoryItems(grabbedHistory, failedLocal.Id);
|
||||||
|
|
||||||
|
if (!historyItems.Any())
|
||||||
|
{
|
||||||
|
_logger.Trace("Unable to find matching history item");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failedHistory.Any(h => h.Data.ContainsKey(DOWNLOAD_CLIENT_ID) &&
|
||||||
|
h.Data[DOWNLOAD_CLIENT_ID].Equals(failedLocal.Id)))
|
||||||
|
{
|
||||||
|
_logger.Trace("Already added to history as failed");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PublishDownloadFailedEvent(historyItems, failedItem.Message);
|
||||||
|
|
||||||
|
if (_configService.RemoveFailedDownloads)
|
||||||
|
{
|
||||||
|
_logger.Info("Removing failed download from history: {0}", failedItem.Title);
|
||||||
|
_downloadClient.RemoveFromHistory(failedItem.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<History.History> GetHistoryItems(List<History.History> grabbedHistory, string downloadClientId)
|
||||||
|
{
|
||||||
|
return grabbedHistory.Where(h => h.Data.ContainsKey(DOWNLOAD_CLIENT) &&
|
||||||
|
h.Data[DOWNLOAD_CLIENT_ID].Equals(downloadClientId))
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PublishDownloadFailedEvent(List<History.History> historyItems, string message)
|
||||||
|
{
|
||||||
|
var historyItem = historyItems.First();
|
||||||
_eventAggregator.PublishEvent(new DownloadFailedEvent
|
_eventAggregator.PublishEvent(new DownloadFailedEvent
|
||||||
{
|
{
|
||||||
SeriesId = historyItem.SeriesId,
|
SeriesId = historyItem.SeriesId,
|
||||||
|
@ -74,10 +142,9 @@ private void CheckForFailedDownloads()
|
||||||
SourceTitle = historyItem.SourceTitle,
|
SourceTitle = historyItem.SourceTitle,
|
||||||
DownloadClient = historyItem.Data[DOWNLOAD_CLIENT],
|
DownloadClient = historyItem.Data[DOWNLOAD_CLIENT],
|
||||||
DownloadClientId = historyItem.Data[DOWNLOAD_CLIENT_ID],
|
DownloadClientId = historyItem.Data[DOWNLOAD_CLIENT_ID],
|
||||||
Message = failedItem.Message
|
Message = message
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void Execute(FailedDownloadCommand message)
|
public void Execute(FailedDownloadCommand message)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,5 +9,7 @@ public interface IDownloadClient
|
||||||
bool IsConfigured { get; }
|
bool IsConfigured { get; }
|
||||||
IEnumerable<QueueItem> GetQueue();
|
IEnumerable<QueueItem> GetQueue();
|
||||||
IEnumerable<HistoryItem> GetHistory(int start = 0, int limit = 0);
|
IEnumerable<HistoryItem> GetHistory(int start = 0, int limit = 0);
|
||||||
|
void RemoveFromQueue(string id);
|
||||||
|
void RemoveFromHistory(string id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,22 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label">Redownload Failed</label>
|
<label class="control-label">Recycling Bin</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" name="recycleBin" class="x-path"/>
|
||||||
|
<span class="help-inline">
|
||||||
|
<i class="icon-nd-form-info" title="Episode files will go here when deleted instead of being permanently deleted"/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset class="advanced-setting">
|
||||||
|
<legend>Failed Download Handling</legend>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label">Redownload</label>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<label class="checkbox toggle well">
|
<label class="checkbox toggle well">
|
||||||
|
@ -56,18 +71,27 @@
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<span class="help-inline-checkbox">
|
<span class="help-inline-checkbox">
|
||||||
<i class="icon-question-sign" title="Should NzbDrone automatically search for and attempt to download another release when a download fails?"/>
|
<i class="icon-question-sign" title="Automatically search for and attempt to download another release when a download fails?"/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label">Recycling Bin</label>
|
<label class="control-label">Remove</label>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" name="recycleBin" class="x-path"/>
|
<label class="checkbox toggle well">
|
||||||
<span class="help-inline">
|
<input type="checkbox" name="removeFailedDownloads"/>
|
||||||
<i class="icon-nd-form-info" title="Episode files will go here when deleted instead of being permanently deleted"/>
|
<p>
|
||||||
|
<span>Yes</span>
|
||||||
|
<span>No</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="btn btn-primary slide-button"/>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<span class="help-inline-checkbox">
|
||||||
|
<i class="icon-question-sign" title="Automatically remove failed downloads from history and encrypted downloads from queue?"/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue