New: Show processing time for pending items on Calendar and Queue

pull/3113/head
Mark McDowall 10 years ago
parent 3b26e82644
commit c21ffcb5e4

@ -1,7 +1,6 @@
using System; using System;
using NzbDrone.Api.REST; using NzbDrone.Api.REST;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv;
using NzbDrone.Api.Series; using NzbDrone.Api.Series;
using NzbDrone.Api.Episodes; using NzbDrone.Api.Episodes;
@ -16,6 +15,7 @@ namespace NzbDrone.Api.Queue
public String Title { get; set; } public String Title { get; set; }
public Decimal Sizeleft { get; set; } public Decimal Sizeleft { get; set; }
public TimeSpan? Timeleft { get; set; } public TimeSpan? Timeleft { get; set; }
public DateTime? EstimatedCompletionTime { get; set; }
public String Status { get; set; } public String Status { get; set; }
public String ErrorMessage { get; set; } public String ErrorMessage { get; set; }
} }

@ -29,21 +29,18 @@ namespace NzbDrone.Core.Download.Pending
private readonly IPendingReleaseRepository _repository; private readonly IPendingReleaseRepository _repository;
private readonly ISeriesService _seriesService; private readonly ISeriesService _seriesService;
private readonly IParsingService _parsingService; private readonly IParsingService _parsingService;
private readonly IDownloadService _downloadService;
private readonly IEventAggregator _eventAggregator; private readonly IEventAggregator _eventAggregator;
private readonly Logger _logger; private readonly Logger _logger;
public PendingReleaseService(IPendingReleaseRepository repository, public PendingReleaseService(IPendingReleaseRepository repository,
ISeriesService seriesService, ISeriesService seriesService,
IParsingService parsingService, IParsingService parsingService,
IDownloadService downloadService,
IEventAggregator eventAggregator, IEventAggregator eventAggregator,
Logger logger) Logger logger)
{ {
_repository = repository; _repository = repository;
_seriesService = seriesService; _seriesService = seriesService;
_parsingService = parsingService; _parsingService = parsingService;
_downloadService = downloadService;
_eventAggregator = eventAggregator; _eventAggregator = eventAggregator;
_logger = logger; _logger = logger;
} }
@ -141,6 +138,9 @@ namespace NzbDrone.Core.Download.Pending
{ {
foreach (var episode in pendingRelease.RemoteEpisode.Episodes) foreach (var episode in pendingRelease.RemoteEpisode.Episodes)
{ {
var ect = pendingRelease.Release.PublishDate.AddHours(
pendingRelease.RemoteEpisode.Series.Profile.Value.GrabDelay);
var queue = new Queue.Queue var queue = new Queue.Queue
{ {
Id = episode.Id ^ (pendingRelease.Id << 16), Id = episode.Id ^ (pendingRelease.Id << 16),
@ -150,10 +150,8 @@ namespace NzbDrone.Core.Download.Pending
Title = pendingRelease.Title, Title = pendingRelease.Title,
Size = pendingRelease.RemoteEpisode.Release.Size, Size = pendingRelease.RemoteEpisode.Release.Size,
Sizeleft = pendingRelease.RemoteEpisode.Release.Size, Sizeleft = pendingRelease.RemoteEpisode.Release.Size,
Timeleft = Timeleft = ect.Subtract(DateTime.UtcNow),
pendingRelease.Release.PublishDate.AddHours( EstimatedCompletionTime = ect,
pendingRelease.RemoteEpisode.Series.Profile.Value.GrabDelay)
.Subtract(DateTime.UtcNow),
Status = "Pending", Status = "Pending",
RemoteEpisode = pendingRelease.RemoteEpisode RemoteEpisode = pendingRelease.RemoteEpisode
}; };

@ -15,6 +15,7 @@ namespace NzbDrone.Core.Queue
public String Title { get; set; } public String Title { get; set; }
public Decimal Sizeleft { get; set; } public Decimal Sizeleft { get; set; }
public TimeSpan? Timeleft { get; set; } public TimeSpan? Timeleft { get; set; }
public DateTime? EstimatedCompletionTime { get; set; }
public String Status { get; set; } public String Status { get; set; }
public String ErrorMessage { get; set; } public String ErrorMessage { get; set; }
public RemoteEpisode RemoteEpisode { get; set; } public RemoteEpisode RemoteEpisode { get; set; }

@ -1,4 +1,5 @@
using System.Linq; using System;
using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using NLog; using NLog;
using NzbDrone.Core.Download; using NzbDrone.Core.Download;
@ -52,11 +53,16 @@ namespace NzbDrone.Core.Queue
RemoteEpisode = queueItem.DownloadItem.RemoteEpisode RemoteEpisode = queueItem.DownloadItem.RemoteEpisode
}; };
if (queueItem.HasError) if (queueItem.HasError)
{ {
queue.ErrorMessage = queueItem.StatusMessage; queue.ErrorMessage = queueItem.StatusMessage;
} }
if (queue.Timeleft.HasValue)
{
queue.EstimatedCompletionTime = DateTime.UtcNow.Add(queue.Timeleft.Value);
}
queued.Add(queue); queued.Add(queue);
} }
} }

