Show unknown items in queue
New: Download items from unknown series now appear on the queue and can be imported with Manual Import.
This commit is contained in:
parent
5f6f4915a1
commit
de61ecbfd2
|
@ -1,4 +1,4 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Core.Datastore.Events;
|
using NzbDrone.Core.Datastore.Events;
|
||||||
using NzbDrone.Core.Download.Pending;
|
using NzbDrone.Core.Download.Pending;
|
||||||
|
@ -30,7 +30,7 @@ namespace NzbDrone.Api.Queue
|
||||||
|
|
||||||
private IEnumerable<Core.Queue.Queue> GetQueueItems()
|
private IEnumerable<Core.Queue.Queue> GetQueueItems()
|
||||||
{
|
{
|
||||||
var queue = _queueService.GetQueue();
|
var queue = _queueService.GetQueue().Where(q => q.Series != null);
|
||||||
var pending = _pendingReleaseService.GetPendingQueue();
|
var pending = _pendingReleaseService.GetPendingQueue();
|
||||||
|
|
||||||
return queue.Concat(pending);
|
return queue.Concat(pending);
|
||||||
|
@ -46,4 +46,4 @@ namespace NzbDrone.Api.Queue
|
||||||
BroadcastResourceChange(ModelAction.Sync);
|
BroadcastResourceChange(ModelAction.Sync);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
||||||
{
|
{
|
||||||
var queue = _queueService.GetQueue();
|
var queue = _queueService.GetQueue();
|
||||||
var matchingSeries = queue.Where(q => q.RemoteEpisode.Series.Id == subject.Series.Id);
|
var matchingSeries = queue.Where(q => q.RemoteEpisode.Series != null && q.RemoteEpisode.Series.Id == subject.Series.Id);
|
||||||
var matchingEpisode = matchingSeries.Where(q => q.RemoteEpisode.Episodes.Select(e => e.Id).Intersect(subject.Episodes.Select(e => e.Id)).Any());
|
var matchingEpisode = matchingSeries.Where(q => q.RemoteEpisode.Episodes.Select(e => e.Id).Intersect(subject.Episodes.Select(e => e.Id)).Any());
|
||||||
|
|
||||||
foreach (var queueItem in matchingEpisode)
|
foreach (var queueItem in matchingEpisode)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Common.Crypto;
|
using NzbDrone.Common.Crypto;
|
||||||
|
@ -40,38 +40,29 @@ namespace NzbDrone.Core.Queue
|
||||||
_queue.Remove(Find(id));
|
_queue.Remove(Find(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(TrackedDownloadRefreshedEvent message)
|
|
||||||
{
|
|
||||||
_queue = message.TrackedDownloads.OrderBy(c => c.DownloadItem.RemainingTime).SelectMany(MapQueue)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
_eventAggregator.PublishEvent(new QueueUpdatedEvent());
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<Queue> MapQueue(TrackedDownload trackedDownload)
|
private IEnumerable<Queue> MapQueue(TrackedDownload trackedDownload)
|
||||||
{
|
{
|
||||||
if (trackedDownload.RemoteEpisode.Episodes != null && trackedDownload.RemoteEpisode.Episodes.Any())
|
if (trackedDownload.RemoteEpisode.Episodes != null && trackedDownload.RemoteEpisode.Episodes.Any())
|
||||||
{
|
{
|
||||||
foreach (var episode in trackedDownload.RemoteEpisode.Episodes)
|
foreach (var episode in trackedDownload.RemoteEpisode.Episodes)
|
||||||
{
|
{
|
||||||
yield return MapEpisode(trackedDownload, episode);
|
yield return MapQueueItem(trackedDownload, episode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// FIXME: Present queue items with unknown series/episodes
|
yield return MapQueueItem(trackedDownload, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Queue MapEpisode(TrackedDownload trackedDownload, Episode episode)
|
private Queue MapQueueItem(TrackedDownload trackedDownload, Episode episode)
|
||||||
{
|
{
|
||||||
var queue = new Queue
|
var queue = new Queue
|
||||||
{
|
{
|
||||||
Id = HashConverter.GetHashInt31(string.Format("trackedDownload-{0}-ep{1}", trackedDownload.DownloadItem.DownloadId, episode.Id)),
|
|
||||||
Series = trackedDownload.RemoteEpisode.Series,
|
Series = trackedDownload.RemoteEpisode.Series,
|
||||||
Episode = episode,
|
Episode = episode,
|
||||||
Quality = trackedDownload.RemoteEpisode.ParsedEpisodeInfo.Quality,
|
Quality = trackedDownload.RemoteEpisode.ParsedEpisodeInfo.Quality,
|
||||||
Title = trackedDownload.DownloadItem.Title,
|
Title = Parser.Parser.RemoveFileExtension(trackedDownload.DownloadItem.Title),
|
||||||
Size = trackedDownload.DownloadItem.TotalSize,
|
Size = trackedDownload.DownloadItem.TotalSize,
|
||||||
Sizeleft = trackedDownload.DownloadItem.RemainingSize,
|
Sizeleft = trackedDownload.DownloadItem.RemainingSize,
|
||||||
Timeleft = trackedDownload.DownloadItem.RemainingTime,
|
Timeleft = trackedDownload.DownloadItem.RemainingTime,
|
||||||
|
@ -86,6 +77,15 @@ namespace NzbDrone.Core.Queue
|
||||||
Indexer = trackedDownload.Indexer
|
Indexer = trackedDownload.Indexer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (episode != null)
|
||||||
|
{
|
||||||
|
queue.Id = HashConverter.GetHashInt31(string.Format("trackedDownload-{0}-ep{1}", trackedDownload.DownloadItem.DownloadId, episode.Id));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
queue.Id = HashConverter.GetHashInt31(string.Format("trackedDownload-{0}", trackedDownload.DownloadItem.DownloadId));
|
||||||
|
}
|
||||||
|
|
||||||
if (queue.Timeleft.HasValue)
|
if (queue.Timeleft.HasValue)
|
||||||
{
|
{
|
||||||
queue.EstimatedCompletionTime = DateTime.UtcNow.Add(queue.Timeleft.Value);
|
queue.EstimatedCompletionTime = DateTime.UtcNow.Add(queue.Timeleft.Value);
|
||||||
|
@ -93,5 +93,13 @@ namespace NzbDrone.Core.Queue
|
||||||
|
|
||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Handle(TrackedDownloadRefreshedEvent message)
|
||||||
|
{
|
||||||
|
_queue = message.TrackedDownloads.OrderBy(c => c.DownloadItem.RemainingTime).SelectMany(MapQueue)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
_eventAggregator.PublishEvent(new QueueUpdatedEvent());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Core.Datastore.Events;
|
using NzbDrone.Core.Datastore.Events;
|
||||||
|
@ -38,7 +38,7 @@ namespace Sonarr.Api.V3.Queue
|
||||||
|
|
||||||
if (seriesIdQuery.HasValue)
|
if (seriesIdQuery.HasValue)
|
||||||
{
|
{
|
||||||
return fullQueue.Where(q => q.Series.Id == (int)seriesIdQuery).ToResource(includeSeries, includeEpisode);
|
return fullQueue.Where(q => q.Series?.Id == (int)seriesIdQuery).ToResource(includeSeries, includeEpisode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (episodeIdsQuery.HasValue)
|
if (episodeIdsQuery.HasValue)
|
||||||
|
@ -49,7 +49,7 @@ namespace Sonarr.Api.V3.Queue
|
||||||
.Select(e => Convert.ToInt32(e))
|
.Select(e => Convert.ToInt32(e))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
return fullQueue.Where(q => episodeIds.Contains(q.Episode.Id)).ToResource(includeSeries, includeEpisode);
|
return fullQueue.Where(q => q.Episode != null && episodeIds.Contains(q.Episode.Id)).ToResource(includeSeries, includeEpisode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fullQueue.ToResource(includeSeries, includeEpisode);
|
return fullQueue.ToResource(includeSeries, includeEpisode);
|
||||||
|
@ -65,4 +65,4 @@ namespace Sonarr.Api.V3.Queue
|
||||||
BroadcastResourceChange(ModelAction.Sync);
|
BroadcastResourceChange(ModelAction.Sync);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.Datastore.Events;
|
using NzbDrone.Core.Datastore.Events;
|
||||||
using NzbDrone.Core.Download.Pending;
|
using NzbDrone.Core.Download.Pending;
|
||||||
|
@ -17,32 +18,39 @@ namespace Sonarr.Api.V3.Queue
|
||||||
{
|
{
|
||||||
private readonly IQueueService _queueService;
|
private readonly IQueueService _queueService;
|
||||||
private readonly IPendingReleaseService _pendingReleaseService;
|
private readonly IPendingReleaseService _pendingReleaseService;
|
||||||
|
private readonly IConfigService _configService;
|
||||||
|
|
||||||
public QueueModule(IBroadcastSignalRMessage broadcastSignalRMessage, IQueueService queueService, IPendingReleaseService pendingReleaseService)
|
public QueueModule(IBroadcastSignalRMessage broadcastSignalRMessage,
|
||||||
|
IQueueService queueService,
|
||||||
|
IPendingReleaseService pendingReleaseService,
|
||||||
|
IConfigService configService)
|
||||||
: base(broadcastSignalRMessage)
|
: base(broadcastSignalRMessage)
|
||||||
{
|
{
|
||||||
_queueService = queueService;
|
_queueService = queueService;
|
||||||
_pendingReleaseService = pendingReleaseService;
|
_pendingReleaseService = pendingReleaseService;
|
||||||
|
_configService = configService;
|
||||||
GetResourcePaged = GetQueue;
|
GetResourcePaged = GetQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PagingResource<QueueResource> GetQueue(PagingResource<QueueResource> pagingResource)
|
private PagingResource<QueueResource> GetQueue(PagingResource<QueueResource> pagingResource)
|
||||||
{
|
{
|
||||||
var pagingSpec = pagingResource.MapToPagingSpec<QueueResource, NzbDrone.Core.Queue.Queue>("timeleft", SortDirection.Ascending);
|
var pagingSpec = pagingResource.MapToPagingSpec<QueueResource, NzbDrone.Core.Queue.Queue>("timeleft", SortDirection.Ascending);
|
||||||
|
var includeUnknownSeriesItems = Request.GetBooleanQueryParameter("includeUnknownSeriesItems");
|
||||||
var includeSeries = Request.GetBooleanQueryParameter("includeSeries");
|
var includeSeries = Request.GetBooleanQueryParameter("includeSeries");
|
||||||
var includeEpisode = Request.GetBooleanQueryParameter("includeEpisode");
|
var includeEpisode = Request.GetBooleanQueryParameter("includeEpisode");
|
||||||
|
|
||||||
return ApplyToPage(GetQueue, pagingSpec, (q) => MapToResource(q, includeSeries, includeEpisode));
|
return ApplyToPage((spec) => GetQueue(spec, includeUnknownSeriesItems), pagingSpec, (q) => MapToResource(q, includeSeries, includeEpisode));
|
||||||
}
|
}
|
||||||
|
|
||||||
private PagingSpec<NzbDrone.Core.Queue.Queue> GetQueue(PagingSpec<NzbDrone.Core.Queue.Queue> pagingSpec)
|
private PagingSpec<NzbDrone.Core.Queue.Queue> GetQueue(PagingSpec<NzbDrone.Core.Queue.Queue> pagingSpec, bool includeUnknownSeriesItems)
|
||||||
{
|
{
|
||||||
var ascending = pagingSpec.SortDirection == SortDirection.Ascending;
|
var ascending = pagingSpec.SortDirection == SortDirection.Ascending;
|
||||||
var orderByFunc = GetOrderByFunc(pagingSpec);
|
var orderByFunc = GetOrderByFunc(pagingSpec);
|
||||||
|
|
||||||
var queue = _queueService.GetQueue();
|
var queue = _queueService.GetQueue();
|
||||||
|
var filteredQueue = includeUnknownSeriesItems ? queue : queue.Where(q => q.Series != null);
|
||||||
var pending = _pendingReleaseService.GetPendingQueue();
|
var pending = _pendingReleaseService.GetPendingQueue();
|
||||||
var fullQueue = queue.Concat(pending).ToList();
|
var fullQueue = filteredQueue.Concat(pending).ToList();
|
||||||
IOrderedEnumerable<NzbDrone.Core.Queue.Queue> ordered;
|
IOrderedEnumerable<NzbDrone.Core.Queue.Queue> ordered;
|
||||||
|
|
||||||
if (pagingSpec.SortKey == "episode")
|
if (pagingSpec.SortKey == "episode")
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Core.Download.TrackedDownloads;
|
using NzbDrone.Core.Download.TrackedDownloads;
|
||||||
|
@ -12,8 +12,8 @@ namespace Sonarr.Api.V3.Queue
|
||||||
{
|
{
|
||||||
public class QueueResource : RestResource
|
public class QueueResource : RestResource
|
||||||
{
|
{
|
||||||
public int SeriesId { get; set; }
|
public int? SeriesId { get; set; }
|
||||||
public int EpisodeId { get; set; }
|
public int? EpisodeId { get; set; }
|
||||||
public SeriesResource Series { get; set; }
|
public SeriesResource Series { get; set; }
|
||||||
public EpisodeResource Episode { get; set; }
|
public EpisodeResource Episode { get; set; }
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
|
@ -41,10 +41,10 @@ namespace Sonarr.Api.V3.Queue
|
||||||
return new QueueResource
|
return new QueueResource
|
||||||
{
|
{
|
||||||
Id = model.Id,
|
Id = model.Id,
|
||||||
SeriesId = model.Series.Id,
|
SeriesId = model.Series?.Id,
|
||||||
EpisodeId = model.Episode.Id,
|
EpisodeId = model.Episode?.Id,
|
||||||
Series = includeSeries ? model.Series.ToResource() : null,
|
Series = includeSeries && model.Series != null ? model.Series.ToResource() : null,
|
||||||
Episode = includeEpisode ? model.Episode.ToResource() : null,
|
Episode = includeEpisode && model.Episode != null ? model.Episode.ToResource() : null,
|
||||||
Quality = model.Quality,
|
Quality = model.Quality,
|
||||||
Size = model.Size,
|
Size = model.Size,
|
||||||
Title = model.Title,
|
Title = model.Title,
|
||||||
|
|
|
@ -47,6 +47,7 @@ namespace Sonarr.Api.V3.Queue
|
||||||
var resource = new QueueStatusResource
|
var resource = new QueueStatusResource
|
||||||
{
|
{
|
||||||
Count = queue.Count + pending.Count,
|
Count = queue.Count + pending.Count,
|
||||||
|
UnknownCount = queue.Count(q => q.Series == null),
|
||||||
Errors = queue.Any(q => q.TrackedDownloadStatus.Equals("Error", StringComparison.InvariantCultureIgnoreCase)),
|
Errors = queue.Any(q => q.TrackedDownloadStatus.Equals("Error", StringComparison.InvariantCultureIgnoreCase)),
|
||||||
Warnings = queue.Any(q => q.TrackedDownloadStatus.Equals("Warning", StringComparison.InvariantCultureIgnoreCase))
|
Warnings = queue.Any(q => q.TrackedDownloadStatus.Equals("Warning", StringComparison.InvariantCultureIgnoreCase))
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
using Sonarr.Http.REST;
|
using Sonarr.Http.REST;
|
||||||
|
|
||||||
namespace Sonarr.Api.V3.Queue
|
namespace Sonarr.Api.V3.Queue
|
||||||
{
|
{
|
||||||
public class QueueStatusResource : RestResource
|
public class QueueStatusResource : RestResource
|
||||||
{
|
{
|
||||||
public int Count { get; set; }
|
public int Count { get; set; }
|
||||||
|
public int UnknownCount { get; set; }
|
||||||
public bool Errors { get; set; }
|
public bool Errors { get; set; }
|
||||||
public bool Warnings { get; set; }
|
public bool Warnings { get; set; }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue