1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2024-12-23 02:05:27 +02:00

New: Filter queue by status

Closes #7196
This commit is contained in:
Mark McDowall 2024-11-03 15:28:48 -08:00 committed by Mark McDowall
parent b8af3af9f1
commit fb540040ef
12 changed files with 116 additions and 11 deletions

View File

@ -13,6 +13,7 @@ import LanguageFilterBuilderRowValue from './LanguageFilterBuilderRowValue';
import ProtocolFilterBuilderRowValue from './ProtocolFilterBuilderRowValue'; import ProtocolFilterBuilderRowValue from './ProtocolFilterBuilderRowValue';
import QualityFilterBuilderRowValueConnector from './QualityFilterBuilderRowValueConnector'; import QualityFilterBuilderRowValueConnector from './QualityFilterBuilderRowValueConnector';
import QualityProfileFilterBuilderRowValue from './QualityProfileFilterBuilderRowValue'; import QualityProfileFilterBuilderRowValue from './QualityProfileFilterBuilderRowValue';
import QueueStatusFilterBuilderRowValue from './QueueStatusFilterBuilderRowValue';
import SeasonsMonitoredStatusFilterBuilderRowValue from './SeasonsMonitoredStatusFilterBuilderRowValue'; import SeasonsMonitoredStatusFilterBuilderRowValue from './SeasonsMonitoredStatusFilterBuilderRowValue';
import SeriesFilterBuilderRowValue from './SeriesFilterBuilderRowValue'; import SeriesFilterBuilderRowValue from './SeriesFilterBuilderRowValue';
import SeriesStatusFilterBuilderRowValue from './SeriesStatusFilterBuilderRowValue'; import SeriesStatusFilterBuilderRowValue from './SeriesStatusFilterBuilderRowValue';
@ -80,6 +81,9 @@ function getRowValueConnector(selectedFilterBuilderProp) {
case filterBuilderValueTypes.QUALITY_PROFILE: case filterBuilderValueTypes.QUALITY_PROFILE:
return QualityProfileFilterBuilderRowValue; return QualityProfileFilterBuilderRowValue;
case filterBuilderValueTypes.QUEUE_STATUS:
return QueueStatusFilterBuilderRowValue;
case filterBuilderValueTypes.SEASONS_MONITORED_STATUS: case filterBuilderValueTypes.SEASONS_MONITORED_STATUS:
return SeasonsMonitoredStatusFilterBuilderRowValue; return SeasonsMonitoredStatusFilterBuilderRowValue;

View File

@ -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 <FilterBuilderRowValue {...props} tagList={statusTagList} />;
}
export default QueueStatusFilterBuilderRowValue;

View File