@ -10,10 +10,11 @@ define(
'System/StatusModel', 'System/StatusModel',
'History/Queue/QueueCollection', 'History/Queue/QueueCollection',
'Config', 'Config',
'Shared/FormatHelpers',
'Mixins/backbone.signalr.mixin', 'Mixins/backbone.signalr.mixin',
'fullcalendar', 'fullcalendar',
'jquery.easypiechart' 'jquery.easypiechart'
], function ($, vent, Marionette, moment, CalendarCollection, StatusModel, QueueCollection, Config) { ], function ($, vent, Marionette, moment, CalendarCollection, StatusModel, QueueCollection, Config, FormatHelpers) {
return Marionette.ItemView.extend({ return Marionette.ItemView.extend({
storageKey: 'calendar.view', storageKey: 'calendar.view',
@ -62,6 +63,16 @@ define(
container: 'body' container: 'body'
}); });
} }
if (event.pending) {
this.$(element).find('.fc-event-time')
.after('<span class="pending pull-right"><i class="icon-time"></i></span>');
this.$(element).find('.pending').tooltip({
title: 'Release will be processed {0}'.format(event.pending),
container: 'body'
});
}
}, },
_getEvents: function (view) { _getEvents: function (view) {
@ -94,7 +105,9 @@ define(
allDay : false, allDay : false,
statusLevel : self._getStatusLevel(model, end), statusLevel : self._getStatusLevel(model, end),
progress : self._getDownloadProgress(model), progress : self._getDownloadProgress(model),
pending : self._getPendingInfo(model),
releaseTitle: self._getReleaseTitle(model), releaseTitle: self._getReleaseTitle(model),
downloading : QueueCollection.findEpisode(model.get('id')),
model : model model : model
}; };
@ -151,6 +164,16 @@ define(
return 100 - (downloading.get('sizeleft') / downloading.get('size') * 100); return 100 - (downloading.get('sizeleft') / downloading.get('size') * 100);
}, },
_getPendingInfo: function (element) {
var pending = QueueCollection.findEpisode(element.get('id'));
if (!pending || pending.get('status').toLocaleLowerCase() !== 'pending') {
return undefined;
}
return new moment(pending.get('estimatedCompletionTime')).fromNow();
},
_getReleaseTitle: function (element) { _getReleaseTitle: function (element) {
var downloading = QueueCollection.findEpisode(element.get('id')); var downloading = QueueCollection.findEpisode(element.get('id'));

@ -21,6 +21,10 @@
.fc-event { .fc-event {
.clickable; .clickable;
.pending {
margin-right : 4px;
}
} }
th { th {

@ -3,8 +3,9 @@
define( define(
[ [
'Cells/NzbDroneCell', 'Cells/NzbDroneCell',
'filesize' 'filesize',
], function (NzbDroneCell, fileSize) { 'moment'
], function (NzbDroneCell, fileSize, Moment) {
return NzbDroneCell.extend({ return NzbDroneCell.extend({
className: 'timeleft-cell', className: 'timeleft-cell',
@ -17,7 +18,7 @@ define(
//If the release is pending we want to use the timeleft as the time it will be processed at //If the release is pending we want to use the timeleft as the time it will be processed at
if (this.cellValue.get('status').toLowerCase() === 'pending') { if (this.cellValue.get('status').toLowerCase() === 'pending') {
this.$el.html('-'); this.$el.html('-');
this.$el.attr('title', 'Will be processed again in: {0}'.format(this.cellValue.get('timeleft'))); this.$el.attr('title', 'Will be processed {0}'.format(new Moment(this.cellValue.get('estimatedCompletionTime')).calendar()));
this.$el.attr('data-container', 'body'); this.$el.attr('data-container', 'body');
return this; return this;

Loading…
Cancel
Save