Merge branch 'signalr' into develop

pull/3113/head
Keivan Beigi 11 years ago
commit 93481728cc

@ -52,9 +52,10 @@ module.exports = function (grunt) {
options:{
dumpLineNumbers : 'false',
compress : false,
compress : true,
yuicompress : false,
ieCompat : false
ieCompat : true,
strictImports : true
},
bootstrap: {

@ -4,6 +4,7 @@ using FizzWare.NBuilder;
using FluentAssertions;
using Marr.Data;
using NUnit.Framework;
using NzbDrone.Api.Commands;
using NzbDrone.Api.Config;
using NzbDrone.Api.Episodes;
using NzbDrone.Api.History;
@ -15,14 +16,18 @@ using NzbDrone.Api.RootFolders;
using NzbDrone.Api.Series;
using NzbDrone.Api.Update;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.RootFolders;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Update;
using NzbDrone.Core.Update.Commands;
using NzbDrone.Test.Common;
using System.Linq;
@ -40,9 +45,9 @@ namespace NzbDrone.Api.Test.MappingTests
[TestCase(typeof(ParsedEpisodeInfo), typeof(ReleaseResource))]
[TestCase(typeof(DownloadDecision), typeof(ReleaseResource))]
[TestCase(typeof(Core.History.History), typeof(HistoryResource))]
[TestCase(typeof(UpdatePackage), typeof(UpdateResource))]
[TestCase(typeof(Quality), typeof(QualityResource))]
[TestCase(typeof(Log), typeof(LogResource))]
[TestCase(typeof(Command), typeof(CommandResource))]
public void matching_fields(Type modelType, Type resourceType)
{
MappingValidation.ValidateMapping(modelType, resourceType);
@ -116,6 +121,15 @@ namespace NzbDrone.Api.Test.MappingTests
profileResource.InjectTo<QualityProfile>();
}
[Test]
public void should_map_tracked_command()
{
var profileResource = new ApplicationUpdateCommand();
profileResource.InjectTo<CommandResource>();
}
}
public class ModelWithLazy

@ -1,42 +0,0 @@
using System;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Infrastructure;
using NzbDrone.Api.SignalR;
using NzbDrone.Common.Messaging;
using NzbDrone.Common.Messaging.Events;
using NzbDrone.Common.Messaging.Tracking;
namespace NzbDrone.Api.Commands
{
public class CommandConnection : NzbDronePersistentConnection,
IHandleAsync<CommandStartedEvent>,
IHandleAsync<CommandCompletedEvent>,
IHandleAsync<CommandFailedEvent>
{
public override string Resource
{
get { return "/Command"; }
}
public void HandleAsync(CommandStartedEvent message)
{
BroadcastMessage(message.TrackedCommand);
}
public void HandleAsync(CommandCompletedEvent message)
{
BroadcastMessage(message.TrackedCommand);
}
public void HandleAsync(CommandFailedEvent message)
{
BroadcastMessage(message.TrackedCommand);
}
private void BroadcastMessage(TrackedCommand trackedCommand)
{
var context = ((ConnectionManager)GlobalHost.ConnectionManager).GetConnection(GetType());
context.Connection.Broadcast(trackedCommand);
}
}
}

@ -1,47 +1,68 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Nancy;
using NzbDrone.Api.Extensions;
using NzbDrone.Api.Mapping;
using NzbDrone.Api.Validation;
using NzbDrone.Common.Composition;
using NzbDrone.Common.Messaging;
using NzbDrone.Common.Messaging.Tracking;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Tracking;
using NzbDrone.Core.ProgressMessaging;
namespace NzbDrone.Api.Commands
{
public class CommandModule : NzbDroneRestModule<CommandResource>
public class CommandModule : NzbDroneRestModuleWithSignalR<CommandResource, Command>, IHandle<CommandUpdatedEvent>
{
private readonly IMessageAggregator _messageAggregator;
private readonly IContainer _container;
private readonly ITrackCommands _trackCommands;
public CommandModule(IMessageAggregator messageAggregator, IContainer container, ITrackCommands trackCommands)
: base(messageAggregator)
{
_messageAggregator = messageAggregator;
_container = container;
_trackCommands = trackCommands;
Post["/"] = x => RunCommand(ReadResourceFromRequest());
Get["/"] = x => GetAllCommands();
GetResourceById = GetCommand;
CreateResource = StartCommand;
GetResourceAll = GetAllCommands;
PostValidator.RuleFor(c => c.Name).NotBlank();
}
private Response RunCommand(CommandResource resource)
private CommandResource GetCommand(int id)
{
return _trackCommands.GetById(id).InjectTo<CommandResource>();
}
private int StartCommand(CommandResource commandResource)
{
var commandType =
_container.GetImplementations(typeof(ICommand))
.Single(c => c.Name.Replace("Command", "")
.Equals(resource.Command, StringComparison.InvariantCultureIgnoreCase));
_container.GetImplementations(typeof(Command))
.Single(c => c.Name.Replace("Command", "")
.Equals(commandResource.Name, StringComparison.InvariantCultureIgnoreCase));
dynamic command = Request.Body.FromJson(commandType);
var response = (TrackedCommand) _messageAggregator.PublishCommandAsync(command);
var trackedCommand = (Command)_messageAggregator.PublishCommandAsync(command);
return trackedCommand.Id;
}
return response.AsResponse(HttpStatusCode.Created);
private List<CommandResource> GetAllCommands()
{
return ToListResource(_trackCommands.RunningCommands);
}
private Response GetAllCommands()
public void Handle(CommandUpdatedEvent message)
{
return _trackCommands.AllTracked().AsResponse();
if (message.Command.SendUpdatesToClient)
{
BroadcastResourceChange(ModelAction.Updated, message.Command.Id);
}
}
}
}

@ -1,9 +1,16 @@
using NzbDrone.Api.REST;
using System;
using NzbDrone.Api.REST;
using NzbDrone.Core.Messaging.Tracking;
namespace NzbDrone.Api.Commands
{
public class CommandResource : RestResource
{
public string Command { get; set; }
public String Name { get; set; }
public String Message { get; set; }
public DateTime StartedOn { get; set; }
public DateTime StateChangeTime { get; set; }
public Boolean SendUpdatesToClient { get; set; }
public CommandStatus State { get; set; }
}
}

@ -1,24 +0,0 @@
using System;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Infrastructure;
using NzbDrone.Api.SignalR;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Download;
using NzbDrone.Core.Tv;
namespace NzbDrone.Api.Episodes
{
public class EpisodeConnection : BasicResourceConnection<Episode>, IHandleAsync<EpisodeGrabbedEvent>
{
public override string Resource
{
get { return "/Episodes"; }
}
public void HandleAsync(EpisodeGrabbedEvent message)
{
var context = ((ConnectionManager)GlobalHost.ConnectionManager).GetConnection(GetType());
context.Connection.Broadcast(message);
}
}
}

@ -4,6 +4,7 @@ using NLog;
using NzbDrone.Api.Mapping;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Download;
using NzbDrone.Core.IndexerSearch;
using NzbDrone.Core.Indexers;

@ -7,9 +7,9 @@ using NzbDrone.Api.ErrorManagement;
using NzbDrone.Api.Extensions;
using NzbDrone.Api.Extensions.Pipelines;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.ProgressMessaging;
using TinyIoC;

@ -83,19 +83,14 @@
<Compile Include="ClientSchema\SelectOption.cs" />
<Compile Include="Commands\CommandModule.cs" />
<Compile Include="Commands\CommandResource.cs" />
<Compile Include="Commands\CommandConnection.cs" />
<Compile Include="Config\NamingConfigResource.cs" />
<Compile Include="Config\NamingModule.cs" />
<Compile Include="ProgressMessaging\ProgressMessageConnection.cs" />
<Compile Include="ProgressMessaging\ProgressMessageModule.cs" />
<Compile Include="ProgressMessaging\ProgressMessageResource.cs" />
<Compile Include="EpisodeFiles\EpisodeFileModule.cs" />
<Compile Include="EpisodeFiles\EpisodeFileResource.cs" />
<Compile Include="Directories\DirectoryLookupService.cs" />
<Compile Include="Directories\DirectoryModule.cs" />
<Compile Include="Episodes\EpisodeModule.cs" />
<Compile Include="Episodes\EpisodeResource.cs" />
<Compile Include="Episodes\EpisodeConnection.cs" />
<Compile Include="Extensions\Pipelines\CacheHeaderPipeline.cs" />
<Compile Include="Extensions\Pipelines\GZipPipeline.cs" />
<Compile Include="Extensions\Pipelines\IfModifiedPipeline.cs" />
@ -127,6 +122,8 @@
<Compile Include="Mapping\ValueInjectorExtensions.cs" />
<Compile Include="Missing\MissingModule.cs" />
<Compile Include="Config\NamingSampleResource.cs" />
<Compile Include="NzbDroneRestModuleWithSignalR.cs" />
<Compile Include="ResourceChangeMessage.cs" />
<Compile Include="Notifications\NotificationSchemaModule.cs" />
<Compile Include="Notifications\NotificationModule.cs" />
<Compile Include="Notifications\NotificationResource.cs" />
@ -139,8 +136,6 @@
<Compile Include="REST\RestResource.cs" />
<Compile Include="RootFolders\RootFolderModule.cs" />
<Compile Include="RootFolders\RootFolderResource.cs" />
<Compile Include="RootFolders\RootFolderConnection.cs" />
<Compile Include="Series\SeriesConnection.cs" />
<Compile Include="Series\SeriesResource.cs" />
<Compile Include="Series\SeriesModule.cs" />
<Compile Include="Series\SeriesLookupModule.cs" />
@ -158,11 +153,6 @@
<Compile Include="Qualities\QualitySizeModule.cs" />
<Compile Include="Extensions\ReqResExtensions.cs" />
<Compile Include="Config\SettingsModule.cs" />
<Compile Include="SignalR\BasicResourceConnection.cs" />
<Compile Include="SignalR\NoOpPerformanceCounterManager.cs" />
<Compile Include="SignalR\Serializer.cs" />
<Compile Include="SignalR\SignalrDependencyResolver.cs" />
<Compile Include="SignalR\NzbDronePersistentConnection.cs" />
<Compile Include="System\SystemModule.cs" />
<Compile Include="TinyIoCNancyBootstrapper.cs" />
<Compile Include="Update\UpdateModule.cs" />
@ -185,6 +175,10 @@
<Project>{ff5ee3b6-913b-47ce-9ceb-11c51b4e1205}</Project>
<Name>NzbDrone.Core</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.SignalR\NzbDrone.SignalR.csproj">
<Project>{7c2cc69f-5ca0-4e5c-85cb-983f9f6c3b36}</Project>
<Name>NzbDrone.SignalR</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
@ -196,4 +190,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>

@ -9,6 +9,8 @@ namespace NzbDrone.Api
{
public abstract class NzbDroneRestModule<TResource> : RestModule<TResource> where TResource : RestResource, new()
{
protected string Resource { get; private set; }
protected NzbDroneRestModule()
: this(new TResource().ResourceName)
{
@ -17,6 +19,7 @@ namespace NzbDrone.Api
protected NzbDroneRestModule(string resource)
: base("/api/" + resource.Trim('/'))
{
Resource = resource;
PostValidator.RuleFor(r => r.Id).IsZero();
PutValidator.RuleFor(r => r.Id).ValidId();
}
@ -28,7 +31,7 @@ namespace NzbDrone.Api
return model.Id;
}
protected List<TResource> ToListResource<TModel>(Func<IEnumerable<TModel>> function) where TModel : ModelBase, new()
protected List<TResource> ToListResource<TModel>(Func<IEnumerable<TModel>> function) where TModel : class
{
var modelList = function();
return modelList.InjectTo<List<TResource>>();

@ -0,0 +1,54 @@
using NzbDrone.Api.REST;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.Messaging;
using NzbDrone.SignalR;
namespace NzbDrone.Api
{
public abstract class NzbDroneRestModuleWithSignalR<TResource, TModel> : NzbDroneRestModule<TResource>, IHandle<ModelEvent<TModel>>
where TResource : RestResource, new()
where TModel : ModelBase
{
private readonly IMessageAggregator _messageAggregator;
protected NzbDroneRestModuleWithSignalR(IMessageAggregator messageAggregator)
{
_messageAggregator = messageAggregator;
}
public void Handle(ModelEvent<TModel> message)
{
if (message.Action == ModelAction.Deleted || message.Action == ModelAction.Sync)
{
BroadcastResourceChange(message.Action);
}
BroadcastResourceChange(message.Action, message.Model.Id);
}
protected void BroadcastResourceChange(ModelAction action, int id)
{
var resource = GetResourceById(id);
var signalRMessage = new SignalRMessage
{
Name = Resource,
Body = new ResourceChangeMessage<TResource>(resource, action)
};
_messageAggregator.PublishCommand(new BroadcastSignalRMessage(signalRMessage));
}
protected void BroadcastResourceChange(ModelAction action)
{
var signalRMessage = new SignalRMessage
{
Name = Resource,
Body = new ResourceChangeMessage<TResource>(action)
};
_messageAggregator.PublishCommand(new BroadcastSignalRMessage(signalRMessage));
}
}
}

@ -1,24 +0,0 @@
using System;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Infrastructure;
using NzbDrone.Api.SignalR;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.ProgressMessaging;
namespace NzbDrone.Api.ProgressMessaging
{
public class ProgressMessageConnection : NzbDronePersistentConnection,
IHandleAsync<NewProgressMessageEvent>
{
public override string Resource
{
get { return "/ProgressMessage"; }
}
public void HandleAsync(NewProgressMessageEvent message)
{
var context = ((ConnectionManager)GlobalHost.ConnectionManager).GetConnection(GetType());
context.Connection.Broadcast(message.ProgressMessage);
}
}
}

@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Nancy;
using NzbDrone.Api.Extensions;
namespace NzbDrone.Api.ProgressMessaging
{
public class ProgressMessageModule : NzbDroneRestModule<ProgressMessageResource>
{
public ProgressMessageModule()
{
Get["/"] = x => GetAllMessages();
}
private Response GetAllMessages()
{
return new List<ProgressMessageResource>().AsResponse();
}
}
}

@ -1,12 +0,0 @@
using System;
using NzbDrone.Api.REST;
namespace NzbDrone.Api.ProgressMessaging
{
public class ProgressMessageResource : RestResource
{
public DateTime Time { get; set; }
public String CommandId { get; set; }
public String Message { get; set; }
}
}

@ -61,7 +61,7 @@ namespace NzbDrone.Api.REST
protected Func<int, TResource> GetResourceById
{
private get { return _getResourceById; }
get { return _getResourceById; }
set
{
_getResourceById = value;

@ -0,0 +1,29 @@
using System;
using NzbDrone.Api.REST;
using NzbDrone.Core.Datastore.Events;
namespace NzbDrone.Api
{
public class ResourceChangeMessage<TResource> where TResource : RestResource
{
public TResource Resource { get; private set; }
public ModelAction Action { get; private set; }
public ResourceChangeMessage(ModelAction action)
{
if (action != ModelAction.Deleted || action != ModelAction.Sync)
{
throw new InvalidOperationException("Resource message without a resource needs to have Delete or Sync as action");
}
Action = action;
}
public ResourceChangeMessage(TResource resource, ModelAction action)
{
Resource = resource;
Action = action;
}
}
}

@ -1,13 +0,0 @@
using NzbDrone.Api.SignalR;
using NzbDrone.Core.RootFolders;
namespace NzbDrone.Api.RootFolders
{
public class RootFolderConnection : BasicResourceConnection<RootFolder>
{
public override string Resource
{
get { return "RootFolder"; }
}
}
}

@ -1,12 +0,0 @@
using NzbDrone.Api.SignalR;
namespace NzbDrone.Api.Series
{
public class SeriesConnection : BasicResourceConnection<Core.Tv.Series>
{
public override string Resource
{
get { return "/Series"; }
}
}
}

@ -1,37 +0,0 @@
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Infrastructure;
using NLog;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Events;
namespace NzbDrone.Api.SignalR
{
public abstract class BasicResourceConnection<T> :
NzbDronePersistentConnection,
IHandleAsync<ModelEvent<T>>
where T : ModelBase
{
private readonly Logger _logger;
public BasicResourceConnection()
{
_logger = NzbDroneLogger.GetLogger(this);
}
protected override Task OnConnected(IRequest request, string connectionId)
{
_logger.Trace("SignalR client connected. ID:{0}", connectionId);
return base.OnConnected(request, connectionId);
}
public void HandleAsync(ModelEvent<T> message)
{
var context = ((ConnectionManager)GlobalHost.ConnectionManager).GetConnection(GetType());
context.Connection.Broadcast(message);
}
}
}

@ -1,9 +0,0 @@
using Microsoft.AspNet.SignalR;
namespace NzbDrone.Api.SignalR
{
public abstract class NzbDronePersistentConnection : PersistentConnection
{
public abstract string Resource { get; }
}
}

@ -33,8 +33,6 @@ namespace NzbDrone.Api.Update
public class UpdateResource : RestResource
{
public String Id { get; set; }
[JsonConverter(typeof(Newtonsoft.Json.Converters.VersionConverter))]
public Version Version { get; set; }

@ -27,5 +27,10 @@ namespace NzbDrone.Api.Validation
{
return ruleBuilder.SetValidator(new PathValidator());
}
public static IRuleBuilderOptions<T, string> NotBlank<T>(this IRuleBuilder<T, string> ruleBuilder)
{
return ruleBuilder.SetValidator(new NotNullValidator()).SetValidator(new NotEmptyValidator(""));
}
}
}

@ -2,12 +2,12 @@
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Download;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Jobs;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
using NzbDrone.Host;
using NzbDrone.Test.Common;
using FluentAssertions;

@ -0,0 +1,20 @@
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Update.Commands;
namespace NzbDrone.Common.Test.MessagingTests
{
[TestFixture]
public class CommandBaseFixture
{
[Test]
public void default_values()
{
var command = new ApplicationUpdateCommand();
command.Id.Should().NotBe(0);
command.Name.Should().Be("ApplicationUpdate");
}
}
}

@ -1,12 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentAssertions;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.IndexerSearch;
using NzbDrone.Core.MediaFiles.Commands;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Common.Test.MessagingTests
{
@ -18,9 +15,8 @@ namespace NzbDrone.Common.Test.MessagingTests
{
var command1 = new DownloadedEpisodesScanCommand();
var command2 = new DownloadedEpisodesScanCommand();
var comparer = new CommandEqualityComparer();
comparer.Equals(command1, command2).Should().BeTrue();
CommandEqualityComparer.Instance.Equals(command1, command2).Should().BeTrue();
}
[Test]
@ -28,9 +24,8 @@ namespace NzbDrone.Common.Test.MessagingTests
{
var command1 = new EpisodeSearchCommand { EpisodeId = 1 };
var command2 = new EpisodeSearchCommand { EpisodeId = 1 };
var comparer = new CommandEqualityComparer();
comparer.Equals(command1, command2).Should().BeTrue();
CommandEqualityComparer.Instance.Equals(command1, command2).Should().BeTrue();
}
[Test]
@ -38,9 +33,8 @@ namespace NzbDrone.Common.Test.MessagingTests
{
var command1 = new SeasonSearchCommand { SeriesId = 1, SeasonNumber = 1 };
var command2 = new SeasonSearchCommand { SeriesId = 1, SeasonNumber = 1 };
var comparer = new CommandEqualityComparer();
comparer.Equals(command1, command2).Should().BeTrue();
CommandEqualityComparer.Instance.Equals(command1, command2).Should().BeTrue();
}
[Test]
@ -48,9 +42,8 @@ namespace NzbDrone.Common.Test.MessagingTests
{
var command1 = new EpisodeSearchCommand { EpisodeId = 1 };
var command2 = new EpisodeSearchCommand { EpisodeId = 2 };
var comparer = new CommandEqualityComparer();
comparer.Equals(command1, command2).Should().BeFalse();
CommandEqualityComparer.Instance.Equals(command1, command2).Should().BeFalse();
}
[Test]
@ -58,9 +51,8 @@ namespace NzbDrone.Common.Test.MessagingTests
{
var command1 = new SeasonSearchCommand { SeriesId = 1, SeasonNumber = 1 };
var command2 = new SeasonSearchCommand { SeriesId = 1, SeasonNumber = 2 };
var comparer = new CommandEqualityComparer();
comparer.Equals(command1, command2).Should().BeFalse();
CommandEqualityComparer.Instance.Equals(command1, command2).Should().BeFalse();
}
[Test]
@ -68,9 +60,8 @@ namespace NzbDrone.Common.Test.MessagingTests
{
var command1 = new SeasonSearchCommand { SeriesId = 1, SeasonNumber = 1 };
var command2 = new SeasonSearchCommand { SeriesId = 2, SeasonNumber = 2 };
var comparer = new CommandEqualityComparer();
comparer.Equals(command1, command2).Should().BeFalse();
CommandEqualityComparer.Instance.Equals(command1, command2).Should().BeFalse();
}
}
}

@ -2,11 +2,12 @@
using System.Collections.Generic;
using Moq;
using NUnit.Framework;
using NzbDrone.Common.Messaging;
using NzbDrone.Common.Messaging.Tracking;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Tracking;
using NzbDrone.Test.Common;
namespace NzbDrone.Common.Test.EventingTests
namespace NzbDrone.Common.Test.MessagingTests
{
[TestFixture]
public class MessageAggregatorCommandTests : TestBase<MessageAggregator>
@ -28,13 +29,10 @@ namespace NzbDrone.Common.Test.EventingTests
.Setup(c => c.Build(typeof(IExecute<CommandB>)))
.Returns(_executorB.Object);
Mocker.GetMock<ITrackCommands>()
.Setup(c => c.TrackIfNew(It.IsAny<CommandA>()))
.Returns(new TrackedCommand(new CommandA(), ProcessState.Running));
Mocker.GetMock<ITrackCommands>()
.Setup(c => c.TrackIfNew(It.IsAny<CommandB>()))
.Returns(new TrackedCommand(new CommandB(), ProcessState.Running));
.Setup(c => c.FindExisting(It.IsAny<Command>()))
.Returns<Command>(null);
}
[Test]
@ -42,10 +40,6 @@ namespace NzbDrone.Common.Test.EventingTests
{
var commandA = new CommandA();
Mocker.GetMock<ITrackCommands>()
.Setup(c => c.TrackIfNew(commandA))
.Returns(new TrackedCommand(commandA, ProcessState.Running));
Subject.PublishCommand(commandA);
_executorA.Verify(c => c.Execute(commandA), Times.Once());
@ -54,7 +48,7 @@ namespace NzbDrone.Common.Test.EventingTests
[Test]
public void should_publish_command_by_with_optional_arg_using_name()
{
Mocker.GetMock<IServiceFactory>().Setup(c => c.GetImplementations(typeof(ICommand)))
Mocker.GetMock<IServiceFactory>().Setup(c => c.GetImplementations(typeof(Command)))
.Returns(new List<Type> { typeof(CommandA), typeof(CommandB) });
Subject.PublishCommand(typeof(CommandA).FullName);
@ -67,10 +61,6 @@ namespace NzbDrone.Common.Test.EventingTests
{
var commandA = new CommandA();
Mocker.GetMock<ITrackCommands>()
.Setup(c => c.TrackIfNew(commandA))
.Returns(new TrackedCommand(commandA, ProcessState.Running));
Subject.PublishCommand(commandA);
_executorA.Verify(c => c.Execute(commandA), Times.Once());
@ -89,24 +79,18 @@ namespace NzbDrone.Common.Test.EventingTests
}
}
public class CommandA : ICommand
public class CommandA : Command
{
public String CommandId { get; private set; }
// ReSharper disable UnusedParameter.Local
public CommandA(int id = 0)
// ReSharper restore UnusedParameter.Local
{
CommandId = HashUtil.GenerateCommandId();
}
}
public class CommandB : ICommand
public class CommandB : Command
{
public String CommandId { get; private set; }
public CommandB()
{
CommandId = HashUtil.GenerateCommandId();
}
}

@ -1,13 +1,14 @@
using System;
using System.Collections.Generic;
using System.Threading;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Messaging;
using NzbDrone.Test.Common;
using FluentAssertions;
namespace NzbDrone.Common.Test.EventingTests
namespace NzbDrone.Common.Test.MessagingTests
{
[TestFixture]
public class MessageAggregatorEventTests : TestBase<MessageAggregator>
@ -127,7 +128,7 @@ namespace NzbDrone.Common.Test.EventingTests
counter.WaitForAllItems();
counter.MaxThreads.Should().Be(2);
counter.MaxThreads.Should().Be(3);
}
}

@ -67,8 +67,9 @@
<Compile Include="EnsureTest\PathExtensionFixture.cs" />
<Compile Include="EnvironmentTests\StartupArgumentsFixture.cs" />
<Compile Include="EnvironmentTests\EnvironmentProviderTest.cs" />
<Compile Include="EventingTests\MessageAggregatorCommandTests.cs" />
<Compile Include="EventingTests\MessageAggregatorEventTests.cs" />
<Compile Include="MessagingTests\CommandBaseFixture.cs" />
<Compile Include="MessagingTests\MessageAggregatorCommandTests.cs" />
<Compile Include="MessagingTests\MessageAggregatorEventTests.cs" />
<Compile Include="MessagingTests\CommandEqualityComparerFixture.cs" />
<Compile Include="ReflectionExtensions.cs" />
<Compile Include="PathExtensionFixture.cs" />

@ -2,8 +2,8 @@
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
using NzbDrone.Host;
using NzbDrone.Test.Common;

@ -25,8 +25,8 @@ namespace NzbDrone.Common
string[] GetFiles(string path, SearchOption searchOption);
long GetFolderSize(string path);
long GetFileSize(string path);
String CreateFolder(string path);
void CopyFolder(string source, string target);
void CreateFolder(string path);
void CopyFolder(string source, string destination);
void MoveFolder(string source, string destination);
void DeleteFile(string path);
void MoveFile(string source, string destination);
@ -37,7 +37,7 @@ namespace NzbDrone.Common
void WriteAllText(string filename, string contents);
void FileSetLastWriteTimeUtc(string path, DateTime dateTime);
void FolderSetLastWriteTimeUtc(string path, DateTime dateTime);
bool IsFileLocked(FileInfo file);
bool IsFileLocked(string path);
string GetPathRoot(string path);
void SetPermissions(string filename, WellKnownSidType accountSid, FileSystemRights rights, AccessControlType controlType);
bool IsParent(string parentPath, string childPath);
@ -60,7 +60,7 @@ namespace NzbDrone.Common
out ulong lpTotalNumberOfBytes,
out ulong lpTotalNumberOfFreeBytes);
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
public HashSet<string> SpecialFolders
{
@ -162,19 +162,18 @@ namespace NzbDrone.Common
return fi.Length;
}
public String CreateFolder(string path)
public void CreateFolder(string path)
{
Ensure.That(() => path).IsValidPath();
return Directory.CreateDirectory(path).FullName;
Directory.CreateDirectory(path);
}
public void CopyFolder(string source, string target)
public void CopyFolder(string source, string destination)
{
Ensure.That(() => source).IsValidPath();
Ensure.That(() => target).IsValidPath();
Ensure.That(() => destination).IsValidPath();
TransferFolder(source, target, TransferAction.Copy);
TransferFolder(source, destination, TransferAction.Copy);
}
public void MoveFolder(string source, string destination)
@ -367,13 +366,17 @@ namespace NzbDrone.Common
Directory.SetLastWriteTimeUtc(path, dateTime);
}
public bool IsFileLocked(FileInfo file)
public bool IsFileLocked(string file)
{
//TOOD: Needs test
//TODO: move to using instead of trycatch
//TODO: prob should use OpenWrite to check for lock.
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
stream = File.OpenRead(file);
}
catch (IOException)
{

@ -4,7 +4,6 @@ using Exceptron.Client;
using Exceptron.Client.Configuration;
using NLog;
using NLog.Common;
using NLog.Config;
using NLog.Layouts;
using NLog.Targets;
using NzbDrone.Common.EnvironmentInfo;
@ -23,9 +22,6 @@ namespace NzbDrone.Common.Instrumentation
/// </summary>
public IExceptronClient ExceptronClient { get; internal set; }
protected override void InitializeTarget()
{
var config = new ExceptronConfiguration

@ -1,53 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NLog;
using NzbDrone.Common.Messaging.Tracking;
namespace NzbDrone.Common.Instrumentation
{
public static class LoggerExtensions
{
public static void Progress(this Logger logger, string message)
{
LogProgressMessage(logger, message, ProcessState.Running);
}
public static void Progress(this Logger logger, string message, params object[] args)
{
var formattedMessage = String.Format(message, args);
Progress(logger, formattedMessage);
}
public static void Complete(this Logger logger, string message)
{
LogProgressMessage(logger, message, ProcessState.Completed);
}
public static void Complete(this Logger logger, string message, params object[] args)
{
var formattedMessage = String.Format(message, args);
Complete(logger, formattedMessage);
}
public static void Failed(this Logger logger, string message)
{
LogProgressMessage(logger, message, ProcessState.Failed);
}
public static void Failed(this Logger logger, string message, params object[] args)
{
var formattedMessage = String.Format(message, args);
Failed(logger, formattedMessage);
}
private static void LogProgressMessage(Logger logger, string message, ProcessState state)
{
var logEvent = new LogEventInfo(LogLevel.Info, logger.Name, message);
logEvent.Properties.Add("Status", state);
logger.Log(logEvent);
}
}
}

@ -1,44 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NzbDrone.Common.EnvironmentInfo;
namespace NzbDrone.Common.Messaging
{
public class CommandEqualityComparer : IEqualityComparer<ICommand>
{
public bool Equals(ICommand x, ICommand y)
{
var xProperties = x.GetType().GetProperties();
var yProperties = y.GetType().GetProperties();
foreach (var xProperty in xProperties)
{
if (xProperty.Name == "CommandId")
{
continue;
}
var yProperty = yProperties.SingleOrDefault(p => p.Name == xProperty.Name);
if (yProperty == null)
{
continue;
}
if (!xProperty.GetValue(x, null).Equals(yProperty.GetValue(y, null)))
{
return false;
}
}
return true;
}
public int GetHashCode(ICommand obj)
{
return obj.CommandId.GetHashCode();
}
}
}

@ -1,14 +0,0 @@
using NzbDrone.Common.Messaging.Tracking;
namespace NzbDrone.Common.Messaging.Events
{
public class CommandCompletedEvent : IEvent
{
public TrackedCommand TrackedCommand { get; private set; }
public CommandCompletedEvent(TrackedCommand trackedCommand)
{
TrackedCommand = trackedCommand;
}
}
}

@ -1,14 +0,0 @@
using NzbDrone.Common.Messaging.Tracking;
namespace NzbDrone.Common.Messaging.Events
{
public class CommandExecutedEvent : IEvent
{
public TrackedCommand TrackedCommand { get; private set; }
public CommandExecutedEvent(TrackedCommand trackedCommand)
{
TrackedCommand = trackedCommand;
}
}
}

@ -1,17 +0,0 @@
using System;
using NzbDrone.Common.Messaging.Tracking;
namespace NzbDrone.Common.Messaging.Events
{
public class CommandFailedEvent : IEvent
{
public TrackedCommand TrackedCommand { get; private set; }
public Exception Exception { get; private set; }
public CommandFailedEvent(TrackedCommand trackedCommand, Exception exception)
{
TrackedCommand = trackedCommand;
Exception = exception;
}
}
}

@ -1,14 +0,0 @@
using NzbDrone.Common.Messaging.Tracking;
namespace NzbDrone.Common.Messaging.Events
{
public class CommandStartedEvent : IEvent
{
public TrackedCommand TrackedCommand { get; private set; }
public CommandStartedEvent(TrackedCommand trackedCommand)
{
TrackedCommand = trackedCommand;
}
}
}

@ -1,10 +0,0 @@
using System;
using System.Collections.Generic;
namespace NzbDrone.Common.Messaging
{
public interface ICommand : IMessage
{
String CommandId { get; }
}
}

@ -1,4 +1,4 @@
namespace NzbDrone.Common.Messaging
namespace NzbDrone.Common.Messaging
{
public interface IEvent : IMessage
{

@ -1,15 +0,0 @@
using System;
namespace NzbDrone.Common.Messaging
{
public class TestCommand : ICommand
{
public int Duration { get; set; }
public String CommandId { get; private set; }
public TestCommand()
{
Duration = 4000;
}
}
}

@ -1,12 +0,0 @@
using System.Threading;
namespace NzbDrone.Common.Messaging
{
public class TestCommandExecutor : IExecute<TestCommand>
{
public void Execute(TestCommand message)
{
Thread.Sleep(message.Duration);
}
}
}

@ -1,127 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting;
using NzbDrone.Common.Cache;
namespace NzbDrone.Common.Messaging.Tracking
{
public interface ITrackCommands
{
TrackedCommand TrackIfNew(ICommand command);
ExistingCommand TrackNewOrGet(ICommand command);
TrackedCommand Completed(TrackedCommand trackedCommand, TimeSpan runtime);
TrackedCommand Failed(TrackedCommand trackedCommand, Exception e);
List<TrackedCommand> AllTracked();
Boolean ExistingCommand(ICommand command);
TrackedCommand FindExisting(ICommand command);
}
public class TrackCommands : ITrackCommands, IExecute<TrackedCommandCleanupCommand>
{
private readonly ICached<TrackedCommand> _cache;
public TrackCommands(ICacheManger cacheManger)
{
_cache = cacheManger.GetCache<TrackedCommand>(GetType());
}
public TrackedCommand TrackIfNew(ICommand command)
{
if (ExistingCommand(command))
{
return null;
}
var trackedCommand = new TrackedCommand(command, ProcessState.Running);
Store(trackedCommand);
return trackedCommand;
}
public ExistingCommand TrackNewOrGet(ICommand command)
{
var trackedCommand = FindExisting(command);
if (trackedCommand == null)
{
trackedCommand = new TrackedCommand(command, ProcessState.Running);
Store(trackedCommand);
return new ExistingCommand(false, trackedCommand);
}
return new ExistingCommand(true, trackedCommand);
}
public TrackedCommand Completed(TrackedCommand trackedCommand, TimeSpan runtime)
{
trackedCommand.StateChangeTime = DateTime.UtcNow;
trackedCommand.State = ProcessState.Completed;
trackedCommand.Runtime = runtime;
Store(trackedCommand);
return trackedCommand;
}
public TrackedCommand Failed(TrackedCommand trackedCommand, Exception e)
{
trackedCommand.StateChangeTime = DateTime.UtcNow;
trackedCommand.State = ProcessState.Failed;
trackedCommand.Exception = e;
Store(trackedCommand);
return trackedCommand;
}
public List<TrackedCommand> AllTracked()
{
return _cache.Values.ToList();
}
public bool ExistingCommand(ICommand command)
{
return FindExisting(command) != null;
}
public TrackedCommand FindExisting(ICommand command)
{
var comparer = new CommandEqualityComparer();
return Running(command.GetType()).SingleOrDefault(t => comparer.Equals(t.Command, command));
}
private List<TrackedCommand> Running(Type type = null)
{
var running = AllTracked().Where(i => i.State == ProcessState.Running);
if (type != null)
{
return running.Where(t => t.Type == type.FullName).ToList();
}
return running.ToList();
}
private void Store(TrackedCommand trackedCommand)
{
if (trackedCommand.Command.GetType() == typeof(TrackedCommandCleanupCommand))
{
return;
}
_cache.Set(trackedCommand.Command.CommandId, trackedCommand);
}
public void Execute(TrackedCommandCleanupCommand message)
{
var old = AllTracked().Where(c => c.State != ProcessState.Running && c.StateChangeTime < DateTime.UtcNow.AddMinutes(-5));
foreach (var trackedCommand in old)
{
_cache.Remove(trackedCommand.Command.CommandId);
}
}
}
}

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NzbDrone.Common.Messaging.Tracking
{
public class ExistingCommand
{
public Boolean Existing { get; set; }
public TrackedCommand TrackedCommand { get; set; }
public ExistingCommand(Boolean exisitng, TrackedCommand trackedCommand)
{
Existing = exisitng;
TrackedCommand = trackedCommand;
}
}
}

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NzbDrone.Common.Messaging.Tracking
{
public enum ProcessState
{
Running,
Completed,
Failed
}
}

@ -1,30 +0,0 @@
using System;
namespace NzbDrone.Common.Messaging.Tracking
{
public class TrackedCommand
{
public String Id { get; private set; }
public String Name { get; private set; }
public String Type { get; private set; }
public ICommand Command { get; private set; }
public ProcessState State { get; set; }
public DateTime StateChangeTime { get; set; }
public TimeSpan Runtime { get; set; }
public Exception Exception { get; set; }
public TrackedCommand()
{
}
public TrackedCommand(ICommand command, ProcessState state)
{
Id = command.CommandId;
Name = command.GetType().Name;
Type = command.GetType().FullName;
Command = command;
State = state;
StateChangeTime = DateTime.UtcNow;
}
}
}

@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NzbDrone.Common.Messaging.Tracking
{
public class TrackedCommandCleanupCommand : ICommand
{
public string CommandId { get; private set; }
public TrackedCommandCleanupCommand()
{
CommandId = HashUtil.GenerateCommandId();
}
}
}

@ -92,16 +92,11 @@
<Compile Include="IEnumerableExtensions.cs" />
<Compile Include="Instrumentation\GlobalExceptionHandlers.cs" />
<Compile Include="Instrumentation\ExceptronTarget.cs" />
<Compile Include="Instrumentation\LogEventExtensions.cs" />
<Compile Include="Instrumentation\NzbDroneLogger.cs" />
<Compile Include="Instrumentation\LogTargets.cs" />
<Compile Include="Instrumentation\LoggerExtensions.cs" />
<Compile Include="Messaging\Tracking\ProcessState.cs" />
<Compile Include="Messaging\Tracking\CommandTrackingService.cs" />
<Compile Include="Messaging\Tracking\ExistingCommand.cs" />
<Compile Include="Messaging\Tracking\TrackedCommand.cs" />
<Compile Include="Messaging\Events\CommandStartedEvent.cs" />
<Compile Include="Messaging\CommandEqualityComparer.cs" />
<Compile Include="Messaging\Tracking\TrackedCommandCleanupCommand.cs" />
<Compile Include="Messaging\IEvent.cs" />
<Compile Include="Messaging\IMessage.cs" />
<Compile Include="PathEqualityComparer.cs" />
<Compile Include="Services.cs" />
<Compile Include="TPL\LimitedConcurrencyLevelTaskScheduler.cs" />
@ -109,20 +104,8 @@
<Compile Include="StringExtensions.cs" />
<Compile Include="EnsureThat\TypeParam.cs" />
<Compile Include="HashUtil.cs" />
<Compile Include="Instrumentation\LogEventExtensions.cs" />
<Compile Include="Instrumentation\LogglyTarget.cs" />
<Compile Include="Serializer\Json.cs" />
<Compile Include="Messaging\Events\CommandCompletedEvent.cs" />
<Compile Include="Messaging\Events\CommandExecutedEvent.cs" />
<Compile Include="Messaging\Events\CommandFailedEvent.cs" />
<Compile Include="Messaging\IExecute.cs" />
<Compile Include="Messaging\ICommand.cs" />
<Compile Include="Messaging\IMessage.cs" />
<Compile Include="Messaging\IProcessMessage.cs" />
<Compile Include="Messaging\MessageAggregator.cs" />
<Compile Include="Messaging\IEvent.cs" />
<Compile Include="Messaging\IMessageAggregator.cs" />
<Compile Include="Messaging\IHandle.cs" />
<Compile Include="Expansive\CircularReferenceException.cs" />
<Compile Include="Expansive\Expansive.cs" />
<Compile Include="Expansive\PatternStyle.cs" />
@ -130,9 +113,6 @@
<Compile Include="Expansive\TreeNode.cs" />
<Compile Include="Expansive\TreeNodeList.cs" />
<Compile Include="Instrumentation\VersionLayoutRenderer.cs" />
<Compile Include="Messaging\MessageExtensions.cs" />
<Compile Include="Messaging\TestCommand.cs" />
<Compile Include="Messaging\TestCommandExecutor.cs" />
<Compile Include="Reflection\ReflectionExtensions.cs" />
<Compile Include="ServiceFactory.cs" />
<Compile Include="HttpProvider.cs" />

@ -5,6 +5,7 @@ using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Download;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;

@ -4,6 +4,7 @@ using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Download;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;

@ -6,9 +6,10 @@ using FluentMigrator.Runner;
using Marr.Data;
using Moq;
using NUnit.Framework;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Migration.Framework;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Test.Framework
{

@ -75,7 +75,7 @@ namespace NzbDrone.Core.Test.MediaFiles
[Test]
public void should_skip_if_file_is_in_use_by_another_process()
{
Mocker.GetMock<IDiskProvider>().Setup(c => c.IsFileLocked(It.IsAny<FileInfo>()))
Mocker.GetMock<IDiskProvider>().Setup(c => c.IsFileLocked(It.IsAny<string>()))
.Returns(true);
Subject.Execute(new DownloadedEpisodesScanCommand());

@ -58,7 +58,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
Subject.IsSatisfiedBy(_localEpisode);
Mocker.GetMock<IDiskProvider>()
.Verify(v => v.IsFileLocked(It.IsAny<FileInfo>()), Times.Never());
.Verify(v => v.IsFileLocked(It.IsAny<string>()), Times.Never());
}
[Test]
@ -67,7 +67,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
GivenNewFile();
Mocker.GetMock<IDiskProvider>()
.Setup(s => s.IsFileLocked(It.IsAny<FileInfo>()))
.Setup(s => s.IsFileLocked(It.IsAny<string>()))
.Returns(true);
Subject.IsSatisfiedBy(_localEpisode).Should().BeFalse();
@ -79,7 +79,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
GivenNewFile();
Mocker.GetMock<IDiskProvider>()
.Setup(s => s.IsFileLocked(It.IsAny<FileInfo>()))
.Setup(s => s.IsFileLocked(It.IsAny<string>()))
.Returns(false);
Subject.IsSatisfiedBy(_localEpisode).Should().BeTrue();

@ -4,10 +4,10 @@ using FizzWare.NBuilder;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.EpisodeImport;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Test.Framework;

@ -3,11 +3,11 @@ using System.Linq;
using FizzWare.NBuilder;
using Moq;
using NUnit.Framework;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.Commands;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Test.MediaFiles

@ -1,22 +1,26 @@
using System;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Update;
using System.Linq;
namespace NzbDrone.Core.Test.UpdateTests
{
public class UpdatePackageProviderFixture : CoreTest<UpdatePackageProvider>
{
[Test]
public void should_get_list_of_available_updates()
public void no_update_when_version_higher()
{
UseRealHttp();
Subject.GetLatestUpdate("master", new Version(10,0)).Should().BeNull();
}
Mocker.GetMock<IConfigFileProvider>().SetupGet(c => c.Branch).Returns("master");
Subject.GetLatestUpdate().Should().BeNull();
[Test]
public void finds_update_when_version_lower()
{
UseRealHttp();
Subject.GetLatestUpdate("master", new Version(1, 0)).Should().NotBeNull();
}
}
}

@ -7,9 +7,10 @@ using System.Xml.Linq;
using NzbDrone.Common;
using NzbDrone.Common.Cache;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Configuration.Events;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Configuration
{

@ -1,6 +1,7 @@
using System.Linq;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Configuration
{

@ -2,11 +2,12 @@
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Configuration.Events;
using NzbDrone.Core.Download;
using NzbDrone.Core.Download.Clients.Nzbget;
using NzbDrone.Core.Download.Clients.Sabnzbd;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Configuration
{

@ -1,4 +1,5 @@
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Configuration.Events
{

@ -1,4 +1,5 @@
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Configuration.Events
{

@ -1,5 +1,6 @@
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.DataAugmentation.Scene
{

@ -2,8 +2,8 @@ using System;
using System.Linq;
using NLog;
using NzbDrone.Common.Cache;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Parser;
namespace NzbDrone.Core.DataAugmentation.Scene

@ -1,16 +1,12 @@
using System;
using NzbDrone.Common;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.DataAugmentation.Scene
{
public class UpdateSceneMappingCommand : ICommand
public class UpdateSceneMappingCommand : Command
{
public String CommandId { get; private set; }
public UpdateSceneMappingCommand()
{
CommandId = HashUtil.GenerateCommandId();
}
}
}

@ -4,9 +4,9 @@ using System.Linq;
using System.Linq.Expressions;
using Marr.Data;
using Marr.Data.QGen;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Common;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Datastore
@ -115,7 +115,6 @@ namespace NzbDrone.Core.Datastore
}
DataMapper.Insert(model);
PublishModelEvent(model, RepositoryAction.Created);
return model;
}
@ -222,22 +221,27 @@ namespace NzbDrone.Core.Datastore
DataMapper.Delete<TModel>(c => c.Id > 0);
}
private void PublishModelEvent(TModel model, RepositoryAction action)
protected void ModelCreated(TModel model)
{
if (PublishModelEvents)
{
_messageAggregator.PublishEvent(new ModelEvent<TModel>(model, action));
}
PublishModelEvent(model, ModelAction.Created);
}
protected virtual void OnModelChanged(IEnumerable<TModel> models)
protected void ModelUpdated(TModel model)
{
PublishModelEvent(model, ModelAction.Updated);
}
protected virtual void OnModelDeleted(IEnumerable<TModel> models)
protected void ModelDeleted(TModel model)
{
PublishModelEvent(model, ModelAction.Deleted);
}
private void PublishModelEvent(TModel model, ModelAction action)
{
if (PublishModelEvents)
{
_messageAggregator.PublishEvent(new ModelEvent<TModel>(model, action));
}
}
protected virtual bool PublishModelEvents

@ -1,40 +0,0 @@
using System.Collections.Generic;
using NzbDrone.Common.Cache;
using NzbDrone.Common.Messaging;
namespace NzbDrone.Core.Datastore
{
public abstract class CachedBasicRepository<TModel> : BasicRepository<TModel> where TModel : ModelBase, new()
{
private readonly ICacheManger _cacheManger;
protected CachedBasicRepository(IDatabase database, IMessageAggregator messageAggregator)
: base(database, messageAggregator)
{
_cacheManger = new CacheManger();
}
protected ICached<T> GetCache<T>(string name)
{
return _cacheManger.GetCache<T>(GetType(), name);
}
protected override void OnModelChanged(IEnumerable<TModel> models)
{
PurgeCache();
}
protected override void OnModelDeleted(IEnumerable<TModel> models)
{
PurgeCache();
}
private void PurgeCache()
{
foreach (var model in _cacheManger.Caches)
{
model.Clear();
}
}
}
}

@ -3,9 +3,9 @@ using System.Data.SQLite;
using Marr.Data;
using Marr.Data.Reflection;
using NzbDrone.Common.Composition;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Datastore.Migration.Framework;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Datastore

@ -2,23 +2,25 @@
namespace NzbDrone.Core.Datastore.Events
{
public class ModelEvent<T> : IEvent where T : ModelBase
public class ModelEvent <TModel> : IEvent
{
public T Model { get; set; }
public RepositoryAction Action { get; set; }
public TModel Model { get; set; }
public ModelAction Action { get; set; }
public ModelEvent(T model, RepositoryAction action)
public ModelEvent(TModel model, ModelAction action)
{
Model = model;
Action = action;
}
}
public enum RepositoryAction
public enum ModelAction
{
Unknow = 0,
Created = 1,
Updated = 2,
Deleted = 3
Deleted = 3,
Sync = 4
}

@ -0,0 +1,241 @@
using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Linq;
using System.Text.RegularExpressions;
using NLog;
namespace NzbDrone.Core.Datastore.Migration.Framework
{
public interface ISQLiteMigrationHelper
{
Dictionary<String, SQLiteMigrationHelper.SQLiteColumn> GetColumns(string tableName);
void CreateTable(string tableName, IEnumerable<SQLiteMigrationHelper.SQLiteColumn> values, IEnumerable<SQLiteMigrationHelper.SQLiteIndex> indexes);
void CopyData(string sourceTable, string destinationTable, IEnumerable<SQLiteMigrationHelper.SQLiteColumn> columns);
void DropTable(string tableName);
void RenameTable(string tableName, string newName);
List<T> GetDuplicates<T>(string tableName, string columnName);
SQLiteTransaction BeginTransaction();
List<SQLiteMigrationHelper.SQLiteIndex> GetIndexes(string tableName);
}
public class SQLiteMigrationHelper : ISQLiteMigrationHelper
{
private readonly SQLiteConnection _connection;
private static readonly Regex SchemaRegex = new Regex(@"['\""\[](?<name>\w+)['\""\]]\s(?<schema>[\w-\s]+)",
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
private static readonly Regex IndexRegex = new Regex(@"\(""(?<col>.*)""\s(?<direction>ASC|DESC)\)$",
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
public SQLiteMigrationHelper(IConnectionStringFactory connectionStringFactory, Logger logger)
{
try
{
_connection = new SQLiteConnection(connectionStringFactory.MainDbConnectionString);
_connection.Open();
}
catch (Exception e)
{
logger.ErrorException("Couldn't open database " + connectionStringFactory.MainDbConnectionString, e);
throw;
}
}
private string GetOriginalSql(string tableName)
{
var command =
new SQLiteCommand(string.Format("SELECT sql FROM sqlite_master WHERE type='table' AND name ='{0}'",
tableName));
command.Connection = _connection;
return (string)command.ExecuteScalar();
}
public Dictionary<String, SQLiteColumn> GetColumns(string tableName)
{
var originalSql = GetOriginalSql(tableName);
var matches = SchemaRegex.Matches(originalSql);
return matches.Cast<Match>().ToDictionary(
match => match.Groups["name"].Value.Trim(),
match => new SQLiteColumn
{
Name = match.Groups["name"].Value.Trim(),
Schema = match.Groups["schema"].Value.Trim()
});
}
private static IEnumerable<T> ReadArray<T>(SQLiteDataReader reader)
{
while (reader.Read())
{
yield return (T)Convert.ChangeType(reader[0], typeof(T));
}
}
public List<SQLiteIndex> GetIndexes(string tableName)
{
var command = new SQLiteCommand(string.Format("SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name ='{0}'", tableName));
command.Connection = _connection;
var reader = command.ExecuteReader();
var sqls = ReadArray<string>(reader).ToList();
var indexes = new List<SQLiteIndex>();
foreach (var indexSql in sqls)
{
var newIndex = new SQLiteIndex();
var matches = IndexRegex.Match(indexSql);
newIndex.Column = matches.Groups["col"].Value;
newIndex.Unique = indexSql.Contains("UNIQUE");
newIndex.Table = tableName;
indexes.Add(newIndex);
}
return indexes;
}
public void CreateTable(string tableName, IEnumerable<SQLiteColumn> values, IEnumerable<SQLiteIndex> indexes)
{
var columns = String.Join(",", values.Select(c => c.ToString()));
ExecuteNonQuery("CREATE TABLE [{0}] ({1})", tableName, columns);
foreach (var index in indexes)
{
ExecuteNonQuery("DROP INDEX {0}", index.IndexName);
ExecuteNonQuery(index.CreateSql(tableName));
}
}
public void CopyData(string sourceTable, string destinationTable, IEnumerable<SQLiteColumn> columns)
{
var originalCount = GetRowCount(sourceTable);
var columnsToTransfer = String.Join(",", columns.Select(c => c.Name));
var transferCommand = BuildCommand("INSERT INTO {0} SELECT {1} FROM {2};", destinationTable, columnsToTransfer, sourceTable);
transferCommand.ExecuteNonQuery();
var transferredRows = GetRowCount(destinationTable);
if (transferredRows != originalCount)
{
throw new ApplicationException(string.Format("Expected {0} rows to be copied from [{1}] to [{2}]. But only copied {3}", originalCount, sourceTable, destinationTable, transferredRows));
}
}
public void DropTable(string tableName)
{
var dropCommand = BuildCommand("DROP TABLE {0};", tableName);
dropCommand.ExecuteNonQuery();
}
public void RenameTable(string tableName, string newName)
{
var renameCommand = BuildCommand("ALTER TABLE {0} RENAME TO {1};", tableName, newName);
renameCommand.ExecuteNonQuery();
}
public Dictionary<int,T> GetDuplicates<T>(string tableName, string columnName)
{
var dupCommand = BuildCommand("select id, {0} from {1}", columnName, tableName);
var result = new Dictionary<int, T>();
using (var reader = dupCommand.ExecuteReader())
{
while (reader.Read())
{
}
}
return ReadArray<T>().ToList();
}
public int GetRowCount(string tableName)
{
var countCommand = BuildCommand("SELECT COUNT(*) FROM {0};", tableName);
return Convert.ToInt32(countCommand.ExecuteScalar());
}
public SQLiteTransaction BeginTransaction()
{
return _connection.BeginTransaction();
}
private SQLiteCommand BuildCommand(string format, params string[] args)
{
var command = new SQLiteCommand(string.Format(format, args));
command.Connection = _connection;
return command;
}
private void ExecuteNonQuery(string command, params string[] args)
{
var sqLiteCommand = new SQLiteCommand(string.Format(command, args))
{
Connection = _connection
};
sqLiteCommand.ExecuteNonQuery();
}
public class SQLiteColumn
{
public string Name { get; set; }
public string Schema { get; set; }
public override string ToString()
{
return string.Format("[{0}] {1}", Name, Schema);
}
}
public class SQLiteIndex
{
public string Column { get; set; }
public string Table { get; set; }
public bool Unique { get; set; }
public override string ToString()
{
return string.Format("[{0}] Unique: {1}", Column, Unique);
}
public string IndexName
{
get
{
return string.Format("IX_{0}_{1}", Table, Column);
}
}
public string CreateSql(string tableName)
{
return string.Format(@"CREATE UNIQUE INDEX ""{2}"" ON ""{0}"" (""{1}"" ASC)", tableName, Column, IndexName);
}
}
}
}

@ -2,9 +2,9 @@ using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Core.DecisionEngine.Specifications.Search;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Common.Serializer;
@ -44,12 +44,12 @@ namespace NzbDrone.Core.DecisionEngine
{
if (reports.Any())
{
_logger.Progress("Processing {0} reports", reports.Count);
_logger.ProgressInfo("Processing {0} reports", reports.Count);
}
else
{
_logger.Progress("No reports found");
_logger.ProgressInfo("No reports found");
}
var reportNumber = 1;
@ -57,7 +57,7 @@ namespace NzbDrone.Core.DecisionEngine
foreach (var report in reports)
{
DownloadDecision decision = null;
_logger.Progress("Processing report {0}/{1}", reportNumber, reports.Count);
_logger.ProgressTrace("Processing report {0}/{1}", reportNumber, reports.Count);
try
{

@ -2,7 +2,7 @@ using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine
namespace NzbDrone.Core.DecisionEngine.Specifications
{
public class DownloadDecision
{

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Download

@ -1,6 +1,7 @@
using NLog;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Download
@ -38,7 +39,7 @@ namespace NzbDrone.Core.Download
downloadClient.DownloadNzb(remoteEpisode);
_logger.Progress("Report sent to download client. {0}", downloadTitle);
_logger.ProgressInfo("Report sent to download client. {0}", downloadTitle);
_messageAggregator.PublishEvent(new EpisodeGrabbedEvent(remoteEpisode));
}
}

@ -1,4 +1,5 @@
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Download

@ -2,8 +2,8 @@
using System.Collections.Generic;
using System.Linq;
using Marr.Data.QGen;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.History

@ -3,10 +3,10 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using NLog;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Download;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.History

@ -1,17 +1,18 @@
using System;
using NzbDrone.Common;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.IndexerSearch
{
public class EpisodeSearchCommand : ICommand
public class EpisodeSearchCommand : Command
{
public String CommandId { get; private set; }
public int EpisodeId { get; set; }
public EpisodeSearchCommand()
public override bool SendUpdatesToClient
{
CommandId = HashUtil.GenerateCommandId();
get
{
return true;
}
}
}
}

@ -1,8 +1,9 @@
using System.Linq;
using NLog;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Download;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.IndexerSearch
{
@ -26,7 +27,7 @@ namespace NzbDrone.Core.IndexerSearch
var decisions = _nzbSearchService.EpisodeSearch(message.EpisodeId);
var downloaded = _downloadApprovedReports.DownloadApproved(decisions);
_logger.Complete("Episode search completed. {0} reports downloaded.", downloaded.Count);
_logger.ProgressInfo("Episode search completed. {0} reports downloaded.", downloaded.Count);
}
}
}

@ -6,8 +6,10 @@ using NLog;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Core.DataAugmentation.Scene;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv;
using System.Linq;
@ -131,7 +133,7 @@ namespace NzbDrone.Core.IndexerSearch
{
var indexers = _indexerService.GetAvailableIndexers().ToList();
_logger.Progress("Searching {0} indexers for {1}", indexers.Count, criteriaBase);
_logger.ProgressInfo("Searching {0} indexers for {1}", indexers.Count, criteriaBase);
var reports = new List<ReportInfo>();
var taskList = new List<Task>();

@ -1,18 +1,21 @@
using System;
using NzbDrone.Common;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.IndexerSearch
{
public class SeasonSearchCommand : ICommand
public class SeasonSearchCommand : Command
{
public String CommandId { get; private set; }
public int SeriesId { get; set; }
public int SeasonNumber { get; set; }
public SeasonSearchCommand()
public override bool SendUpdatesToClient
{
CommandId = HashUtil.GenerateCommandId();
get
{
return true;
}
}
}
}

@ -1,7 +1,8 @@
using NLog;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Download;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.IndexerSearch
{
@ -25,7 +26,7 @@ namespace NzbDrone.Core.IndexerSearch
var decisions = _nzbSearchService.SeasonSearch(message.SeriesId, message.SeasonNumber);
var downloaded = _downloadApprovedReports.DownloadApproved(decisions);
_logger.Complete("Season search completed. {0} reports downloaded.", downloaded.Count);
_logger.ProgressInfo("Season search completed. {0} reports downloaded.", downloaded.Count);
}
}
}

@ -1,17 +1,20 @@
using System;
using NzbDrone.Common;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.IndexerSearch
{
public class SeriesSearchCommand : ICommand
public class SeriesSearchCommand : Command
{
public String CommandId { get; private set; }
public int SeriesId { get; set; }
public SeriesSearchCommand()
public override bool SendUpdatesToClient
{
CommandId = HashUtil.GenerateCommandId();
get
{
return true;
}
}
}
}

@ -1,8 +1,9 @@
using System.Linq;
using NLog;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Download;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.IndexerSearch
@ -40,7 +41,7 @@ namespace NzbDrone.Core.IndexerSearch
downloadedCount += _downloadApprovedReports.DownloadApproved(decisions).Count;
}
_logger.Complete("Series search completed. {0} reports downloaded.", downloadedCount);
_logger.ProgressInfo("Series search completed. {0} reports downloaded.", downloadedCount);
}
}
}

@ -1,7 +1,8 @@
using System;
using System.Linq;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Indexers
{

@ -2,10 +2,10 @@
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Common.Messaging;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Indexers.Newznab;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
using Omu.ValueInjecter;
namespace NzbDrone.Core.Indexers

@ -1,4 +1,5 @@
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Indexers
{

@ -1,16 +1,20 @@
using System;
using NzbDrone.Common;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.Indexers
{
public class RssSyncCommand : ICommand
public class RssSyncCommand : Command
{
public String CommandId { get; private set; }
public RssSyncCommand()
public override bool SendUpdatesToClient
{
CommandId = HashUtil.GenerateCommandId();
get
{
return true;
}
}
}
}

@ -1,9 +1,10 @@
using System.Linq;
using NLog;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Indexers
{
@ -33,13 +34,13 @@ namespace NzbDrone.Core.Indexers
public void Sync()
{
_logger.Progress("Starting RSS Sync");
_logger.ProgressInfo("Starting RSS Sync");
var reports = _rssFetcherAndParser.Fetch();
var decisions = _downloadDecisionMaker.GetRssDecision(reports);
var downloaded = _downloadApprovedReports.DownloadApproved(decisions);
_logger.Complete("RSS Sync Completed. Reports found: {0}, Reports downloaded: {1}", reports.Count, downloaded.Count());
_logger.ProgressInfo("RSS Sync Completed. Reports found: {0}, Reports downloaded: {1}", reports.Count, downloaded.Count());
}
public void Execute(RssSyncCommand message)

@ -1,16 +1,18 @@
using System;
using NzbDrone.Common;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.Instrumentation.Commands
{
public class ClearLogCommand : ICommand
public class ClearLogCommand : Command
{
public String CommandId { get; private set; }
public ClearLogCommand()
public override bool SendUpdatesToClient
{
CommandId = HashUtil.GenerateCommandId();
get
{
return true;
}
}
}
}

@ -1,16 +1,18 @@
using System;
using NzbDrone.Common;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.Instrumentation.Commands
{
public class DeleteLogFilesCommand : ICommand
public class DeleteLogFilesCommand : Command
{
public String CommandId { get; private set; }
public DeleteLogFilesCommand()
public override bool SendUpdatesToClient
{
CommandId = HashUtil.GenerateCommandId();
get
{
return true;
}
}
}
}

@ -1,16 +1,11 @@
using System;
using NzbDrone.Common;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.Instrumentation.Commands
{
public class TrimLogCommand : ICommand
public class TrimLogCommand : Command
{
public String CommandId { get; private set; }
public TrimLogCommand()
{
CommandId = HashUtil.GenerateCommandId();
}
}
}

@ -3,8 +3,8 @@ using NLog.Config;
using NLog;
using NLog.Layouts;
using NLog.Targets;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Instrumentation
{

@ -5,8 +5,8 @@ using System.Linq;
using NLog;
using NzbDrone.Common;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Instrumentation.Commands;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Instrumentation
{

@ -1,6 +1,7 @@
using System;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Instrumentation
{

@ -1,7 +1,7 @@
using System;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Instrumentation.Commands;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Instrumentation
{

@ -0,0 +1,34 @@
using System;
using NLog;
namespace NzbDrone.Core.Instrumentation
{
public static class LoggerExtensions
{
public static void ProgressInfo(this Logger logger, string message, params object[] args)
{
var formattedMessage = String.Format(message, args);
LogProgressMessage(logger, LogLevel.Info, formattedMessage);
}
public static void ProgressDebug(this Logger logger, string message, params object[] args)
{
var formattedMessage = String.Format(message, args);
LogProgressMessage(logger, LogLevel.Debug, formattedMessage);
}
public static void ProgressTrace(this Logger logger, string message, params object[] args)
{
var formattedMessage = String.Format(message, args);
LogProgressMessage(logger, LogLevel.Trace, formattedMessage);
}
private static void LogProgressMessage(Logger logger, LogLevel level, string message)
{
var logEvent = new LogEventInfo(level, logger.Name, message);
logEvent.Properties.Add("Status", "");
logger.Log(logEvent);
}
}
}

@ -3,10 +3,10 @@ using System.Linq;
using NLog;
using NLog.Config;
using NLog.Targets;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Configuration.Events;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Instrumentation
{

@ -1,7 +1,8 @@
using System;
using System.Linq;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging;
namespace NzbDrone.Core.Jobs
{

@ -2,8 +2,8 @@
using System.Threading;
using System.Threading.Tasks;
using NLog;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
using Timer = System.Timers.Timer;
using NzbDrone.Common.TPL;

@ -2,15 +2,15 @@ using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Common.Messaging;
using NzbDrone.Common.Messaging.Events;
using NzbDrone.Common.Messaging.Tracking;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Configuration.Events;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Instrumentation.Commands;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.MediaFiles.Commands;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Messaging.Tracking;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Tv.Commands;
using NzbDrone.Core.Update.Commands;
@ -79,7 +79,7 @@ namespace NzbDrone.Core.Jobs
public void HandleAsync(CommandExecutedEvent message)
{
var scheduledTask = _scheduledTaskRepository.All().SingleOrDefault(c => c.TypeName == message.TrackedCommand.Command.GetType().FullName);
var scheduledTask = _scheduledTaskRepository.All().SingleOrDefault(c => c.TypeName == message.Command.GetType().FullName);
if (scheduledTask != null)
{

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save