@ -2,7 +2,7 @@ import React from 'react';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
import FilterBuilderRowValue from './FilterBuilderRowValue'; import FilterBuilderRowValue from './FilterBuilderRowValue';
const seriesStatusList = [ const statusTagList = [
{ {
id: 'continuing', id: 'continuing',
get name() { get name() {
@ -32,7 +32,7 @@ const seriesStatusList = [
function SeriesStatusFilterBuilderRowValue(props) { function SeriesStatusFilterBuilderRowValue(props) {
return ( return (
<FilterBuilderRowValue <FilterBuilderRowValue
tagList={seriesStatusList} tagList={statusTagList}
{...props} {...props}
/> />
); );

View File

@ -8,6 +8,7 @@ export const LANGUAGE = 'language';
export const PROTOCOL = 'protocol'; export const PROTOCOL = 'protocol';
export const QUALITY = 'quality'; export const QUALITY = 'quality';
export const QUALITY_PROFILE = 'qualityProfile'; export const QUALITY_PROFILE = 'qualityProfile';
export const QUEUE_STATUS = 'queueStatus';
export const SEASONS_MONITORED_STATUS = 'seasonsMonitoredStatus'; export const SEASONS_MONITORED_STATUS = 'seasonsMonitoredStatus';
export const SERIES = 'series'; export const SERIES = 'series';
export const SERIES_STATUS = 'seriesStatus'; export const SERIES_STATUS = 'seriesStatus';

View File

@ -212,6 +212,12 @@ export const defaultState = {
label: () => translate('Protocol'), label: () => translate('Protocol'),
type: filterBuilderTypes.EQUAL, type: filterBuilderTypes.EQUAL,
valueType: filterBuilderValueTypes.PROTOCOL valueType: filterBuilderValueTypes.PROTOCOL
},
{
name: 'status',
label: () => translate('Status'),
type: filterBuilderTypes.EQUAL,
valueType: filterBuilderValueTypes.QUEUE_STATUS
} }
] ]
} }

View File

@ -15,6 +15,7 @@
using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Profiles.Delay; using NzbDrone.Core.Profiles.Delay;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.Queue;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.Core.Tv.Events; using NzbDrone.Core.Tv.Events;
@ -389,7 +390,7 @@ private Queue.Queue GetQueueItem(PendingRelease pendingRelease, Lazy<DateTime> n
Timeleft = timeleft, Timeleft = timeleft,
EstimatedCompletionTime = ect, EstimatedCompletionTime = ect,
Added = pendingRelease.Added, Added = pendingRelease.Added,
Status = pendingRelease.Reason.ToString(), Status = Enum.TryParse(pendingRelease.Reason.ToString(), out QueueStatus outValue) ? outValue : QueueStatus.Unknown,
Protocol = pendingRelease.RemoteEpisode.Release.DownloadProtocol, Protocol = pendingRelease.RemoteEpisode.Release.DownloadProtocol,
Indexer = pendingRelease.RemoteEpisode.Release.Indexer, Indexer = pendingRelease.RemoteEpisode.Release.Indexer,
DownloadClient = downloadClientName DownloadClient = downloadClientName

View File

@ -323,6 +323,7 @@
"DefaultNameCopiedProfile": "{name} - Copy", "DefaultNameCopiedProfile": "{name} - Copy",
"DefaultNameCopiedSpecification": "{name} - Copy", "DefaultNameCopiedSpecification": "{name} - Copy",
"DefaultNotFoundMessage": "You must be lost, nothing to see here.", "DefaultNotFoundMessage": "You must be lost, nothing to see here.",
"Delay": "Delay",
"DelayMinutes": "{delay} Minutes", "DelayMinutes": "{delay} Minutes",
"DelayProfile": "Delay Profile", "DelayProfile": "Delay Profile",
"DelayProfileProtocol": "Protocol: {preferredProtocol}", "DelayProfileProtocol": "Protocol: {preferredProtocol}",
@ -541,6 +542,7 @@
"DownloadClientStatusSingleClientHealthCheckMessage": "Download clients unavailable due to failures: {downloadClientNames}", "DownloadClientStatusSingleClientHealthCheckMessage": "Download clients unavailable due to failures: {downloadClientNames}",
"DownloadClientTransmissionSettingsDirectoryHelpText": "Optional location to put downloads in, leave blank to use the default Transmission location", "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}'", "DownloadClientTransmissionSettingsUrlBaseHelpText": "Adds a prefix to the {clientName} rpc url, eg {url}, defaults to '{defaultUrl}'",
"DownloadClientUnavailable": "Download Client Unavailable",
"DownloadClientUTorrentTorrentStateError": "uTorrent is reporting an error", "DownloadClientUTorrentTorrentStateError": "uTorrent is reporting an error",
"DownloadClientValidationApiKeyIncorrect": "API Key Incorrect", "DownloadClientValidationApiKeyIncorrect": "API Key Incorrect",
"DownloadClientValidationApiKeyRequired": "API Key Required", "DownloadClientValidationApiKeyRequired": "API Key Required",
@ -689,6 +691,7 @@
"FailedToLoadTagsFromApi": "Failed to load tags from API", "FailedToLoadTagsFromApi": "Failed to load tags from API",
"FailedToLoadTranslationsFromApi": "Failed to load translations from API", "FailedToLoadTranslationsFromApi": "Failed to load translations from API",
"FailedToLoadUiSettingsFromApi": "Failed to load UI settings from API", "FailedToLoadUiSettingsFromApi": "Failed to load UI settings from API",
"Fallback": "Fallback",
"False": "False", "False": "False",
"FavoriteFolderAdd": "Add Favorite Folder", "FavoriteFolderAdd": "Add Favorite Folder",
"FavoriteFolderRemove": "Remove 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)", "WantMoreControlAddACustomFormat": "Want more control over which downloads are preferred? Add a [Custom Format](/settings/customformats)",
"Wanted": "Wanted", "Wanted": "Wanted",
"Warn": "Warn", "Warn": "Warn",
"Warning": "Warning",
"Week": "Week", "Week": "Week",
"WeekColumnHeader": "Week Column Header", "WeekColumnHeader": "Week Column Header",
"WeekColumnHeaderHelpText": "Shown above each column when week is the active view", "WeekColumnHeaderHelpText": "Shown above each column when week is the active view",

View File

@ -22,7 +22,7 @@ public class Queue : ModelBase
public TimeSpan? Timeleft { get; set; } public TimeSpan? Timeleft { get; set; }
public DateTime? EstimatedCompletionTime { get; set; } public DateTime? EstimatedCompletionTime { get; set; }
public DateTime? Added { get; set; } public DateTime? Added { get; set; }
public string Status { get; set; } public QueueStatus Status { get; set; }
public TrackedDownloadStatus? TrackedDownloadStatus { get; set; } public TrackedDownloadStatus? TrackedDownloadStatus { get; set; }
public TrackedDownloadState? TrackedDownloadState { get; set; } public TrackedDownloadState? TrackedDownloadState { get; set; }
public List<TrackedDownloadStatusMessage> StatusMessages { get; set; } public List<TrackedDownloadStatusMessage> StatusMessages { get; set; }

View File

@ -69,7 +69,7 @@ private Queue MapQueueItem(TrackedDownload trackedDownload, Episode episode)
Size = trackedDownload.DownloadItem.TotalSize, Size = trackedDownload.DownloadItem.TotalSize,
Sizeleft = trackedDownload.DownloadItem.RemainingSize, Sizeleft = trackedDownload.DownloadItem.RemainingSize,
Timeleft = trackedDownload.DownloadItem.RemainingTime, 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, TrackedDownloadStatus = trackedDownload.Status,
TrackedDownloadState = trackedDownload.State, TrackedDownloadState = trackedDownload.State,
StatusMessages = trackedDownload.StatusMessages.ToList(), StatusMessages = trackedDownload.StatusMessages.ToList(),

View File

@ -0,0 +1,16 @@
namespace NzbDrone.Core.Queue
{
public enum QueueStatus
{
Unknown,
Queued,
Paused,
Downloading,
Completed,
Failed,
Warning,
Delay,
DownloadClientUnavailable,
Fallback
}
}

View File

@ -136,7 +136,7 @@ public object RemoveMany([FromBody] QueueBulkResource resource, [FromQuery] bool
[HttpGet] [HttpGet]
[Produces("application/json")] [Produces("application/json")]
public PagingResource<QueueResource> 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<QueueResource> 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<QueueResource>(paging); var pagingResource = new PagingResource<QueueResource>(paging);
var pagingSpec = pagingResource.MapToPagingSpec<QueueResource, NzbDrone.Core.Queue.Queue>( var pagingSpec = pagingResource.MapToPagingSpec<QueueResource, NzbDrone.Core.Queue.Queue>(
@ -165,10 +165,10 @@ public PagingResource<QueueResource> GetQueue([FromQuery] PagingRequestResource
"timeleft", "timeleft",
SortDirection.Ascending); 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<NzbDrone.Core.Queue.Queue> GetQueue(PagingSpec<NzbDrone.Core.Queue.Queue> pagingSpec, HashSet<int> seriesIds, DownloadProtocol? protocol, HashSet<int> languages, HashSet<int> quality, bool includeUnknownSeriesItems) private PagingSpec<NzbDrone.Core.Queue.Queue> GetQueue(PagingSpec<NzbDrone.Core.Queue.Queue> pagingSpec, HashSet<int> seriesIds, DownloadProtocol? protocol, HashSet<int> languages, HashSet<int> quality, HashSet<QueueStatus> status, bool includeUnknownSeriesItems)
{ {
var ascending = pagingSpec.SortDirection == SortDirection.Ascending; var ascending = pagingSpec.SortDirection == SortDirection.Ascending;
var orderByFunc = GetOrderByFunc(pagingSpec); var orderByFunc = GetOrderByFunc(pagingSpec);
@ -180,6 +180,7 @@ public PagingResource<QueueResource> GetQueue([FromQuery] PagingRequestResource
var hasSeriesIdFilter = seriesIds.Any(); var hasSeriesIdFilter = seriesIds.Any();
var hasLanguageFilter = languages.Any(); var hasLanguageFilter = languages.Any();
var hasQualityFilter = quality.Any(); var hasQualityFilter = quality.Any();
var hasStatusFilter = status.Any();
var fullQueue = filteredQueue.Concat(pending).Where(q => var fullQueue = filteredQueue.Concat(pending).Where(q =>
{ {
@ -205,6 +206,11 @@ public PagingResource<QueueResource> GetQueue([FromQuery] PagingRequestResource
include &= quality.Contains(q.Quality.Quality.Id); include &= quality.Contains(q.Quality.Quality.Id);
} }
if (include && hasStatusFilter)
{
include &= status.Contains(q.Status);
}
return include; return include;
}).ToList(); }).ToList();

View File

@ -1,11 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Download.TrackedDownloads; using NzbDrone.Core.Download.TrackedDownloads;
using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers;
using NzbDrone.Core.Languages; using NzbDrone.Core.Languages;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.Queue;
using Sonarr.Api.V3.CustomFormats; using Sonarr.Api.V3.CustomFormats;
using Sonarr.Api.V3.Episodes; using Sonarr.Api.V3.Episodes;
using Sonarr.Api.V3.Series; using Sonarr.Api.V3.Series;
@ -30,7 +30,7 @@ public class QueueResource : RestResource
public TimeSpan? Timeleft { get; set; } public TimeSpan? Timeleft { get; set; }
public DateTime? EstimatedCompletionTime { get; set; } public DateTime? EstimatedCompletionTime { get; set; }
public DateTime? Added { get; set; } public DateTime? Added { get; set; }
public string Status { get; set; } public QueueStatus Status { get; set; }
public TrackedDownloadStatus? TrackedDownloadStatus { get; set; } public TrackedDownloadStatus? TrackedDownloadStatus { get; set; }
public TrackedDownloadState? TrackedDownloadState { get; set; } public TrackedDownloadState? TrackedDownloadState { get; set; }
public List<TrackedDownloadStatusMessage> StatusMessages { get; set; } public List<TrackedDownloadStatusMessage> StatusMessages { get; set; }
@ -74,7 +74,7 @@ public static QueueResource ToResource(this NzbDrone.Core.Queue.Queue model, boo
Timeleft = model.Timeleft, Timeleft = model.Timeleft,
EstimatedCompletionTime = model.EstimatedCompletionTime, EstimatedCompletionTime = model.EstimatedCompletionTime,
Added = model.Added, Added = model.Added,
Status = model.Status.FirstCharToLower(), Status = model.Status,
TrackedDownloadStatus = model.TrackedDownloadStatus, TrackedDownloadStatus = model.TrackedDownloadStatus,
TrackedDownloadState = model.TrackedDownloadState, TrackedDownloadState = model.TrackedDownloadState,
StatusMessages = model.StatusMessages, StatusMessages = model.StatusMessages,