diff --git a/frontend/src/Components/Filter/Builder/FilterBuilderRow.js b/frontend/src/Components/Filter/Builder/FilterBuilderRow.js
index 7110dddf3..0b00c0f03 100644
--- a/frontend/src/Components/Filter/Builder/FilterBuilderRow.js
+++ b/frontend/src/Components/Filter/Builder/FilterBuilderRow.js
@@ -13,6 +13,7 @@ import LanguageFilterBuilderRowValue from './LanguageFilterBuilderRowValue';
import ProtocolFilterBuilderRowValue from './ProtocolFilterBuilderRowValue';
import QualityFilterBuilderRowValueConnector from './QualityFilterBuilderRowValueConnector';
import QualityProfileFilterBuilderRowValue from './QualityProfileFilterBuilderRowValue';
+import QueueStatusFilterBuilderRowValue from './QueueStatusFilterBuilderRowValue';
import SeasonsMonitoredStatusFilterBuilderRowValue from './SeasonsMonitoredStatusFilterBuilderRowValue';
import SeriesFilterBuilderRowValue from './SeriesFilterBuilderRowValue';
import SeriesStatusFilterBuilderRowValue from './SeriesStatusFilterBuilderRowValue';
@@ -80,6 +81,9 @@ function getRowValueConnector(selectedFilterBuilderProp) {
case filterBuilderValueTypes.QUALITY_PROFILE:
return QualityProfileFilterBuilderRowValue;
+ case filterBuilderValueTypes.QUEUE_STATUS:
+ return QueueStatusFilterBuilderRowValue;
+
case filterBuilderValueTypes.SEASONS_MONITORED_STATUS:
return SeasonsMonitoredStatusFilterBuilderRowValue;
diff --git a/frontend/src/Components/Filter/Builder/QueueStatusFilterBuilderRowValue.tsx b/frontend/src/Components/Filter/Builder/QueueStatusFilterBuilderRowValue.tsx
new file mode 100644
index 000000000..1127493a5
--- /dev/null
+++ b/frontend/src/Components/Filter/Builder/QueueStatusFilterBuilderRowValue.tsx
@@ -0,0 +1,67 @@
+import React from 'react';
+import translate from 'Utilities/String/translate';
+import FilterBuilderRowValue from './FilterBuilderRowValue';
+import FilterBuilderRowValueProps from './FilterBuilderRowValueProps';
+
+const statusTagList = [
+ {
+ id: 'queued',
+ get name() {
+ return translate('Queued');
+ },
+ },
+ {
+ id: 'paused',
+ get name() {
+ return translate('Paused');
+ },
+ },
+ {
+ id: 'downloading',
+ get name() {
+ return translate('Downloading');
+ },
+ },
+ {
+ id: 'completed',
+ get name() {
+ return translate('Completed');
+ },
+ },
+ {
+ id: 'failed',
+ get name() {
+ return translate('Failed');
+ },
+ },
+ {
+ id: 'warning',
+ get name() {
+ return translate('Warning');
+ },
+ },
+ {
+ id: 'delay',
+ get name() {
+ return translate('Delay');
+ },
+ },
+ {
+ id: 'downloadClientUnavailable',
+ get name() {
+ return translate('DownloadClientUnavailable');
+ },
+ },
+ {
+ id: 'fallback',
+ get name() {
+ return translate('Fallback');
+ },
+ },
+];
+
+function QueueStatusFilterBuilderRowValue(props: FilterBuilderRowValueProps) {
+ return ;
+}
+
+export default QueueStatusFilterBuilderRowValue;
diff --git a/frontend/src/Components/Filter/Builder/SeriesStatusFilterBuilderRowValue.js b/frontend/src/Components/Filter/Builder/SeriesStatusFilterBuilderRowValue.js
index 3464300f1..e017f72e7 100644
--- a/frontend/src/Components/Filter/Builder/SeriesStatusFilterBuilderRowValue.js
+++ b/frontend/src/Components/Filter/Builder/SeriesStatusFilterBuilderRowValue.js
@@ -2,7 +2,7 @@ import React from 'react';
import translate from 'Utilities/String/translate';
import FilterBuilderRowValue from './FilterBuilderRowValue';
-const seriesStatusList = [
+const statusTagList = [
{
id: 'continuing',
get name() {
@@ -32,7 +32,7 @@ const seriesStatusList = [
function SeriesStatusFilterBuilderRowValue(props) {
return (
);
diff --git a/frontend/src/Helpers/Props/filterBuilderValueTypes.js b/frontend/src/Helpers/Props/filterBuilderValueTypes.js
index d9a5d58c7..a6666ba03 100644
--- a/frontend/src/Helpers/Props/filterBuilderValueTypes.js
+++ b/frontend/src/Helpers/Props/filterBuilderValueTypes.js
@@ -8,6 +8,7 @@ export const LANGUAGE = 'language';
export const PROTOCOL = 'protocol';
export const QUALITY = 'quality';
export const QUALITY_PROFILE = 'qualityProfile';
+export const QUEUE_STATUS = 'queueStatus';
export const SEASONS_MONITORED_STATUS = 'seasonsMonitoredStatus';
export const SERIES = 'series';
export const SERIES_STATUS = 'seriesStatus';
diff --git a/frontend/src/Store/Actions/queueActions.js b/frontend/src/Store/Actions/queueActions.js
index 5f91318ad..ca97e5213 100644
--- a/frontend/src/Store/Actions/queueActions.js
+++ b/frontend/src/Store/Actions/queueActions.js
@@ -212,6 +212,12 @@ export const defaultState = {
label: () => translate('Protocol'),
type: filterBuilderTypes.EQUAL,
valueType: filterBuilderValueTypes.PROTOCOL
+ },
+ {
+ name: 'status',
+ label: () => translate('Status'),
+ type: filterBuilderTypes.EQUAL,
+ valueType: filterBuilderValueTypes.QUEUE_STATUS
}
]
}
diff --git a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs
index 8b6592f73..47d8d0755 100644
--- a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs
+++ b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs
@@ -15,6 +15,7 @@ using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Profiles.Delay;
using NzbDrone.Core.Qualities;
+using NzbDrone.Core.Queue;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Tv.Events;
@@ -389,7 +390,7 @@ namespace NzbDrone.Core.Download.Pending
Timeleft = timeleft,
EstimatedCompletionTime = ect,
Added = pendingRelease.Added,
- Status = pendingRelease.Reason.ToString(),
+ Status = Enum.TryParse(pendingRelease.Reason.ToString(), out QueueStatus outValue) ? outValue : QueueStatus.Unknown,
Protocol = pendingRelease.RemoteEpisode.Release.DownloadProtocol,
Indexer = pendingRelease.RemoteEpisode.Release.Indexer,
DownloadClient = downloadClientName
diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json
index 41969de5d..a478ad5b3 100644
--- a/src/NzbDrone.Core/Localization/Core/en.json
+++ b/src/NzbDrone.Core/Localization/Core/en.json
@@ -323,6 +323,7 @@
"DefaultNameCopiedProfile": "{name} - Copy",
"DefaultNameCopiedSpecification": "{name} - Copy",
"DefaultNotFoundMessage": "You must be lost, nothing to see here.",
+ "Delay": "Delay",
"DelayMinutes": "{delay} Minutes",
"DelayProfile": "Delay Profile",
"DelayProfileProtocol": "Protocol: {preferredProtocol}",
@@ -541,6 +542,7 @@
"DownloadClientStatusSingleClientHealthCheckMessage": "Download clients unavailable due to failures: {downloadClientNames}",
"DownloadClientTransmissionSettingsDirectoryHelpText": "Optional location to put downloads in, leave blank to use the default Transmission location",
"DownloadClientTransmissionSettingsUrlBaseHelpText": "Adds a prefix to the {clientName} rpc url, eg {url}, defaults to '{defaultUrl}'",
+ "DownloadClientUnavailable": "Download Client Unavailable",
"DownloadClientUTorrentTorrentStateError": "uTorrent is reporting an error",
"DownloadClientValidationApiKeyIncorrect": "API Key Incorrect",
"DownloadClientValidationApiKeyRequired": "API Key Required",
@@ -689,6 +691,7 @@
"FailedToLoadTagsFromApi": "Failed to load tags from API",
"FailedToLoadTranslationsFromApi": "Failed to load translations from API",
"FailedToLoadUiSettingsFromApi": "Failed to load UI settings from API",
+ "Fallback": "Fallback",
"False": "False",
"FavoriteFolderAdd": "Add Favorite Folder",
"FavoriteFolderRemove": "Remove Favorite Folder",
@@ -2114,6 +2117,7 @@
"WantMoreControlAddACustomFormat": "Want more control over which downloads are preferred? Add a [Custom Format](/settings/customformats)",
"Wanted": "Wanted",
"Warn": "Warn",
+ "Warning": "Warning",
"Week": "Week",
"WeekColumnHeader": "Week Column Header",
"WeekColumnHeaderHelpText": "Shown above each column when week is the active view",
diff --git a/src/NzbDrone.Core/Queue/Queue.cs b/src/NzbDrone.Core/Queue/Queue.cs
index c5d2a123a..c38749678 100644
--- a/src/NzbDrone.Core/Queue/Queue.cs
+++ b/src/NzbDrone.Core/Queue/Queue.cs
@@ -22,7 +22,7 @@ namespace NzbDrone.Core.Queue
public TimeSpan? Timeleft { get; set; }
public DateTime? EstimatedCompletionTime { get; set; }
public DateTime? Added { get; set; }
- public string Status { get; set; }
+ public QueueStatus Status { get; set; }
public TrackedDownloadStatus? TrackedDownloadStatus { get; set; }
public TrackedDownloadState? TrackedDownloadState { get; set; }
public List StatusMessages { get; set; }
diff --git a/src/NzbDrone.Core/Queue/QueueService.cs b/src/NzbDrone.Core/Queue/QueueService.cs
index 8bb11a13c..7142bd03c 100644
--- a/src/NzbDrone.Core/Queue/QueueService.cs
+++ b/src/NzbDrone.Core/Queue/QueueService.cs
@@ -69,7 +69,7 @@ namespace NzbDrone.Core.Queue
Size = trackedDownload.DownloadItem.TotalSize,
Sizeleft = trackedDownload.DownloadItem.RemainingSize,
Timeleft = trackedDownload.DownloadItem.RemainingTime,
- Status = trackedDownload.DownloadItem.Status.ToString(),
+ Status = Enum.TryParse(trackedDownload.DownloadItem.Status.ToString(), out QueueStatus outValue) ? outValue : QueueStatus.Unknown,
TrackedDownloadStatus = trackedDownload.Status,
TrackedDownloadState = trackedDownload.State,
StatusMessages = trackedDownload.StatusMessages.ToList(),
diff --git a/src/NzbDrone.Core/Queue/QueueStatus.cs b/src/NzbDrone.Core/Queue/QueueStatus.cs
new file mode 100644
index 000000000..77b0751d9
--- /dev/null
+++ b/src/NzbDrone.Core/Queue/QueueStatus.cs
@@ -0,0 +1,16 @@
+namespace NzbDrone.Core.Queue
+{
+ public enum QueueStatus
+ {
+ Unknown,
+ Queued,
+ Paused,
+ Downloading,
+ Completed,
+ Failed,
+ Warning,
+ Delay,
+ DownloadClientUnavailable,
+ Fallback
+ }
+}
diff --git a/src/Sonarr.Api.V3/Queue/QueueController.cs b/src/Sonarr.Api.V3/Queue/QueueController.cs
index 0fc12bb14..6c7438203 100644
--- a/src/Sonarr.Api.V3/Queue/QueueController.cs
+++ b/src/Sonarr.Api.V3/Queue/QueueController.cs
@@ -136,7 +136,7 @@ namespace Sonarr.Api.V3.Queue
[HttpGet]
[Produces("application/json")]
- public PagingResource GetQueue([FromQuery] PagingRequestResource paging, bool includeUnknownSeriesItems = false, bool includeSeries = false, bool includeEpisode = false, [FromQuery] int[] seriesIds = null, DownloadProtocol? protocol = null, [FromQuery] int[] languages = null, [FromQuery] int[] quality = null)
+ public PagingResource GetQueue([FromQuery] PagingRequestResource paging, bool includeUnknownSeriesItems = false, bool includeSeries = false, bool includeEpisode = false, [FromQuery] int[] seriesIds = null, DownloadProtocol? protocol = null, [FromQuery] int[] languages = null, [FromQuery] int[] quality = null, [FromQuery] QueueStatus[] status = null)
{
var pagingResource = new PagingResource(paging);
var pagingSpec = pagingResource.MapToPagingSpec(
@@ -165,10 +165,10 @@ namespace Sonarr.Api.V3.Queue
"timeleft",
SortDirection.Ascending);
- return pagingSpec.ApplyToPage((spec) => GetQueue(spec, seriesIds?.ToHashSet(), protocol, languages?.ToHashSet(), quality?.ToHashSet(), includeUnknownSeriesItems), (q) => MapToResource(q, includeSeries, includeEpisode));
+ return pagingSpec.ApplyToPage((spec) => GetQueue(spec, seriesIds?.ToHashSet(), protocol, languages?.ToHashSet(), quality?.ToHashSet(), status?.ToHashSet(), includeUnknownSeriesItems), (q) => MapToResource(q, includeSeries, includeEpisode));
}
- private PagingSpec GetQueue(PagingSpec pagingSpec, HashSet seriesIds, DownloadProtocol? protocol, HashSet languages, HashSet quality, bool includeUnknownSeriesItems)
+ private PagingSpec GetQueue(PagingSpec pagingSpec, HashSet seriesIds, DownloadProtocol? protocol, HashSet languages, HashSet quality, HashSet status, bool includeUnknownSeriesItems)
{
var ascending = pagingSpec.SortDirection == SortDirection.Ascending;
var orderByFunc = GetOrderByFunc(pagingSpec);
@@ -180,6 +180,7 @@ namespace Sonarr.Api.V3.Queue
var hasSeriesIdFilter = seriesIds.Any();
var hasLanguageFilter = languages.Any();
var hasQualityFilter = quality.Any();
+ var hasStatusFilter = status.Any();
var fullQueue = filteredQueue.Concat(pending).Where(q =>
{
@@ -205,6 +206,11 @@ namespace Sonarr.Api.V3.Queue
include &= quality.Contains(q.Quality.Quality.Id);
}
+ if (include && hasStatusFilter)
+ {
+ include &= status.Contains(q.Status);
+ }
+
return include;
}).ToList();
diff --git a/src/Sonarr.Api.V3/Queue/QueueResource.cs b/src/Sonarr.Api.V3/Queue/QueueResource.cs
index e5152f1d7..5a0e47e20 100644
--- a/src/Sonarr.Api.V3/Queue/QueueResource.cs
+++ b/src/Sonarr.Api.V3/Queue/QueueResource.cs
@@ -1,11 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using NzbDrone.Common.Extensions;
using NzbDrone.Core.Download.TrackedDownloads;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Qualities;
+using NzbDrone.Core.Queue;
using Sonarr.Api.V3.CustomFormats;
using Sonarr.Api.V3.Episodes;
using Sonarr.Api.V3.Series;
@@ -30,7 +30,7 @@ namespace Sonarr.Api.V3.Queue
public TimeSpan? Timeleft { get; set; }
public DateTime? EstimatedCompletionTime { get; set; }
public DateTime? Added { get; set; }
- public string Status { get; set; }
+ public QueueStatus Status { get; set; }
public TrackedDownloadStatus? TrackedDownloadStatus { get; set; }
public TrackedDownloadState? TrackedDownloadState { get; set; }
public List StatusMessages { get; set; }
@@ -74,7 +74,7 @@ namespace Sonarr.Api.V3.Queue
Timeleft = model.Timeleft,
EstimatedCompletionTime = model.EstimatedCompletionTime,
Added = model.Added,
- Status = model.Status.FirstCharToLower(),
+ Status = model.Status,
TrackedDownloadStatus = model.TrackedDownloadStatus,
TrackedDownloadState = model.TrackedDownloadState,
StatusMessages = model.StatusMessages,