diff --git a/src/NzbDrone.Api/Queue/QueueModule.cs b/src/NzbDrone.Api/Queue/QueueModule.cs index 39053d0fc..83c648f73 100644 --- a/src/NzbDrone.Api/Queue/QueueModule.cs +++ b/src/NzbDrone.Api/Queue/QueueModule.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using NzbDrone.Core.Datastore.Events; using NzbDrone.Core.Download.Pending; @@ -30,7 +30,7 @@ namespace NzbDrone.Api.Queue private IEnumerable GetQueueItems() { - var queue = _queueService.GetQueue(); + var queue = _queueService.GetQueue().Where(q => q.Series != null); var pending = _pendingReleaseService.GetPendingQueue(); return queue.Concat(pending); @@ -46,4 +46,4 @@ namespace NzbDrone.Api.Queue BroadcastResourceChange(ModelAction.Sync); } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/QueueSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/QueueSpecification.cs index dec8429c5..5973b3725 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/QueueSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/QueueSpecification.cs @@ -31,7 +31,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { 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()); foreach (var queueItem in matchingEpisode) diff --git a/src/NzbDrone.Core/Queue/QueueService.cs b/src/NzbDrone.Core/Queue/QueueService.cs index 0f417837c..e131fafe7 100644 --- a/src/NzbDrone.Core/Queue/QueueService.cs +++ b/src/NzbDrone.Core/Queue/QueueService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using NzbDrone.Common.Crypto; @@ -40,38 +40,29 @@ namespace NzbDrone.Core.Queue _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 MapQueue(TrackedDownload trackedDownload) { if (trackedDownload.RemoteEpisode.Episodes != null && trackedDownload.RemoteEpisode.Episodes.Any()) { foreach (var episode in trackedDownload.RemoteEpisode.Episodes) { - yield return MapEpisode(trackedDownload, episode); + yield return MapQueueItem(trackedDownload, episode); } } 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 { - Id = HashConverter.GetHashInt31(string.Format("trackedDownload-{0}-ep{1}", trackedDownload.DownloadItem.DownloadId, episode.Id)), Series = trackedDownload.RemoteEpisode.Series, Episode = episode, Quality = trackedDownload.RemoteEpisode.ParsedEpisodeInfo.Quality, - Title = trackedDownload.DownloadItem.Title, + Title = Parser.Parser.RemoveFileExtension(trackedDownload.DownloadItem.Title), Size = trackedDownload.DownloadItem.TotalSize, Sizeleft = trackedDownload.DownloadItem.RemainingSize, Timeleft = trackedDownload.DownloadItem.RemainingTime, @@ -86,6 +77,15 @@ namespace NzbDrone.Core.Queue 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) { queue.EstimatedCompletionTime = DateTime.UtcNow.Add(queue.Timeleft.Value); @@ -93,5 +93,13 @@ namespace NzbDrone.Core.Queue return queue; } + + public void Handle(TrackedDownloadRefreshedEvent message) + { + _queue = message.TrackedDownloads.OrderBy(c => c.DownloadItem.RemainingTime).SelectMany(MapQueue) + .ToList(); + + _eventAggregator.PublishEvent(new QueueUpdatedEvent()); + } } } diff --git a/src/Sonarr.Api.V3/Queue/QueueDetailsModule.cs b/src/Sonarr.Api.V3/Queue/QueueDetailsModule.cs index b88656517..1d5a4f118 100644 --- a/src/Sonarr.Api.V3/Queue/QueueDetailsModule.cs +++ b/src/Sonarr.Api.V3/Queue/QueueDetailsModule.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using NzbDrone.Core.Datastore.Events; @@ -38,7 +38,7 @@ namespace Sonarr.Api.V3.Queue 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) @@ -49,7 +49,7 @@ namespace Sonarr.Api.V3.Queue .Select(e => Convert.ToInt32(e)) .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); @@ -65,4 +65,4 @@ namespace Sonarr.Api.V3.Queue BroadcastResourceChange(ModelAction.Sync); } } -} \ No newline at end of file +} diff --git a/src/Sonarr.Api.V3/Queue/QueueModule.cs b/src/Sonarr.Api.V3/Queue/QueueModule.cs index 2046a079f..39c314ea5 100644 --- a/src/Sonarr.Api.V3/Queue/QueueModule.cs +++ b/src/Sonarr.Api.V3/Queue/QueueModule.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using NzbDrone.Common.Extensions; +using NzbDrone.Core.Configuration; using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore.Events; using NzbDrone.Core.Download.Pending; @@ -17,32 +18,39 @@ namespace Sonarr.Api.V3.Queue { private readonly IQueueService _queueService; 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) { _queueService = queueService; _pendingReleaseService = pendingReleaseService; + _configService = configService; GetResourcePaged = GetQueue; } private PagingResource GetQueue(PagingResource pagingResource) { var pagingSpec = pagingResource.MapToPagingSpec("timeleft", SortDirection.Ascending); + var includeUnknownSeriesItems = Request.GetBooleanQueryParameter("includeUnknownSeriesItems"); var includeSeries = Request.GetBooleanQueryParameter("includeSeries"); 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 GetQueue(PagingSpec pagingSpec) + private PagingSpec GetQueue(PagingSpec pagingSpec, bool includeUnknownSeriesItems) { var ascending = pagingSpec.SortDirection == SortDirection.Ascending; var orderByFunc = GetOrderByFunc(pagingSpec); var queue = _queueService.GetQueue(); + var filteredQueue = includeUnknownSeriesItems ? queue : queue.Where(q => q.Series != null); var pending = _pendingReleaseService.GetPendingQueue(); - var fullQueue = queue.Concat(pending).ToList(); + var fullQueue = filteredQueue.Concat(pending).ToList(); IOrderedEnumerable ordered; if (pagingSpec.SortKey == "episode") diff --git a/src/Sonarr.Api.V3/Queue/QueueResource.cs b/src/Sonarr.Api.V3/Queue/QueueResource.cs index 02a1bc59a..a221eb978 100644 --- a/src/Sonarr.Api.V3/Queue/QueueResource.cs +++ b/src/Sonarr.Api.V3/Queue/QueueResource.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using NzbDrone.Core.Download.TrackedDownloads; @@ -12,8 +12,8 @@ namespace Sonarr.Api.V3.Queue { public class QueueResource : RestResource { - public int SeriesId { get; set; } - public int EpisodeId { get; set; } + public int? SeriesId { get; set; } + public int? EpisodeId { get; set; } public SeriesResource Series { get; set; } public EpisodeResource Episode { get; set; } public QualityModel Quality { get; set; } @@ -41,10 +41,10 @@ namespace Sonarr.Api.V3.Queue return new QueueResource { Id = model.Id, - SeriesId = model.Series.Id, - EpisodeId = model.Episode.Id, - Series = includeSeries ? model.Series.ToResource() : null, - Episode = includeEpisode ? model.Episode.ToResource() : null, + SeriesId = model.Series?.Id, + EpisodeId = model.Episode?.Id, + Series = includeSeries && model.Series != null ? model.Series.ToResource() : null, + Episode = includeEpisode && model.Episode != null ? model.Episode.ToResource() : null, Quality = model.Quality, Size = model.Size, Title = model.Title, diff --git a/src/Sonarr.Api.V3/Queue/QueueStatusModule.cs b/src/Sonarr.Api.V3/Queue/QueueStatusModule.cs index 6b22ed5fb..9720884be 100644 --- a/src/Sonarr.Api.V3/Queue/QueueStatusModule.cs +++ b/src/Sonarr.Api.V3/Queue/QueueStatusModule.cs @@ -47,6 +47,7 @@ namespace Sonarr.Api.V3.Queue var resource = new QueueStatusResource { Count = queue.Count + pending.Count, + UnknownCount = queue.Count(q => q.Series == null), Errors = queue.Any(q => q.TrackedDownloadStatus.Equals("Error", StringComparison.InvariantCultureIgnoreCase)), Warnings = queue.Any(q => q.TrackedDownloadStatus.Equals("Warning", StringComparison.InvariantCultureIgnoreCase)) }; diff --git a/src/Sonarr.Api.V3/Queue/QueueStatusResource.cs b/src/Sonarr.Api.V3/Queue/QueueStatusResource.cs index 022c2f295..77ec0c804 100644 --- a/src/Sonarr.Api.V3/Queue/QueueStatusResource.cs +++ b/src/Sonarr.Api.V3/Queue/QueueStatusResource.cs @@ -1,10 +1,11 @@ -using Sonarr.Http.REST; +using Sonarr.Http.REST; namespace Sonarr.Api.V3.Queue { public class QueueStatusResource : RestResource { public int Count { get; set; } + public int UnknownCount { get; set; } public bool Errors { get; set; } public bool Warnings { get; set; } }