You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Sonarr/src/NzbDrone.Api/Commands/CommandModule.cs

93 lines
3.1 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using Sonarr.Http.Extensions;
using NzbDrone.Common;
using NzbDrone.Common.TPL;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.ProgressMessaging;
using NzbDrone.SignalR;
using Sonarr.Http;
using Sonarr.Http.Validation;
namespace NzbDrone.Api.Commands
{
public class CommandModule : SonarrRestModuleWithSignalR<CommandResource, CommandModel>, IHandle<CommandUpdatedEvent>
{
private readonly IManageCommandQueue _commandQueueManager;
private readonly IServiceFactory _serviceFactory;
private readonly Debouncer _debouncer;
private readonly Dictionary<int, CommandResource> _pendingUpdates;
public CommandModule(IManageCommandQueue commandQueueManager,
IBroadcastSignalRMessage signalRBroadcaster,
IServiceFactory serviceFactory)
: base(signalRBroadcaster)
{
_commandQueueManager = commandQueueManager;
_serviceFactory = serviceFactory;
GetResourceById = GetCommand;
CreateResource = StartCommand;
GetResourceAll = GetStartedCommands;
PostValidator.RuleFor(c => c.Name).NotBlank();
_debouncer = new Debouncer(SendUpdates, TimeSpan.FromSeconds(0.1));
_pendingUpdates = new Dictionary<int, CommandResource>();
}
private CommandResource GetCommand(int id)
{
return _commandQueueManager.Get(id).ToResource();
}
private int StartCommand(CommandResource commandResource)
{
var commandType = _serviceFactory.GetImplementations(typeof(Command))
.Single(c => c.Name.Replace("Command", "").Equals(commandResource.Name, StringComparison.InvariantCultureIgnoreCase));
dynamic command = Request.Body.FromJson(commandType);
command.Trigger = CommandTrigger.Manual;
var trackedCommand = _commandQueueManager.Push(command, CommandPriority.Normal, CommandTrigger.Manual);
return trackedCommand.Id;
}
private List<CommandResource> GetStartedCommands()
{
return _commandQueueManager.GetStarted().ToResource();
}
public void Handle(CommandUpdatedEvent message)
{
if (message.Command.Body.SendUpdatesToClient)
{
lock (_pendingUpdates)
{
_pendingUpdates[message.Command.Id] = message.Command.ToResource();
}
_debouncer.Execute();
}
}
private void SendUpdates()
{
lock (_pendingUpdates)
{
var pendingUpdates = _pendingUpdates.Values.ToArray();
_pendingUpdates.Clear();
foreach (var pendingUpdate in pendingUpdates)
{
BroadcastResourceChange(ModelAction.Updated, pendingUpdate);
}
}
}
}
}