mirror of
https://github.com/Radarr/Radarr.git
synced 2024-11-10 04:52:42 +01:00
Merge branch 'develop'
Conflicts: NzbDrone.Core.Test/MetadataSourceTests/TraktProxyFixture.cs NzbDrone.Core/Jobs/TaskManager.cs NzbDrone.Core/MetadataSource/TraktProxy.cs NzbDrone.Core/Tv/SeasonService.cs NzbDrone.Integration.Test/SeasonIntegrationTests.cs
This commit is contained in:
commit
50b2aba5f9
@ -52,9 +52,10 @@ module.exports = function (grunt) {
|
||||
|
||||
options:{
|
||||
dumpLineNumbers : 'false',
|
||||
compress : false,
|
||||
compress : true,
|
||||
yuicompress : false,
|
||||
ieCompat : false
|
||||
ieCompat : true,
|
||||
strictImports : true
|
||||
},
|
||||
|
||||
bootstrap: {
|
||||
|
@ -28,8 +28,8 @@ public void schema_should_have_proper_fields()
|
||||
|
||||
var schema = SchemaBuilder.GenerateSchema(model);
|
||||
|
||||
schema.Should().Contain(c => c.Order == 1 && c.Name == "LastName" && c.Label == "Last Name" && c.HelpText == "Your Last Name" && c.Value == "Poop");
|
||||
schema.Should().Contain(c => c.Order == 0 && c.Name == "FirstName" && c.Label == "First Name" && c.HelpText == "Your First Name" && c.Value == "Bob");
|
||||
schema.Should().Contain(c => c.Order == 1 && c.Name == "LastName" && c.Label == "Last Name" && c.HelpText == "Your Last Name" && (string) c.Value == "Poop");
|
||||
schema.Should().Contain(c => c.Order == 0 && c.Name == "FirstName" && c.Label == "First Name" && c.HelpText == "Your First Name" && (string) c.Value == "Bob");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,9 +37,6 @@ public void Setup()
|
||||
"Windows"
|
||||
};
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.SetupGet(s => s.SpecialFolders)
|
||||
.Returns(new HashSet<string> { "$recycle.bin", "system volume information", "recycler" });
|
||||
}
|
||||
|
||||
private void SetupFolders(string root)
|
||||
|
@ -4,6 +4,7 @@
|
||||
using FluentAssertions;
|
||||
using Marr.Data;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Api.Commands;
|
||||
using NzbDrone.Api.Config;
|
||||
using NzbDrone.Api.Episodes;
|
||||
using NzbDrone.Api.History;
|
||||
@ -13,16 +14,16 @@
|
||||
using NzbDrone.Api.Qualities;
|
||||
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.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;
|
||||
|
||||
@ -36,13 +37,13 @@ public class ResourceMappingFixture : TestBase
|
||||
[TestCase(typeof(RootFolder), typeof(RootFolderResource))]
|
||||
[TestCase(typeof(NamingConfig), typeof(NamingConfigResource))]
|
||||
[TestCase(typeof(Indexer), typeof(IndexerResource))]
|
||||
[TestCase(typeof(ReportInfo), typeof(ReleaseResource))]
|
||||
[TestCase(typeof(ReleaseInfo), typeof(ReleaseResource))]
|
||||
[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 +117,15 @@ public void should_map_qualityprofile()
|
||||
profileResource.InjectTo<QualityProfile>();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_map_tracked_command()
|
||||
{
|
||||
var profileResource = new ApplicationUpdateCommand();
|
||||
profileResource.InjectTo<CommandResource>();
|
||||
}
|
||||
}
|
||||
|
||||
public class ModelWithLazy
|
||||
|
@ -1,37 +1,69 @@
|
||||
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.Core.Datastore.Events;
|
||||
using NzbDrone.Core.Messaging;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Messaging.Commands.Tracking;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
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 ICommandExecutor _commandExecutor;
|
||||
private readonly IContainer _container;
|
||||
private readonly ITrackCommands _trackCommands;
|
||||
|
||||
public CommandModule(IMessageAggregator messageAggregator, IContainer container)
|
||||
public CommandModule(ICommandExecutor commandExecutor, IContainer container, ITrackCommands trackCommands)
|
||||
: base(commandExecutor)
|
||||
{
|
||||
_messageAggregator = messageAggregator;
|
||||
_commandExecutor = commandExecutor;
|
||||
_container = container;
|
||||
_trackCommands = trackCommands;
|
||||
|
||||
Post["/"] = x => RunCommand(ReadResourceFromRequest());
|
||||
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))
|
||||
_container.GetImplementations(typeof(Command))
|
||||
.Single(c => c.Name.Replace("Command", "")
|
||||
.Equals(resource.Command, StringComparison.InvariantCultureIgnoreCase));
|
||||
.Equals(commandResource.Name, StringComparison.InvariantCultureIgnoreCase));
|
||||
|
||||
dynamic command = Request.Body.FromJson(commandType);
|
||||
_messageAggregator.PublishCommand(command);
|
||||
|
||||
return resource.AsResponse(HttpStatusCode.Created);
|
||||
var trackedCommand = (Command)_commandExecutor.PublishCommandAsync(command);
|
||||
return trackedCommand.Id;
|
||||
}
|
||||
|
||||
private List<CommandResource> GetAllCommands()
|
||||
{
|
||||
return ToListResource(_trackCommands.RunningCommands);
|
||||
}
|
||||
|
||||
public void Handle(CommandUpdatedEvent message)
|
||||
{
|
||||
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.Commands.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);
|
||||
}
|
||||
}
|
||||
}
|
@ -9,7 +9,6 @@ public abstract class ApiException : Exception
|
||||
{
|
||||
public object Content { get; private set; }
|
||||
|
||||
|
||||
public HttpStatusCode StatusCode { get; private set; }
|
||||
|
||||
protected ApiException(HttpStatusCode statusCode, object content = null)
|
||||
|
@ -3,6 +3,7 @@
|
||||
using NLog;
|
||||
using Nancy;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Core;
|
||||
using HttpStatusCode = Nancy.HttpStatusCode;
|
||||
|
||||
namespace NzbDrone.Api.ErrorManagement
|
||||
@ -35,9 +36,20 @@ public Response HandleException(NancyContext context, Exception exception)
|
||||
return validationException.Errors.AsResponse(HttpStatusCode.BadRequest);
|
||||
}
|
||||
|
||||
var clientException = exception as NzbDroneClientException;
|
||||
|
||||
if (clientException != null)
|
||||
{
|
||||
return new ErrorModel
|
||||
{
|
||||
Message = exception.Message,
|
||||
Description = exception.ToString()
|
||||
}.AsResponse((HttpStatusCode)clientException.StatusCode);
|
||||
}
|
||||
|
||||
_logger.FatalException("Request Failed", exception);
|
||||
|
||||
return new ErrorModel()
|
||||
return new ErrorModel
|
||||
{
|
||||
Message = exception.Message,
|
||||
Description = exception.ToString()
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Nancy;
|
||||
using Nancy;
|
||||
using Nancy.Bootstrapper;
|
||||
using NzbDrone.Api.Frontend;
|
||||
|
||||
|
@ -12,7 +12,6 @@ public static class ReqResExtensions
|
||||
{
|
||||
private static readonly NancyJsonSerializer NancySerializer = new NancyJsonSerializer();
|
||||
|
||||
|
||||
public static readonly string LastModified = BuildInfo.BuildDateTime.ToString("r");
|
||||
|
||||
public static T FromJson<T>(this Stream body) where T : class, new()
|
||||
@ -25,7 +24,6 @@ public static T FromJson<T>(this Stream body, Type type)
|
||||
return (T)FromJson(body, type);
|
||||
}
|
||||
|
||||
|
||||
public static object FromJson(this Stream body, Type type)
|
||||
{
|
||||
var reader = new StreamReader(body, true);
|
||||
|
@ -6,7 +6,6 @@
|
||||
using NzbDrone.Core.Indexers;
|
||||
using Omu.ValueInjecter;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Api.Mapping;
|
||||
|
||||
namespace NzbDrone.Api.Indexers
|
||||
|
@ -1,7 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using Nancy;
|
||||
using NLog;
|
||||
using NzbDrone.Api.Mapping;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.IndexerSearch;
|
||||
using NzbDrone.Core.Indexers;
|
||||
@ -40,7 +42,7 @@ public ReleaseModule(IFetchAndParseRss rssFetcherAndParser,
|
||||
private Response DownloadRelease(ReleaseResource release)
|
||||
{
|
||||
var remoteEpisode = _parsingService.Map(release.InjectTo<ParsedEpisodeInfo>(), 0);
|
||||
remoteEpisode.Report = release.InjectTo<ReportInfo>();
|
||||
remoteEpisode.Release = release.InjectTo<ReleaseInfo>();
|
||||
|
||||
_downloadService.DownloadReport(remoteEpisode);
|
||||
|
||||
@ -60,6 +62,7 @@ private List<ReleaseResource> GetReleases()
|
||||
private List<ReleaseResource> GetEpisodeReleases(int episodeId)
|
||||
{
|
||||
var decisions = _nzbSearchService.EpisodeSearch(episodeId);
|
||||
|
||||
return MapDecisions(decisions);
|
||||
}
|
||||
|
||||
@ -79,7 +82,7 @@ private static List<ReleaseResource> MapDecisions(IEnumerable<DownloadDecision>
|
||||
{
|
||||
var release = new ReleaseResource();
|
||||
|
||||
release.InjectFrom(downloadDecision.RemoteEpisode.Report);
|
||||
release.InjectFrom(downloadDecision.RemoteEpisode.Release);
|
||||
release.InjectFrom(downloadDecision.RemoteEpisode.ParsedEpisodeInfo);
|
||||
release.InjectFrom(downloadDecision);
|
||||
release.Rejections = downloadDecision.Rejections.ToList();
|
||||
|
@ -12,8 +12,6 @@ public class ReleaseResource : RestResource
|
||||
public Int32 Age { get; set; }
|
||||
public Int64 Size { get; set; }
|
||||
public String Indexer { get; set; }
|
||||
public String NzbInfoUrl { get; set; }
|
||||
public String NzbUrl { get; set; }
|
||||
public String ReleaseGroup { get; set; }
|
||||
public String Title { get; set; }
|
||||
public Boolean FullSeason { get; set; }
|
||||
@ -26,5 +24,9 @@ public class ReleaseResource : RestResource
|
||||
public Boolean Approved { get; set; }
|
||||
public Int32 TvRageId { get; set; }
|
||||
public List<string> Rejections { get; set; }
|
||||
public DateTime PublishDate { get; set; }
|
||||
public String CommentUrl { get; set; }
|
||||
public String DownloadUrl { get; set; }
|
||||
public String InfoUrl { get; set; }
|
||||
}
|
||||
}
|
@ -17,6 +17,12 @@ public LogModule(ILogService logService)
|
||||
private PagingResource<LogResource> GetLogs(PagingResource<LogResource> pagingResource)
|
||||
{
|
||||
var pageSpec = pagingResource.InjectTo<PagingSpec<Log>>();
|
||||
|
||||
if (pageSpec.SortKey == "time")
|
||||
{
|
||||
pageSpec.SortKey = "id";
|
||||
}
|
||||
|
||||
return ApplyToPage(_logService.Paged, pageSpec);
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,10 @@ protected override bool Match(ConventionInfo conventionInfo)
|
||||
|
||||
protected override object SetValue(ConventionInfo conventionInfo)
|
||||
{
|
||||
if (conventionInfo.SourceProp.Type.IsValueType || conventionInfo.SourceProp.Type == typeof(string))
|
||||
if (conventionInfo.SourceProp.Type == conventionInfo.TargetProp.Type)
|
||||
return conventionInfo.SourceProp.Value;
|
||||
|
||||
|
||||
if (conventionInfo.SourceProp.Type.IsArray)
|
||||
{
|
||||
var array = (Array)conventionInfo.SourceProp.Value;
|
||||
|
@ -1,14 +1,14 @@
|
||||
using System;
|
||||
using NLog;
|
||||
using NLog;
|
||||
using Nancy.Bootstrapper;
|
||||
using Nancy.Diagnostics;
|
||||
using NzbDrone.Api.Authentication;
|
||||
using NzbDrone.Api.ErrorManagement;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Api.Extensions.Pipelines;
|
||||
using NzbDrone.Common.Messaging;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
using NzbDrone.Core.Instrumentation;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Messaging;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using TinyIoC;
|
||||
|
||||
namespace NzbDrone.Api
|
||||
@ -21,20 +21,18 @@ public class NancyBootstrapper : TinyIoCNancyBootstrapper
|
||||
public NancyBootstrapper(TinyIoCContainer tinyIoCContainer)
|
||||
{
|
||||
_tinyIoCContainer = tinyIoCContainer;
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
_logger = NzbDroneLogger.GetLogger();
|
||||
}
|
||||
|
||||
protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
|
||||
{
|
||||
_logger.Info("Starting NzbDrone API");
|
||||
|
||||
|
||||
RegisterPipelines(pipelines);
|
||||
|
||||
container.Resolve<DatabaseTarget>().Register();
|
||||
container.Resolve<IEnableBasicAuthInNancy>().Register(pipelines);
|
||||
container.Resolve<IMessageAggregator>().PublishEvent(new ApplicationStartedEvent());
|
||||
|
||||
container.Resolve<IEventAggregator>().PublishEvent(new ApplicationStartedEvent());
|
||||
|
||||
ApplicationPipelines.OnError.AddItemToEndOfPipeline(container.Resolve<NzbDroneErrorPipeline>().HandleException);
|
||||
}
|
||||
@ -47,10 +45,8 @@ private void RegisterPipelines(IPipelines pipelines)
|
||||
{
|
||||
registerNancyPipeline.Register(pipelines);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected override TinyIoCContainer GetApplicationContainer()
|
||||
{
|
||||
return _tinyIoCContainer;
|
||||
|
@ -91,7 +91,6 @@
|
||||
<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" />
|
||||
@ -123,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" />
|
||||
@ -135,10 +136,6 @@
|
||||
<Compile Include="REST\RestResource.cs" />
|
||||
<Compile Include="RootFolders\RootFolderModule.cs" />
|
||||
<Compile Include="RootFolders\RootFolderResource.cs" />
|
||||
<Compile Include="RootFolders\RootFolderConnection.cs" />
|
||||
<Compile Include="Seasons\SeasonModule.cs" />
|
||||
<Compile Include="Seasons\SeasonResource.cs" />
|
||||
<Compile Include="Series\SeriesConnection.cs" />
|
||||
<Compile Include="Series\SeriesResource.cs" />
|
||||
<Compile Include="Series\SeriesModule.cs" />
|
||||
<Compile Include="Series\SeriesLookupModule.cs" />
|
||||
@ -156,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" />
|
||||
@ -183,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" />
|
||||
|
@ -1,8 +1,8 @@
|
||||
<ProjectConfiguration>
|
||||
<CopyReferencedAssembliesToWorkspace>false</CopyReferencedAssembliesToWorkspace>
|
||||
<ConsiderInconclusiveTestsAsPassing>false</ConsiderInconclusiveTestsAsPassing>
|
||||
<ConsiderInconclusiveTestsAsPassing>true</ConsiderInconclusiveTestsAsPassing>
|
||||
<PreloadReferencedAssemblies>false</PreloadReferencedAssemblies>
|
||||
<AllowDynamicCodeContractChecking>true</AllowDynamicCodeContractChecking>
|
||||
<AllowDynamicCodeContractChecking>false</AllowDynamicCodeContractChecking>
|
||||
<AllowStaticCodeContractChecking>false</AllowStaticCodeContractChecking>
|
||||
<IgnoreThisComponentCompletely>false</IgnoreThisComponentCompletely>
|
||||
<RunPreBuildEvents>false</RunPreBuildEvents>
|
||||
@ -12,9 +12,11 @@
|
||||
<PreventSigningOfAssembly>false</PreventSigningOfAssembly>
|
||||
<AnalyseExecutionTimes>true</AnalyseExecutionTimes>
|
||||
<IncludeStaticReferencesInWorkspace>true</IncludeStaticReferencesInWorkspace>
|
||||
<DefaultTestTimeout>60000</DefaultTestTimeout>
|
||||
<UseBuildConfiguration />
|
||||
<UseBuildPlatform />
|
||||
<ProxyProcessPath />
|
||||
<UseCPUArchitecture>AutoDetect</UseCPUArchitecture>
|
||||
<DefaultTestTimeout>5000</DefaultTestTimeout>
|
||||
<UseBuildConfiguration>Debug</UseBuildConfiguration>
|
||||
<UseBuildPlatform>x86</UseBuildPlatform>
|
||||
<ProxyProcessPath></ProxyProcessPath>
|
||||
<UseCPUArchitecture>x86</UseCPUArchitecture>
|
||||
<MSTestThreadApartmentState>STA</MSTestThreadApartmentState>
|
||||
<BuildProcessArchitecture>x86</BuildProcessArchitecture>
|
||||
</ProjectConfiguration>
|
@ -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 @@ protected NzbDroneRestModule()
|
||||
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 @@ protected NzbDroneRestModule(string resource)
|
||||
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>>();
|
||||
|
56
NzbDrone.Api/NzbDroneRestModuleWithSignalR.cs
Normal file
56
NzbDrone.Api/NzbDroneRestModuleWithSignalR.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Datastore.Events;
|
||||
using NzbDrone.Core.Messaging;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
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 ICommandExecutor _commandExecutor;
|
||||
|
||||
protected NzbDroneRestModuleWithSignalR(ICommandExecutor commandExecutor)
|
||||
{
|
||||
_commandExecutor = commandExecutor;
|
||||
}
|
||||
|
||||
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)
|
||||
};
|
||||
|
||||
_commandExecutor.PublishCommand(new BroadcastSignalRMessage(signalRMessage));
|
||||
}
|
||||
|
||||
protected void BroadcastResourceChange(ModelAction action)
|
||||
{
|
||||
var signalRMessage = new SignalRMessage
|
||||
{
|
||||
Name = Resource,
|
||||
Body = new ResourceChangeMessage<TResource>(action)
|
||||
};
|
||||
|
||||
_commandExecutor.PublishCommand(new BroadcastSignalRMessage(signalRMessage));
|
||||
}
|
||||
}
|
||||
}
|
@ -61,7 +61,7 @@ protected Action<int> DeleteResource
|
||||
|
||||
protected Func<int, TResource> GetResourceById
|
||||
{
|
||||
private get { return _getResourceById; }
|
||||
get { return _getResourceById; }
|
||||
set
|
||||
{
|
||||
_getResourceById = value;
|
||||
|
29
NzbDrone.Api/ResourceChangeMessage.cs
Normal file
29
NzbDrone.Api/ResourceChangeMessage.cs
Normal file
@ -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,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.RootFolders;
|
||||
using NzbDrone.Api.Mapping;
|
||||
using NzbDrone.Api.Validation;
|
||||
|
@ -1,53 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Api.Mapping;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Api.Seasons
|
||||
{
|
||||
public class SeasonModule : NzbDroneRestModule<SeasonResource>
|
||||
{
|
||||
private readonly ISeasonService _seasonService;
|
||||
|
||||
public SeasonModule(ISeasonService seasonService)
|
||||
: base("/season")
|
||||
{
|
||||
_seasonService = seasonService;
|
||||
|
||||
GetResourceAll = GetSeasons;
|
||||
GetResourceById = GetSeason;
|
||||
UpdateResource = Update;
|
||||
|
||||
Post["/pass"] = x => SetSeasonPass();
|
||||
}
|
||||
|
||||
private List<SeasonResource> GetSeasons()
|
||||
{
|
||||
var seriesId = Request.Query.SeriesId;
|
||||
|
||||
if (seriesId.HasValue)
|
||||
{
|
||||
return ToListResource<Season>(() => _seasonService.GetSeasonsBySeries(seriesId));
|
||||
}
|
||||
|
||||
return ToListResource(() => _seasonService.GetAllSeasons());
|
||||
}
|
||||
|
||||
private SeasonResource GetSeason(int id)
|
||||
{
|
||||
return _seasonService.Get(id).InjectTo<SeasonResource>();
|
||||
}
|
||||
|
||||
private void Update(SeasonResource seasonResource)
|
||||
{
|
||||
_seasonService.SetMonitored(seasonResource.SeriesId, seasonResource.SeasonNumber, seasonResource.Monitored);
|
||||
}
|
||||
|
||||
private List<SeasonResource> SetSeasonPass()
|
||||
{
|
||||
var seriesId = Request.Form.SeriesId;
|
||||
var seasonNumber = Request.Form.SeasonNumber;
|
||||
|
||||
return ToListResource<Season>(() => _seasonService.SetSeasonPass(seriesId, seasonNumber));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
using System;
|
||||
using NzbDrone.Api.REST;
|
||||
|
||||
namespace NzbDrone.Api.Seasons
|
||||
{
|
||||
public class SeasonResource : RestResource
|
||||
{
|
||||
public int SeriesId { get; set; }
|
||||
public int SeasonNumber { get; set; }
|
||||
public Boolean Monitored { get; set; }
|
||||
}
|
||||
}
|
@ -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"; }
|
||||
}
|
||||
}
|
||||
}
|
@ -117,7 +117,6 @@ private void LinkSeriesStatistics(SeriesResource resource, SeriesStatistics seri
|
||||
{
|
||||
resource.EpisodeCount = seriesStatistics.EpisodeCount;
|
||||
resource.EpisodeFileCount = seriesStatistics.EpisodeFileCount;
|
||||
resource.SeasonCount = seriesStatistics.SeasonCount;
|
||||
resource.NextAiring = seriesStatistics.NextAiring;
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,17 @@ public class SeriesResource : RestResource
|
||||
|
||||
//View Only
|
||||
public String Title { get; set; }
|
||||
public Int32 SeasonCount { get; set; }
|
||||
|
||||
public Int32 SeasonCount
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Seasons != null) return Seasons.Count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public Int32 EpisodeCount { get; set; }
|
||||
public Int32 EpisodeFileCount { get; set; }
|
||||
public SeriesStatusType Status { get; set; }
|
||||
@ -26,7 +36,8 @@ public class SeriesResource : RestResource
|
||||
public List<MediaCover> Images { get; set; }
|
||||
|
||||
public String RemotePoster { get; set; }
|
||||
|
||||
public List<Season> Seasons { get; set; }
|
||||
public Int32 Year { get; set; }
|
||||
|
||||
//View & Edit
|
||||
public String Path { get; set; }
|
||||
|
@ -1,36 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.SignalR;
|
||||
using Microsoft.AspNet.SignalR.Infrastructure;
|
||||
using NLog;
|
||||
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 = LogManager.GetCurrentClassLogger();
|
||||
}
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
@ -40,6 +40,7 @@ private Response GetStatus()
|
||||
OsVersion = OsInfo.Version.ToString(),
|
||||
IsMono = OsInfo.IsMono,
|
||||
IsLinux = OsInfo.IsLinux,
|
||||
IsWindows = OsInfo.IsWindows,
|
||||
Branch = _configFileProvider.Branch,
|
||||
Authentication = _configFileProvider.AuthenticationEnabled
|
||||
}.AsResponse();
|
||||
|
@ -33,8 +33,6 @@ private List<UpdateResource> GetAvailableUpdate()
|
||||
|
||||
public class UpdateResource : RestResource
|
||||
{
|
||||
public String Id { get; set; }
|
||||
|
||||
[JsonConverter(typeof(Newtonsoft.Json.Converters.VersionConverter))]
|
||||
public Version Version { get; set; }
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Text.RegularExpressions;
|
||||
using FluentValidation;
|
||||
using FluentValidation.Validators;
|
||||
|
||||
@ -27,5 +25,10 @@ public static IRuleBuilderOptions<T, string> IsValidPath<T>(this IRuleBuilder<T,
|
||||
{
|
||||
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,13 @@
|
||||
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.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Host;
|
||||
using NzbDrone.Test.Common;
|
||||
using FluentAssertions;
|
||||
@ -45,7 +46,6 @@ public void should_resolve_command_executor_by_name()
|
||||
{
|
||||
var genericExecutor = typeof(IExecute<>).MakeGenericType(typeof(RssSyncCommand));
|
||||
var container = MainAppContainerBuilder.BuildContainer(args);
|
||||
DbFactory.RegisterDatabase(container);
|
||||
|
||||
var executor = container.Resolve(genericExecutor);
|
||||
|
||||
|
@ -48,6 +48,23 @@ public void should_be_able_to_update_key()
|
||||
_cachedString.Find("Key").Should().Be("New");
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_be_able_to_remove_key()
|
||||
{
|
||||
_cachedString.Set("Key", "Value");
|
||||
|
||||
_cachedString.Remove("Key");
|
||||
|
||||
_cachedString.Find("Key").Should().BeNull();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_be_able_to_remove_non_existing_key()
|
||||
{
|
||||
_cachedString.Remove("Key");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_store_null()
|
||||
{
|
||||
|
@ -23,6 +23,10 @@ public void Setup()
|
||||
|
||||
if (_binFolderCopy.Exists)
|
||||
{
|
||||
foreach (var file in _binFolderCopy.GetFiles("*", SearchOption.AllDirectories))
|
||||
{
|
||||
file.Attributes = FileAttributes.Normal;
|
||||
}
|
||||
_binFolderCopy.Delete(true);
|
||||
}
|
||||
|
||||
@ -83,11 +87,7 @@ public void moveFile_should_not_move_overwrite_itself()
|
||||
[Test]
|
||||
public void CopyFolder_should_copy_folder()
|
||||
{
|
||||
|
||||
|
||||
Subject.CopyFolder(_binFolder.FullName, _binFolderCopy.FullName);
|
||||
|
||||
|
||||
VerifyCopy();
|
||||
}
|
||||
|
||||
@ -127,6 +127,22 @@ public void MoveFolder_should_overwrite_existing_folder()
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void move_read_only_file()
|
||||
{
|
||||
var source = GetTestFilePath();
|
||||
var destination = GetTestFilePath();
|
||||
|
||||
Subject.WriteAllText(source, "SourceFile");
|
||||
Subject.WriteAllText(destination, "DestinationFile");
|
||||
|
||||
File.SetAttributes(source, FileAttributes.ReadOnly);
|
||||
File.SetAttributes(destination, FileAttributes.ReadOnly);
|
||||
|
||||
Subject.MoveFile(source, destination);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[Test]
|
||||
@ -139,16 +155,60 @@ public void empty_folder_should_return_folder_modified_date()
|
||||
[Test]
|
||||
public void folder_should_return_correct_value_for_last_write()
|
||||
{
|
||||
var testFile = Path.Combine(SandboxFolder, "newfile.txt");
|
||||
var testFile = GetTestFilePath();
|
||||
|
||||
TestLogger.Info("Path is: {0}", testFile);
|
||||
|
||||
Subject.WriteAllText(testFile, "");
|
||||
Subject.WriteAllText(testFile, "Test");
|
||||
|
||||
Subject.GetLastFolderWrite(SandboxFolder).Should().BeOnOrAfter(DateTime.UtcNow.AddMinutes(-1));
|
||||
Subject.GetLastFolderWrite(SandboxFolder).Should().BeBefore(DateTime.UtcNow);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_for_unlocked_file()
|
||||
{
|
||||
var testFile = GetTestFilePath();
|
||||
Subject.WriteAllText(testFile, new Guid().ToString());
|
||||
|
||||
Subject.IsFileLocked(testFile).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_for_unlocked_and_readonly_file()
|
||||
{
|
||||
var testFile = GetTestFilePath();
|
||||
Subject.WriteAllText(testFile, new Guid().ToString());
|
||||
|
||||
File.SetAttributes(testFile, FileAttributes.ReadOnly);
|
||||
|
||||
Subject.IsFileLocked(testFile).Should().BeFalse();
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_return_true_for_unlocked_file()
|
||||
{
|
||||
var testFile = GetTestFilePath();
|
||||
Subject.WriteAllText(testFile, new Guid().ToString());
|
||||
|
||||
using (var file = File.OpenWrite(testFile))
|
||||
{
|
||||
Subject.IsFileLocked(testFile).Should().BeTrue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_be_able_to_set_permission_from_parrent()
|
||||
{
|
||||
var testFile = GetTestFilePath();
|
||||
Subject.WriteAllText(testFile, new Guid().ToString());
|
||||
|
||||
Subject.InheritFolderPermissions(testFile);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
[Explicit]
|
||||
public void check_last_write()
|
||||
|
@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FluentAssertions;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
|
@ -29,7 +29,7 @@ public void ApplicationPath_should_not_be_empty()
|
||||
[Test]
|
||||
public void IsProduction_should_return_false_when_run_within_nunit()
|
||||
{
|
||||
RuntimeInfo.IsProduction.Should().BeFalse("Process name is " + Process.GetCurrentProcess().ProcessName);
|
||||
RuntimeInfo.IsProduction.Should().BeFalse("Process name is " + Process.GetCurrentProcess().ProcessName + " Folder is " + Directory.GetCurrentDirectory());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -1,16 +1,18 @@
|
||||
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.Core.Messaging.Events;
|
||||
using NzbDrone.Test.Common;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace NzbDrone.Common.Test.EventingTests
|
||||
namespace NzbDrone.Common.Test.MessagingTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class MessageAggregatorEventTests : TestBase<MessageAggregator>
|
||||
public class MessageAggregatorEventTests : TestBase<EventAggregator>
|
||||
{
|
||||
private Mock<IHandle<EventA>> HandlerA1;
|
||||
private Mock<IHandle<EventA>> HandlerA2;
|
||||
@ -127,7 +129,7 @@ public void should_queue_multiple_async_events()
|
||||
|
||||
counter.WaitForAllItems();
|
||||
|
||||
counter.MaxThreads.Should().Be(2);
|
||||
counter.MaxThreads.Should().Be(3);
|
||||
}
|
||||
}
|
||||
|
@ -67,8 +67,7 @@
|
||||
<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\MessageAggregatorEventTests.cs" />
|
||||
<Compile Include="ReflectionExtensions.cs" />
|
||||
<Compile Include="PathExtensionFixture.cs" />
|
||||
<Compile Include="DiskProviderTests\DiskProviderFixture.cs" />
|
||||
|
@ -2,7 +2,7 @@
|
||||
<CopyReferencedAssembliesToWorkspace>false</CopyReferencedAssembliesToWorkspace>
|
||||
<ConsiderInconclusiveTestsAsPassing>true</ConsiderInconclusiveTestsAsPassing>
|
||||
<PreloadReferencedAssemblies>false</PreloadReferencedAssemblies>
|
||||
<AllowDynamicCodeContractChecking>true</AllowDynamicCodeContractChecking>
|
||||
<AllowDynamicCodeContractChecking>false</AllowDynamicCodeContractChecking>
|
||||
<AllowStaticCodeContractChecking>false</AllowStaticCodeContractChecking>
|
||||
<IgnoreThisComponentCompletely>false</IgnoreThisComponentCompletely>
|
||||
<RunPreBuildEvents>false</RunPreBuildEvents>
|
||||
@ -12,11 +12,11 @@
|
||||
<PreventSigningOfAssembly>false</PreventSigningOfAssembly>
|
||||
<AnalyseExecutionTimes>true</AnalyseExecutionTimes>
|
||||
<IncludeStaticReferencesInWorkspace>true</IncludeStaticReferencesInWorkspace>
|
||||
<DefaultTestTimeout>60000</DefaultTestTimeout>
|
||||
<UseBuildConfiguration></UseBuildConfiguration>
|
||||
<UseBuildPlatform></UseBuildPlatform>
|
||||
<DefaultTestTimeout>5000</DefaultTestTimeout>
|
||||
<UseBuildConfiguration>Debug</UseBuildConfiguration>
|
||||
<UseBuildPlatform>x86</UseBuildPlatform>
|
||||
<ProxyProcessPath></ProxyProcessPath>
|
||||
<UseCPUArchitecture>AutoDetect</UseCPUArchitecture>
|
||||
<UseCPUArchitecture>x86</UseCPUArchitecture>
|
||||
<MSTestThreadApartmentState>STA</MSTestThreadApartmentState>
|
||||
<BuildProcessArchitecture>x86</BuildProcessArchitecture>
|
||||
<IgnoredTests>
|
||||
@ -26,11 +26,35 @@
|
||||
<RegexTestSelector>
|
||||
<RegularExpression>NzbDrone\.Common\.Test\.EventingTests\.ServiceNameFixture\..*</RegularExpression>
|
||||
</RegexTestSelector>
|
||||
<RegexTestSelector>
|
||||
<RegularExpression>NzbDrone\.Common\.Test\.ProcessProviderTests\..*</RegularExpression>
|
||||
</RegexTestSelector>
|
||||
<RegexTestSelector>
|
||||
<RegularExpression>NzbDrone\.Common\.Test\.ServiceFactoryFixture\..*</RegularExpression>
|
||||
</RegexTestSelector>
|
||||
<NamedTestSelector>
|
||||
<TestName>NzbDrone.Common.Test.ProcessProviderTests.ToString_on_new_processInfo</TestName>
|
||||
</NamedTestSelector>
|
||||
<NamedTestSelector>
|
||||
<TestName>NzbDrone.Common.Test.ProcessProviderTests.Should_be_able_to_start_process</TestName>
|
||||
</NamedTestSelector>
|
||||
<NamedTestSelector>
|
||||
<TestName>NzbDrone.Common.Test.ProcessProviderTests.kill_all_should_kill_all_process_with_name</TestName>
|
||||
</NamedTestSelector>
|
||||
<NamedTestSelector>
|
||||
<TestName>NzbDrone.Common.Test.ProcessProviderTests.GetProcessById_should_return_null_for_invalid_process(9999)</TestName>
|
||||
</NamedTestSelector>
|
||||
<NamedTestSelector>
|
||||
<TestName>NzbDrone.Common.Test.ProcessProviderTests.GetProcessById_should_return_null_for_invalid_process(-1)</TestName>
|
||||
</NamedTestSelector>
|
||||
<NamedTestSelector>
|
||||
<TestName>NzbDrone.Common.Test.ProcessProviderTests.GetProcessById_should_return_null_for_invalid_process(0)</TestName>
|
||||
</NamedTestSelector>
|
||||
<RegexTestSelector>
|
||||
<RegularExpression>NzbDrone\.Common\.Test\.ServiceProviderTests\..*</RegularExpression>
|
||||
</RegexTestSelector>
|
||||
<NamedTestSelector>
|
||||
<TestName>NzbDrone.Common.Test.DiskProviderTests.DiskProviderFixture.folder_should_return_correct_value_for_last_write</TestName>
|
||||
</NamedTestSelector>
|
||||
<RegexTestSelector>
|
||||
<RegularExpression>NzbDrone\.Common\.Test\.DiskProviderTests\.DiskProviderFixture\..*</RegularExpression>
|
||||
</RegexTestSelector>
|
||||
</IgnoredTests>
|
||||
</ProjectConfiguration>
|
@ -126,17 +126,16 @@ public void get_actual_casing_should_return_actual_casing_for_local_file_in_wind
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Test]
|
||||
public void get_actual_casing_should_return_actual_casing_for_local_dir_in_windows()
|
||||
{
|
||||
WindowsOnly();
|
||||
var path = Directory.GetCurrentDirectory();
|
||||
var path = Directory.GetCurrentDirectory().Replace("c:\\","C:\\");
|
||||
|
||||
path.ToUpper().GetActualCasing().Should().Be(path);
|
||||
path.ToLower().GetActualCasing().Should().Be(path);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void get_actual_casing_should_return_original_value_in_linux()
|
||||
{
|
||||
|
@ -73,7 +73,7 @@ public void kill_all_should_kill_all_process_with_name()
|
||||
var dummy1 = StartDummyProcess();
|
||||
var dummy2 = StartDummyProcess();
|
||||
|
||||
Subject.KillAll(dummy1.ProcessName);
|
||||
Subject.KillAll(DummyApp.DUMMY_PROCCESS_NAME);
|
||||
|
||||
dummy1.HasExited.Should().BeTrue();
|
||||
dummy2.HasExited.Should().BeTrue();
|
||||
|
@ -2,8 +2,9 @@
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Messaging;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Messaging;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Host;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
|
@ -28,7 +28,6 @@ public ICached<T> GetCache<T>(Type host)
|
||||
return GetCache<T>(host, host.FullName);
|
||||
}
|
||||
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_cache.Clear();
|
||||
|
@ -61,6 +61,12 @@ public T Find(string key)
|
||||
return value.Object;
|
||||
}
|
||||
|
||||
public void Remove(string key)
|
||||
{
|
||||
CacheItem value;
|
||||
_store.TryRemove(key, out value);
|
||||
}
|
||||
|
||||
public T Get(string key, Func<T> function, TimeSpan? lifeTime = null)
|
||||
{
|
||||
Ensure.That(() => key).IsNotNullOrWhiteSpace();
|
||||
@ -81,7 +87,6 @@ public T Get(string key, Func<T> function, TimeSpan? lifeTime = null)
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_store.Clear();
|
||||
|
@ -13,6 +13,7 @@ public interface ICached<T> : ICached
|
||||
void Set(string key, T value, TimeSpan? lifetime = null);
|
||||
T Get(string key, Func<T> function, TimeSpan? lifeTime = null);
|
||||
T Find(string key);
|
||||
void Remove(string key);
|
||||
|
||||
ICollection<T> Values { get; }
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
@ -8,12 +7,12 @@
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnsureThat;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
|
||||
namespace NzbDrone.Common
|
||||
{
|
||||
public interface IDiskProvider
|
||||
{
|
||||
HashSet<string> SpecialFolders { get; }
|
||||
DateTime GetLastFolderWrite(string path);
|
||||
DateTime GetLastFileWrite(string path);
|
||||
void EnsureFolder(string path);
|
||||
@ -24,8 +23,8 @@ public interface IDiskProvider
|
||||
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);
|
||||
@ -36,11 +35,12 @@ public interface IDiskProvider
|
||||
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);
|
||||
FileAttributes GetFileAttributes(string path);
|
||||
void EmptyFolder(string path);
|
||||
}
|
||||
|
||||
public class DiskProvider : IDiskProvider
|
||||
@ -58,15 +58,7 @@ static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
|
||||
out ulong lpTotalNumberOfBytes,
|
||||
out ulong lpTotalNumberOfFreeBytes);
|
||||
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public HashSet<string> SpecialFolders
|
||||
{
|
||||
get
|
||||
{
|
||||
return new HashSet<string> { "$recycle.bin", "system volume information", "recycler" };
|
||||
}
|
||||
}
|
||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
|
||||
|
||||
public DateTime GetLastFolderWrite(string path)
|
||||
{
|
||||
@ -93,7 +85,9 @@ public DateTime GetLastFileWrite(string path)
|
||||
Ensure.That(() => path).IsValidPath();
|
||||
|
||||
if (!FileExists(path))
|
||||
{
|
||||
throw new FileNotFoundException("File doesn't exist: " + path);
|
||||
}
|
||||
|
||||
return new FileInfo(path).LastWriteTimeUtc;
|
||||
}
|
||||
@ -154,25 +148,26 @@ public long GetFileSize(string path)
|
||||
Ensure.That(() => path).IsValidPath();
|
||||
|
||||
if (!FileExists(path))
|
||||
{
|
||||
throw new FileNotFoundException("File doesn't exist: " + path);
|
||||
}
|
||||
|
||||
var fi = new FileInfo(path);
|
||||
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)
|
||||
@ -183,7 +178,7 @@ public void MoveFolder(string source, string destination)
|
||||
try
|
||||
{
|
||||
TransferFolder(source, destination, TransferAction.Move);
|
||||
Directory.Delete(source, true);
|
||||
DeleteFolder(source, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -238,8 +233,10 @@ private void TransferFolder(string source, string target, TransferAction transfe
|
||||
public void DeleteFile(string path)
|
||||
{
|
||||
Ensure.That(() => path).IsValidPath();
|
||||
|
||||
Logger.Trace("Deleting file: {0}", path);
|
||||
|
||||
RemoveReadOnly(path);
|
||||
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
@ -259,6 +256,7 @@ public void MoveFile(string source, string destination)
|
||||
DeleteFile(destination);
|
||||
}
|
||||
|
||||
RemoveReadOnly(source);
|
||||
File.Move(source, destination);
|
||||
}
|
||||
|
||||
@ -273,10 +271,20 @@ public void InheritFolderPermissions(string filename)
|
||||
{
|
||||
Ensure.That(() => filename).IsValidPath();
|
||||
|
||||
try
|
||||
{
|
||||
var fs = File.GetAccessControl(filename);
|
||||
fs.SetAccessRuleProtection(false, false);
|
||||
File.SetAccessControl(filename, fs);
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
{
|
||||
if (!OsInfo.IsLinux)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long? GetAvailableSpace(string path)
|
||||
{
|
||||
@ -347,11 +355,10 @@ public string ReadAllText(string filePath)
|
||||
public void WriteAllText(string filename, string contents)
|
||||
{
|
||||
Ensure.That(() => filename).IsValidPath();
|
||||
|
||||
RemoveReadOnly(filename);
|
||||
File.WriteAllText(filename, contents);
|
||||
}
|
||||
|
||||
|
||||
public void FileSetLastWriteTimeUtc(string path, DateTime dateTime)
|
||||
{
|
||||
Ensure.That(() => path).IsValidPath();
|
||||
@ -366,26 +373,19 @@ public void FolderSetLastWriteTimeUtc(string path, DateTime dateTime)
|
||||
Directory.SetLastWriteTimeUtc(path, dateTime);
|
||||
}
|
||||
|
||||
public bool IsFileLocked(FileInfo file)
|
||||
public bool IsFileLocked(string file)
|
||||
{
|
||||
FileStream stream = null;
|
||||
|
||||
try
|
||||
{
|
||||
stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
|
||||
using (File.Open(file, FileMode.Open, FileAccess.Read, FileShare.None))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (stream != null)
|
||||
stream.Close();
|
||||
}
|
||||
|
||||
//file is not locked
|
||||
return false;
|
||||
}
|
||||
|
||||
public string GetPathRoot(string path)
|
||||
@ -441,9 +441,34 @@ public bool IsParent(string parentPath, string childPath)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static void RemoveReadOnly(string path)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var newAttributes = File.GetAttributes(path) & ~(FileAttributes.ReadOnly);
|
||||
File.SetAttributes(path, newAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
public FileAttributes GetFileAttributes(string path)
|
||||
{
|
||||
return File.GetAttributes(path);
|
||||
}
|
||||
|
||||
public void EmptyFolder(string path)
|
||||
{
|
||||
Ensure.That(() => path).IsValidPath();
|
||||
|
||||
foreach (var file in GetFiles(path, SearchOption.TopDirectoryOnly))
|
||||
{
|
||||
DeleteFile(file);
|
||||
}
|
||||
|
||||
foreach (var directory in GetDirectories(path))
|
||||
{
|
||||
DeleteFolder(directory, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using NzbDrone.Common.EnsureThat.Resources;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
@ -4,6 +4,7 @@
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
|
||||
namespace NzbDrone.Common.EnvironmentInfo
|
||||
{
|
||||
@ -30,7 +31,7 @@ public AppFolderInfo(IDiskProvider diskProvider, IStartupArguments startupArgume
|
||||
DATA_SPECIAL_FOLDER = Environment.SpecialFolder.ApplicationData;
|
||||
}
|
||||
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
_logger = NzbDroneLogger.GetLogger(this);
|
||||
|
||||
if (startupArguments.Args.ContainsKey(StartupArguments.APPDATA))
|
||||
{
|
||||
|
@ -2,7 +2,6 @@
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Security.Principal;
|
||||
using System.ServiceProcess;
|
||||
using NLog;
|
||||
|
||||
namespace NzbDrone.Common.EnvironmentInfo
|
||||
@ -65,7 +64,9 @@ private static bool InternalIsProduction()
|
||||
if (lowerProcessName.Contains("jetbrain")) return false;
|
||||
if (lowerProcessName.Contains("resharper")) return false;
|
||||
|
||||
if (Directory.GetCurrentDirectory().ToLower().Contains("teamcity")) return false;
|
||||
string lowerCurrentDir = Directory.GetCurrentDirectory().ToLower();
|
||||
if (lowerCurrentDir.Contains("teamcity")) return false;
|
||||
if (lowerCurrentDir.StartsWith("/run/")) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NzbDrone.Common.EnvironmentInfo
|
||||
{
|
||||
@ -17,14 +16,6 @@ public class StartupArguments : IStartupArguments
|
||||
public const string UNINSTALL_SERVICE = "u";
|
||||
public const string HELP = "?";
|
||||
|
||||
static StartupArguments()
|
||||
{
|
||||
if (RuntimeInfo.IsProduction)
|
||||
{
|
||||
Instance = new StartupArguments("");
|
||||
}
|
||||
}
|
||||
|
||||
public StartupArguments(params string[] args)
|
||||
{
|
||||
Flags = new HashSet<string>();
|
||||
@ -45,13 +36,9 @@ public StartupArguments(params string[] args)
|
||||
Flags.Add(flag);
|
||||
}
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
public HashSet<string> Flags { get; private set; }
|
||||
public Dictionary<string, string> Args { get; private set; }
|
||||
|
||||
public static IStartupArguments Instance { get; private set; }
|
||||
}
|
||||
}
|
@ -2,8 +2,6 @@
|
||||
|
||||
namespace NzbDrone.Common.Exceptions
|
||||
{
|
||||
|
||||
|
||||
public abstract class NzbDroneException : ApplicationException
|
||||
{
|
||||
protected NzbDroneException(string message, params object[] args)
|
||||
@ -17,5 +15,16 @@ protected NzbDroneException(string message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected NzbDroneException(string message, Exception innerException, params object[] args)
|
||||
: base(string.Format(message, args), innerException)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected NzbDroneException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
@ -34,31 +33,9 @@ public static string CalculateCrc(string input)
|
||||
return String.Format("{0:x8}", mCrc);
|
||||
}
|
||||
|
||||
public static string GenerateUserId()
|
||||
public static string GenerateCommandId()
|
||||
{
|
||||
return GenerateId("u");
|
||||
}
|
||||
|
||||
public static string GenerateAppId()
|
||||
{
|
||||
return GenerateId("a");
|
||||
}
|
||||
|
||||
public static string GenerateApiToken()
|
||||
{
|
||||
return Guid.NewGuid().ToString().Replace("-", "");
|
||||
}
|
||||
|
||||
public static string GenerateSecurityToken(int length)
|
||||
{
|
||||
var byteSize = (length / 4) * 3;
|
||||
|
||||
var linkBytes = new byte[byteSize];
|
||||
var rngCrypto = new RNGCryptoServiceProvider();
|
||||
rngCrypto.GetBytes(linkBytes);
|
||||
var base64String = Convert.ToBase64String(linkBytes);
|
||||
|
||||
return base64String;
|
||||
return GenerateId("c");
|
||||
}
|
||||
|
||||
private static string GenerateId(string prefix)
|
||||
|
@ -1,26 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using NLog.LayoutRenderers;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Common.Instrumentation
|
||||
{
|
||||
[ThreadAgnostic]
|
||||
[LayoutRenderer("appLog")]
|
||||
public class ApplicationLogLayoutRenderer : LayoutRenderer
|
||||
{
|
||||
private readonly string _appData;
|
||||
|
||||
public ApplicationLogLayoutRenderer()
|
||||
{
|
||||
_appData = Path.Combine(new AppFolderInfo(new DiskProvider(), StartupArguments.Instance ).GetLogFolder(), "nzbdrone.txt");
|
||||
}
|
||||
|
||||
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
|
||||
{
|
||||
builder.Append(_appData);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using NLog.LayoutRenderers;
|
||||
|
||||
namespace NzbDrone.Common.Instrumentation
|
||||
{
|
||||
[ThreadAgnostic]
|
||||
[LayoutRenderer("dirSeparator")]
|
||||
public class DirSeparatorLayoutRenderer : LayoutRenderer
|
||||
{
|
||||
|
||||
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
|
||||
{
|
||||
builder.Append(Path.DirectorySeparatorChar);
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@
|
||||
using Exceptron.Client.Configuration;
|
||||
using NLog;
|
||||
using NLog.Common;
|
||||
using NLog.Config;
|
||||
using NLog.Layouts;
|
||||
using NLog.Targets;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
@ -23,19 +22,6 @@ public class ExceptronTarget : Target
|
||||
/// </summary>
|
||||
public IExceptronClient ExceptronClient { get; internal set; }
|
||||
|
||||
|
||||
private static ExceptronTarget _instance = new ExceptronTarget();
|
||||
|
||||
public static void Register()
|
||||
{
|
||||
var rule = new LoggingRule("*", LogLevel.Warn, _instance);
|
||||
|
||||
LogManager.Configuration.AddTarget("ExceptronTarget", _instance);
|
||||
LogManager.Configuration.LoggingRules.Add(rule);
|
||||
LogManager.ConfigurationReloaded += (sender, args) => Register();
|
||||
LogManager.ReconfigExistingLoggers();
|
||||
}
|
||||
|
||||
protected override void InitializeTarget()
|
||||
{
|
||||
var config = new ExceptronConfiguration
|
||||
|
@ -6,12 +6,9 @@ namespace NzbDrone.Common.Instrumentation
|
||||
{
|
||||
public static class GlobalExceptionHandlers
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetLogger("Global");
|
||||
|
||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
|
||||
public static void Register()
|
||||
{
|
||||
ExceptronTarget.Register();
|
||||
|
||||
AppDomain.CurrentDomain.UnhandledException += ((s, e) => AppDomainException(e.ExceptionObject as Exception));
|
||||
TaskScheduler.UnobservedTaskException += ((s, e) => TaskException(e.Exception));
|
||||
}
|
||||
@ -24,6 +21,15 @@ private static void TaskException(Exception exception)
|
||||
|
||||
private static void AppDomainException(Exception exception)
|
||||
{
|
||||
if (exception == null) return;
|
||||
|
||||
if (exception is NullReferenceException &&
|
||||
exception.ToString().Contains("Microsoft.AspNet.SignalR.Transports.TransportHeartbeat.ProcessServerCommand"))
|
||||
{
|
||||
Logger.Warn("SignalR Heartbeat error.");
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine("EPIC FAIL: {0}", exception);
|
||||
Logger.FatalException("EPIC FAIL: " + exception.Message, exception);
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ public static string GetHash(this LogEventInfo logEvent)
|
||||
return HashUtil.CalculateCrc(hashSeed);
|
||||
}
|
||||
|
||||
|
||||
public static string GetFormattedMessage(this LogEventInfo logEvent)
|
||||
{
|
||||
var message = logEvent.FormattedMessage;
|
||||
|
127
NzbDrone.Common/Instrumentation/LogTargets.cs
Normal file
127
NzbDrone.Common/Instrumentation/LogTargets.cs
Normal file
@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using NLog.Targets;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Common.Instrumentation
|
||||
{
|
||||
public static class LogTargets
|
||||
{
|
||||
public static void Register(IStartupArguments startupArguments, bool updateApp, bool inConsole)
|
||||
{
|
||||
var appFolderInfo = new AppFolderInfo(new DiskProvider(), startupArguments);
|
||||
|
||||
LogManager.Configuration = new LoggingConfiguration();
|
||||
|
||||
RegisterExceptron();
|
||||
|
||||
if (updateApp)
|
||||
{
|
||||
RegisterLoggly();
|
||||
RegisterUpdateFile(appFolderInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inConsole && (OsInfo.IsLinux || new RuntimeInfo(null).IsUserInteractive))
|
||||
{
|
||||
RegisterConsole();
|
||||
}
|
||||
|
||||
RegisterAppFile(appFolderInfo);
|
||||
}
|
||||
|
||||
LogManager.ReconfigExistingLoggers();
|
||||
}
|
||||
|
||||
private static void RegisterConsole()
|
||||
{
|
||||
var level = LogLevel.Trace;
|
||||
|
||||
if (RuntimeInfo.IsProduction)
|
||||
{
|
||||
level = LogLevel.Info;
|
||||
}
|
||||
|
||||
var coloredConsoleTarget = new ColoredConsoleTarget();
|
||||
|
||||
coloredConsoleTarget.Name = "consoleLogger";
|
||||
coloredConsoleTarget.Layout = "[${level}] ${logger}: ${message} ${onexception:inner=${newline}${newline}${exception:format=ToString}${newline}}";
|
||||
|
||||
var loggingRule = new LoggingRule("*", level, coloredConsoleTarget);
|
||||
|
||||
LogManager.Configuration.AddTarget("console", coloredConsoleTarget);
|
||||
LogManager.Configuration.LoggingRules.Add(loggingRule);
|
||||
}
|
||||
|
||||
|
||||
const string FileLogLayout = @"${date:format=yy-M-d HH\:mm\:ss.f}|${level}|${logger}|${message}${onexception:inner=${newline}${newline}${exception:format=ToString}${newline}}";
|
||||
|
||||
private static void RegisterAppFile(IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
var fileTarget = new FileTarget();
|
||||
|
||||
fileTarget.Name = "rollingFileLogger";
|
||||
fileTarget.FileName = Path.Combine(appFolderInfo.GetLogFolder(), "nzbdrone.txt");
|
||||
fileTarget.AutoFlush = true;
|
||||
fileTarget.KeepFileOpen = false;
|
||||
fileTarget.ConcurrentWrites = false;
|
||||
fileTarget.ConcurrentWriteAttemptDelay = 50;
|
||||
fileTarget.ConcurrentWriteAttempts = 10;
|
||||
fileTarget.ArchiveAboveSize = 1024000;
|
||||
fileTarget.MaxArchiveFiles = 5;
|
||||
fileTarget.EnableFileDelete = true;
|
||||
fileTarget.ArchiveNumbering = ArchiveNumberingMode.Rolling;
|
||||
fileTarget.Layout = FileLogLayout;
|
||||
|
||||
var loggingRule = new LoggingRule("*", LogLevel.Info, fileTarget);
|
||||
|
||||
LogManager.Configuration.AddTarget("appfile", fileTarget);
|
||||
LogManager.Configuration.LoggingRules.Add(loggingRule);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void RegisterUpdateFile(IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
var fileTarget = new FileTarget();
|
||||
|
||||
fileTarget.Name = "updateFileLogger";
|
||||
fileTarget.FileName = Path.Combine(appFolderInfo.GetUpdateLogFolder(), DateTime.Now.ToString("yy.MM.d-HH.mm") + ".txt");
|
||||
fileTarget.AutoFlush = true;
|
||||
fileTarget.KeepFileOpen = false;
|
||||
fileTarget.ConcurrentWrites = false;
|
||||
fileTarget.ConcurrentWriteAttemptDelay = 50;
|
||||
fileTarget.ConcurrentWriteAttempts = 100;
|
||||
fileTarget.Layout = FileLogLayout;
|
||||
|
||||
var loggingRule = new LoggingRule("*", LogLevel.Trace, fileTarget);
|
||||
|
||||
LogManager.Configuration.AddTarget("updateFile", fileTarget);
|
||||
LogManager.Configuration.LoggingRules.Add(loggingRule);
|
||||
}
|
||||
|
||||
private static void RegisterExceptron()
|
||||
{
|
||||
|
||||
var exceptronTarget = new ExceptronTarget();
|
||||
var rule = new LoggingRule("*", LogLevel.Warn, exceptronTarget);
|
||||
|
||||
LogManager.Configuration.AddTarget("ExceptronTarget", exceptronTarget);
|
||||
LogManager.Configuration.LoggingRules.Add(rule);
|
||||
}
|
||||
|
||||
|
||||
private static void RegisterLoggly()
|
||||
{
|
||||
var logglyTarger = new LogglyTarget();
|
||||
|
||||
var rule = new LoggingRule("*", LogLevel.Trace, logglyTarger);
|
||||
|
||||
LogManager.Configuration.AddTarget("LogglyLogger", logglyTarger);
|
||||
LogManager.Configuration.LoggingRules.Add(rule);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using NLog.Layouts;
|
||||
using NLog.Targets;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
@ -13,16 +12,10 @@ public class LogglyTarget : TargetWithLayout
|
||||
{
|
||||
private Logger _logger;
|
||||
|
||||
public void Register(LogLevel minLevel)
|
||||
public LogglyTarget()
|
||||
{
|
||||
Layout = new SimpleLayout("${callsite:className=false:fileName=false:includeSourcePath=false:methodName=true}");
|
||||
|
||||
var rule = new LoggingRule("*", minLevel, this);
|
||||
|
||||
LogManager.Configuration.AddTarget("LogglyLogger", this);
|
||||
LogManager.Configuration.LoggingRules.Add(rule);
|
||||
LogManager.ConfigurationReloaded += (sender, args) => Register(minLevel);
|
||||
LogManager.ReconfigExistingLoggers();
|
||||
}
|
||||
|
||||
protected override void InitializeTarget()
|
||||
|
42
NzbDrone.Common/Instrumentation/NzbDroneLogger.cs
Normal file
42
NzbDrone.Common/Instrumentation/NzbDroneLogger.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using NLog;
|
||||
|
||||
namespace NzbDrone.Common.Instrumentation
|
||||
{
|
||||
public static class NzbDroneLogger
|
||||
{
|
||||
public static Logger GetLogger()
|
||||
{
|
||||
string loggerName;
|
||||
Type declaringType;
|
||||
int framesToSkip = 1;
|
||||
do
|
||||
{
|
||||
var frame = new StackFrame(framesToSkip, false);
|
||||
var method = frame.GetMethod();
|
||||
declaringType = method.DeclaringType;
|
||||
if (declaringType == null)
|
||||
{
|
||||
loggerName = method.Name;
|
||||
break;
|
||||
}
|
||||
|
||||
framesToSkip++;
|
||||
loggerName = declaringType.Name;
|
||||
} while (declaringType.Module.Name.Equals("mscorlib.dll", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
return LogManager.GetLogger(loggerName);
|
||||
}
|
||||
|
||||
public static Logger GetLogger(object obj)
|
||||
{
|
||||
return LogManager.GetLogger(obj.GetType().Name);
|
||||
}
|
||||
|
||||
public static Logger GetLogger<T>()
|
||||
{
|
||||
return LogManager.GetLogger(typeof(T).Name);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using NLog.LayoutRenderers;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Common.Instrumentation
|
||||
{
|
||||
[ThreadAgnostic]
|
||||
[LayoutRenderer("updateLog")]
|
||||
public class UpdateLogLayoutRenderer : LayoutRenderer
|
||||
{
|
||||
private readonly string _appData;
|
||||
|
||||
public UpdateLogLayoutRenderer()
|
||||
{
|
||||
_appData = Path.Combine(new AppFolderInfo(new DiskProvider(), StartupArguments.Instance).GetUpdateLogFolder(), DateTime.Now.ToString("yy.MM.d-HH.mm") + ".txt");
|
||||
|
||||
}
|
||||
|
||||
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
|
||||
{
|
||||
builder.Append(_appData);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
namespace NzbDrone.Common.Messaging
|
||||
{
|
||||
public class CommandCompletedEvent : IEvent
|
||||
{
|
||||
public ICommand Command { get; private set; }
|
||||
|
||||
public CommandCompletedEvent(ICommand command)
|
||||
{
|
||||
Command = command;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace NzbDrone.Common.Messaging
|
||||
{
|
||||
public class CommandFailedEvent : IEvent
|
||||
{
|
||||
public ICommand Command { get; private set; }
|
||||
public Exception Exception { get; private set; }
|
||||
|
||||
public CommandFailedEvent(ICommand command, Exception exception)
|
||||
{
|
||||
Command = command;
|
||||
Exception = exception;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
namespace NzbDrone.Common.Messaging
|
||||
{
|
||||
public class CommandExecutedEvent : IEvent
|
||||
{
|
||||
public ICommand Command { get; private set; }
|
||||
|
||||
public CommandExecutedEvent(ICommand command)
|
||||
{
|
||||
Command = command;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
namespace NzbDrone.Common.Messaging
|
||||
{
|
||||
public interface ICommand : IMessage
|
||||
{
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
namespace NzbDrone.Common.Messaging
|
||||
namespace NzbDrone.Common.Messaging
|
||||
{
|
||||
public interface IEvent : IMessage
|
||||
{
|
||||
|
@ -1,12 +0,0 @@
|
||||
namespace NzbDrone.Common.Messaging
|
||||
{
|
||||
/// <summary>
|
||||
/// Enables loosely-coupled publication of events.
|
||||
/// </summary>
|
||||
public interface IMessageAggregator
|
||||
{
|
||||
void PublishEvent<TEvent>(TEvent @event) where TEvent : class, IEvent;
|
||||
void PublishCommand<TCommand>(TCommand command) where TCommand : class, ICommand;
|
||||
void PublishCommand(string commandType);
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace NzbDrone.Common.Messaging
|
||||
{
|
||||
public static class MessageExtensions
|
||||
{
|
||||
public static string GetExecutorName(this Type commandType)
|
||||
{
|
||||
if (!typeof(ICommand).IsAssignableFrom(commandType))
|
||||
{
|
||||
throw new ArgumentException("commandType must implement ICommand");
|
||||
}
|
||||
|
||||
return string.Format("I{0}Executor", commandType.Name);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
namespace NzbDrone.Common.Messaging
|
||||
{
|
||||
public class TestCommand : ICommand
|
||||
{
|
||||
public TestCommand()
|
||||
{
|
||||
Duration = 4000;
|
||||
}
|
||||
|
||||
public int Duration { get; set; }
|
||||
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -41,7 +41,7 @@
|
||||
</Reference>
|
||||
<Reference Include="Loggly, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\loggly-csharp.2.2\lib\Loggly.dll</HintPath>
|
||||
<HintPath>..\packages\loggly-csharp.2.3\lib\net35\Loggly.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
@ -92,6 +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="Messaging\IEvent.cs" />
|
||||
<Compile Include="Messaging\IMessage.cs" />
|
||||
<Compile Include="PathEqualityComparer.cs" />
|
||||
<Compile Include="Services.cs" />
|
||||
<Compile Include="TPL\LimitedConcurrencyLevelTaskScheduler.cs" />
|
||||
@ -99,23 +104,8 @@
|
||||
<Compile Include="StringExtensions.cs" />
|
||||
<Compile Include="EnsureThat\TypeParam.cs" />
|
||||
<Compile Include="HashUtil.cs" />
|
||||
<Compile Include="Instrumentation\ApplicationLogLayoutRenderer.cs" />
|
||||
<Compile Include="Instrumentation\DirSeparatorLayoutRenderer.cs" />
|
||||
<Compile Include="Instrumentation\LogEventExtensions.cs" />
|
||||
<Compile Include="Instrumentation\LogglyTarget.cs" />
|
||||
<Compile Include="Instrumentation\UpdateLogLayoutRenderer.cs" />
|
||||
<Compile Include="Serializer\Json.cs" />
|
||||
<Compile Include="Messaging\CommandCompletedEvent.cs" />
|
||||
<Compile Include="Messaging\CommandStartedEvent.cs" />
|
||||
<Compile Include="Messaging\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" />
|
||||
@ -123,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" />
|
||||
|
@ -1,8 +1,8 @@
|
||||
<ProjectConfiguration>
|
||||
<CopyReferencedAssembliesToWorkspace>false</CopyReferencedAssembliesToWorkspace>
|
||||
<ConsiderInconclusiveTestsAsPassing>false</ConsiderInconclusiveTestsAsPassing>
|
||||
<ConsiderInconclusiveTestsAsPassing>true</ConsiderInconclusiveTestsAsPassing>
|
||||
<PreloadReferencedAssemblies>false</PreloadReferencedAssemblies>
|
||||
<AllowDynamicCodeContractChecking>true</AllowDynamicCodeContractChecking>
|
||||
<AllowDynamicCodeContractChecking>false</AllowDynamicCodeContractChecking>
|
||||
<AllowStaticCodeContractChecking>false</AllowStaticCodeContractChecking>
|
||||
<IgnoreThisComponentCompletely>false</IgnoreThisComponentCompletely>
|
||||
<RunPreBuildEvents>false</RunPreBuildEvents>
|
||||
@ -12,8 +12,11 @@
|
||||
<PreventSigningOfAssembly>false</PreventSigningOfAssembly>
|
||||
<AnalyseExecutionTimes>true</AnalyseExecutionTimes>
|
||||
<IncludeStaticReferencesInWorkspace>true</IncludeStaticReferencesInWorkspace>
|
||||
<DefaultTestTimeout>60000</DefaultTestTimeout>
|
||||
<UseBuildConfiguration />
|
||||
<ProxyProcessPath />
|
||||
<UseCPUArchitecture>AutoDetect</UseCPUArchitecture>
|
||||
<DefaultTestTimeout>5000</DefaultTestTimeout>
|
||||
<UseBuildConfiguration>Debug</UseBuildConfiguration>
|
||||
<UseBuildPlatform>x86</UseBuildPlatform>
|
||||
<ProxyProcessPath></ProxyProcessPath>
|
||||
<UseCPUArchitecture>x86</UseCPUArchitecture>
|
||||
<MSTestThreadApartmentState>STA</MSTestThreadApartmentState>
|
||||
<BuildProcessArchitecture>x86</BuildProcessArchitecture>
|
||||
</ProjectConfiguration>
|
@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Common
|
||||
|
@ -6,6 +6,7 @@
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
using NzbDrone.Common.Model;
|
||||
|
||||
namespace NzbDrone.Common
|
||||
@ -26,7 +27,7 @@ public interface IProcessProvider
|
||||
|
||||
public class ProcessProvider : IProcessProvider
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
|
||||
|
||||
public const string NZB_DRONE_PROCESS_NAME = "NzbDrone";
|
||||
public const string NZB_DRONE_CONSOLE_PROCESS_NAME = "NzbDrone.Console";
|
||||
@ -212,7 +213,7 @@ private static ProcessInfo ConvertToProcessInfo(Process process)
|
||||
return new ProcessInfo
|
||||
{
|
||||
Id = process.Id,
|
||||
StartPath = process.MainModule.FileName,
|
||||
StartPath = GetExeFileName(process),
|
||||
Name = process.ProcessName
|
||||
};
|
||||
}
|
||||
@ -224,6 +225,17 @@ private static ProcessInfo ConvertToProcessInfo(Process process)
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static string GetExeFileName(Process process)
|
||||
{
|
||||
if (process.MainModule.FileName != "mono.exe")
|
||||
{
|
||||
return process.MainModule.FileName;
|
||||
}
|
||||
|
||||
return process.Modules.Cast<ProcessModule>().FirstOrDefault(module => module.ModuleName.ToLower().EndsWith(".exe")).FileName;
|
||||
}
|
||||
|
||||
private void Kill(int processId)
|
||||
{
|
||||
var process = Process.GetProcesses().FirstOrDefault(p => p.Id == processId);
|
||||
|
@ -3,12 +3,13 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
|
||||
namespace NzbDrone.Common.Security
|
||||
{
|
||||
public static class IgnoreCertErrorPolicy
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetLogger("CertPolicy");
|
||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
|
||||
|
||||
public static void Register()
|
||||
{
|
||||
|
@ -5,6 +5,7 @@
|
||||
using System.Linq;
|
||||
using System.ServiceProcess;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
|
||||
namespace NzbDrone.Common
|
||||
{
|
||||
@ -25,7 +26,7 @@ public class ServiceProvider : IServiceProvider
|
||||
{
|
||||
public const string NZBDRONE_SERVICE_NAME = "NzbDrone";
|
||||
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
|
||||
|
||||
public virtual bool ServiceExist(string name)
|
||||
{
|
||||
|
@ -1,11 +1,12 @@
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
|
||||
namespace NzbDrone.Common.TPL
|
||||
{
|
||||
public static class TaskExtensions
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetLogger("TaskExtensions");
|
||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
|
||||
|
||||
public static Task LogExceptions(this Task task)
|
||||
{
|
||||
|
@ -70,7 +70,6 @@ namespace TinyIoC
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="loggly-csharp" version="2.2" targetFramework="net40" />
|
||||
<package id="loggly-csharp" version="2.3" targetFramework="net40" />
|
||||
<package id="Newtonsoft.Json" version="5.0.6" targetFramework="net40" />
|
||||
<package id="NLog" version="2.0.1.2" targetFramework="net40" />
|
||||
<package id="SharpZipLib" version="0.86.0" targetFramework="net40" />
|
||||
|
@ -2,23 +2,29 @@
|
||||
using System.Threading;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
using NzbDrone.Host;
|
||||
|
||||
namespace NzbDrone.Console
|
||||
{
|
||||
public static class ConsoleApp
|
||||
{
|
||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
Bootstrap.Start(new StartupArguments(args), new ConsoleAlerts());
|
||||
var startupArgs = new StartupArguments(args);
|
||||
LogTargets.Register(startupArgs, false, true);
|
||||
Bootstrap.Start(startupArgs, new ConsoleAlerts());
|
||||
}
|
||||
catch (TerminateApplicationException)
|
||||
{
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.FatalException("EPIC FAIL!", e);
|
||||
System.Console.ReadLine();
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
using NUnit.Framework;
|
||||
using Newtonsoft.Json;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.DataAugmentation.Scene;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
@ -13,7 +12,7 @@ namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene
|
||||
|
||||
public class SceneMappingProxyFixture : CoreTest<SceneMappingProxy>
|
||||
{
|
||||
private const string SCENE_MAPPING_URL = "http://services.nzbdrone.com/SceneMapping/Active";
|
||||
private const string SCENE_MAPPING_URL = "http://services.nzbdrone.com/v1/SceneMapping";
|
||||
|
||||
[Test]
|
||||
public void fetch_should_return_list_of_mappings()
|
||||
@ -31,7 +30,6 @@ public void fetch_should_return_list_of_mappings()
|
||||
mappings.Should().NotContain(c => c.TvdbId == 0);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_throw_on_server_error()
|
||||
{
|
||||
|
@ -1,84 +0,0 @@
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore
|
||||
{
|
||||
[TestFixture]
|
||||
public class SQLiteMigrationHelperFixture : DbTest
|
||||
{
|
||||
private SQLiteMigrationHelper _subject;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_subject = Mocker.Resolve<SQLiteMigrationHelper>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_parse_existing_columns()
|
||||
{
|
||||
var columns = _subject.GetColumns("Series");
|
||||
|
||||
columns.Should().NotBeEmpty();
|
||||
|
||||
columns.Values.Should().NotContain(c => string.IsNullOrWhiteSpace(c.Name));
|
||||
columns.Values.Should().NotContain(c => string.IsNullOrWhiteSpace(c.Schema));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_create_table_from_column_list()
|
||||
{
|
||||
var columns = _subject.GetColumns("Series");
|
||||
columns.Remove("Title");
|
||||
|
||||
_subject.CreateTable("Series_New", columns.Values);
|
||||
|
||||
var newColumns = _subject.GetColumns("Series_New");
|
||||
|
||||
newColumns.Values.Should().HaveSameCount(columns.Values);
|
||||
newColumns.Should().NotContainKey("Title");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_get_zero_count_on_empty_table()
|
||||
{
|
||||
_subject.GetRowCount("Series").Should().Be(0);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_be_able_to_transfer_empty_tables()
|
||||
{
|
||||
var columns = _subject.GetColumns("Series");
|
||||
columns.Remove("Title");
|
||||
|
||||
_subject.CreateTable("Series_New", columns.Values);
|
||||
|
||||
|
||||
_subject.CopyData("Series", "Series_New", columns.Values);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_transfer_table_with_data()
|
||||
{
|
||||
var originalEpisodes = Builder<Episode>.CreateListOfSize(10).BuildListOfNew();
|
||||
|
||||
Mocker.Resolve<EpisodeRepository>().InsertMany(originalEpisodes);
|
||||
|
||||
var columns = _subject.GetColumns("Episodes");
|
||||
columns.Remove("Title");
|
||||
|
||||
_subject.CreateTable("Episodes_New", columns.Values);
|
||||
|
||||
_subject.CopyData("Episodes", "Episodes_New", columns.Values);
|
||||
|
||||
_subject.GetRowCount("Episodes_New").Should().Be(originalEpisodes.Count);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
using System.Collections.Generic;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
using System.Linq;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.SQLiteMigrationHelperTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class AlterFixture : DbTest
|
||||
{
|
||||
private SqLiteMigrationHelper _subject;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_subject = Mocker.Resolve<SqLiteMigrationHelper>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_existing_columns()
|
||||
{
|
||||
var columns = _subject.GetColumns("Series");
|
||||
|
||||
columns.Should().NotBeEmpty();
|
||||
|
||||
columns.Values.Should().NotContain(c => string.IsNullOrWhiteSpace(c.Name));
|
||||
columns.Values.Should().NotContain(c => string.IsNullOrWhiteSpace(c.Schema));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_create_table_from_column_list()
|
||||
{
|
||||
var columns = _subject.GetColumns("Series");
|
||||
columns.Remove("Title");
|
||||
|
||||
_subject.CreateTable("Series_New", columns.Values, new List<SQLiteIndex>());
|
||||
|
||||
var newColumns = _subject.GetColumns("Series_New");
|
||||
|
||||
newColumns.Values.Should().HaveSameCount(columns.Values);
|
||||
newColumns.Should().NotContainKey("Title");
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_be_able_to_transfer_empty_tables()
|
||||
{
|
||||
var columns = _subject.GetColumns("Series");
|
||||
var indexes = _subject.GetIndexes("Series");
|
||||
columns.Remove("Title");
|
||||
|
||||
_subject.CreateTable("Series_New", columns.Values, indexes);
|
||||
|
||||
|
||||
_subject.CopyData("Series", "Series_New", columns.Values);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_transfer_table_with_data()
|
||||
{
|
||||
var originalEpisodes = Builder<Episode>.CreateListOfSize(10).BuildListOfNew();
|
||||
|
||||
Mocker.Resolve<EpisodeRepository>().InsertMany(originalEpisodes);
|
||||
|
||||
var columns = _subject.GetColumns("Episodes");
|
||||
var indexes = _subject.GetIndexes("Episodes");
|
||||
|
||||
columns.Remove("Title");
|
||||
|
||||
_subject.CreateTable("Episodes_New", columns.Values, indexes);
|
||||
|
||||
_subject.CopyData("Episodes", "Episodes_New", columns.Values);
|
||||
|
||||
_subject.GetRowCount("Episodes_New").Should().Be(originalEpisodes.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_read_existing_indexes()
|
||||
{
|
||||
var indexes = _subject.GetIndexes("QualitySizes");
|
||||
|
||||
indexes.Should().NotBeEmpty();
|
||||
|
||||
indexes.Should().OnlyContain(c => c != null);
|
||||
indexes.Should().OnlyContain(c => !string.IsNullOrWhiteSpace(c.Column));
|
||||
indexes.Should().OnlyContain(c => c.Table == "QualitySizes");
|
||||
indexes.Should().OnlyContain(c => c.Unique);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_add_indexes_when_creating_new_table()
|
||||
{
|
||||
var columns = _subject.GetColumns("QualitySizes");
|
||||
var indexes = _subject.GetIndexes("QualitySizes");
|
||||
|
||||
|
||||
_subject.CreateTable("QualityB", columns.Values, indexes);
|
||||
|
||||
|
||||
var newIndexes = _subject.GetIndexes("QualityB");
|
||||
|
||||
newIndexes.Should().HaveSameCount(indexes);
|
||||
newIndexes.Select(c=>c.Column).Should().BeEquivalentTo(indexes.Select(c=>c.Column));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_be_able_to_create_table_with_new_indexes()
|
||||
{
|
||||
var columns = _subject.GetColumns("Series");
|
||||
columns.Remove("Title");
|
||||
|
||||
_subject.CreateTable("Series_New", columns.Values, new List<SQLiteIndex>{new SQLiteIndex{Column = "AirTime", Table = "Series_New", Unique = true}});
|
||||
|
||||
var newColumns = _subject.GetColumns("Series_New");
|
||||
var newIndexes = _subject.GetIndexes("Series_New");
|
||||
|
||||
newColumns.Values.Should().HaveSameCount(columns.Values);
|
||||
newIndexes.Should().Contain(i=>i.Column == "AirTime");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.SQLiteMigrationHelperTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class DuplicateFixture : DbTest
|
||||
{
|
||||
private SqLiteMigrationHelper _subject;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_subject = Mocker.Resolve<SqLiteMigrationHelper>();
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void get_duplicates()
|
||||
{
|
||||
var series = Builder<Series>.CreateListOfSize(10)
|
||||
.Random(3)
|
||||
.With(c => c.QualityProfileId = 100)
|
||||
.BuildListOfNew();
|
||||
|
||||
Db.InsertMany(series);
|
||||
|
||||
var duplicates = _subject.GetDuplicates<int>("series", "QualityProfileId").ToList();
|
||||
|
||||
|
||||
duplicates.Should().HaveCount(1);
|
||||
duplicates.First().Should().HaveCount(3);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -26,14 +26,14 @@ public void Setup()
|
||||
{
|
||||
parseResultMulti = new RemoteEpisode
|
||||
{
|
||||
Report = new ReportInfo(),
|
||||
Release = new ReleaseInfo(),
|
||||
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.SDTV, true) },
|
||||
Episodes = new List<Episode> { new Episode(), new Episode() }
|
||||
};
|
||||
|
||||
parseResultSingle = new RemoteEpisode
|
||||
{
|
||||
Report = new ReportInfo(),
|
||||
Release = new ReleaseInfo(),
|
||||
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.SDTV, true) },
|
||||
Episodes = new List<Episode> { new Episode() }
|
||||
|
||||
@ -59,7 +59,7 @@ public void Setup()
|
||||
public void IsAcceptableSize_true_single_episode_not_first_or_last_30_minute()
|
||||
{
|
||||
parseResultSingle.Series = series30minutes;
|
||||
parseResultSingle.Report.Size = 184572800;
|
||||
parseResultSingle.Release.Size = 184572800;
|
||||
|
||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
||||
|
||||
@ -78,7 +78,7 @@ public void IsAcceptableSize_true_single_episode_not_first_or_last_30_minute()
|
||||
public void IsAcceptableSize_true_single_episode_not_first_or_last_60_minute()
|
||||
{
|
||||
parseResultSingle.Series = series60minutes;
|
||||
parseResultSingle.Report.Size = 368572800;
|
||||
parseResultSingle.Release.Size = 368572800;
|
||||
|
||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
||||
|
||||
@ -97,7 +97,7 @@ public void IsAcceptableSize_true_single_episode_not_first_or_last_60_minute()
|
||||
public void IsAcceptableSize_false_single_episode_not_first_or_last_30_minute()
|
||||
{
|
||||
parseResultSingle.Series = series30minutes;
|
||||
parseResultSingle.Report.Size = 1.Gigabytes();
|
||||
parseResultSingle.Release.Size = 1.Gigabytes();
|
||||
|
||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
||||
|
||||
@ -116,7 +116,7 @@ public void IsAcceptableSize_false_single_episode_not_first_or_last_30_minute()
|
||||
public void IsAcceptableSize_false_single_episode_not_first_or_last_60_minute()
|
||||
{
|
||||
parseResultSingle.Series = series60minutes;
|
||||
parseResultSingle.Report.Size = 1.Gigabytes();
|
||||
parseResultSingle.Release.Size = 1.Gigabytes();
|
||||
|
||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
||||
|
||||
@ -133,7 +133,7 @@ public void IsAcceptableSize_false_single_episode_not_first_or_last_60_minute()
|
||||
public void IsAcceptableSize_true_multi_episode_not_first_or_last_30_minute()
|
||||
{
|
||||
parseResultMulti.Series = series30minutes;
|
||||
parseResultMulti.Report.Size = 184572800;
|
||||
parseResultMulti.Release.Size = 184572800;
|
||||
|
||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
||||
|
||||
@ -152,7 +152,7 @@ public void IsAcceptableSize_true_multi_episode_not_first_or_last_30_minute()
|
||||
public void IsAcceptableSize_true_multi_episode_not_first_or_last_60_minute()
|
||||
{
|
||||
parseResultMulti.Series = series60minutes;
|
||||
parseResultMulti.Report.Size = 368572800;
|
||||
parseResultMulti.Release.Size = 368572800;
|
||||
|
||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
||||
|
||||
@ -171,7 +171,7 @@ public void IsAcceptableSize_true_multi_episode_not_first_or_last_60_minute()
|
||||
public void IsAcceptableSize_false_multi_episode_not_first_or_last_30_minute()
|
||||
{
|
||||
parseResultMulti.Series = series30minutes;
|
||||
parseResultMulti.Report.Size = 1.Gigabytes();
|
||||
parseResultMulti.Release.Size = 1.Gigabytes();
|
||||
|
||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
||||
|
||||
@ -190,7 +190,7 @@ public void IsAcceptableSize_false_multi_episode_not_first_or_last_30_minute()
|
||||
public void IsAcceptableSize_false_multi_episode_not_first_or_last_60_minute()
|
||||
{
|
||||
parseResultMulti.Series = series60minutes;
|
||||
parseResultMulti.Report.Size = 10.Gigabytes();
|
||||
parseResultMulti.Release.Size = 10.Gigabytes();
|
||||
|
||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
||||
|
||||
@ -209,7 +209,7 @@ public void IsAcceptableSize_false_multi_episode_not_first_or_last_60_minute()
|
||||
public void IsAcceptableSize_true_single_episode_first_30_minute()
|
||||
{
|
||||
parseResultSingle.Series = series30minutes;
|
||||
parseResultSingle.Report.Size = 184572800;
|
||||
parseResultSingle.Release.Size = 184572800;
|
||||
|
||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
||||
|
||||
@ -228,7 +228,7 @@ public void IsAcceptableSize_true_single_episode_first_30_minute()
|
||||
public void IsAcceptableSize_true_single_episode_first_60_minute()
|
||||
{
|
||||
parseResultSingle.Series = series60minutes;
|
||||
parseResultSingle.Report.Size = 368572800;
|
||||
parseResultSingle.Release.Size = 368572800;
|
||||
|
||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
||||
|
||||
@ -247,7 +247,7 @@ public void IsAcceptableSize_true_single_episode_first_60_minute()
|
||||
public void IsAcceptableSize_false_single_episode_first_30_minute()
|
||||
{
|
||||
parseResultSingle.Series = series30minutes;
|
||||
parseResultSingle.Report.Size = 1.Gigabytes();
|
||||
parseResultSingle.Release.Size = 1.Gigabytes();
|
||||
|
||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
||||
|
||||
@ -268,7 +268,7 @@ public void IsAcceptableSize_false_single_episode_first_60_minute()
|
||||
|
||||
|
||||
parseResultSingle.Series = series60minutes;
|
||||
parseResultSingle.Report.Size = 10.Gigabytes();
|
||||
parseResultSingle.Release.Size = 10.Gigabytes();
|
||||
|
||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
||||
|
||||
@ -289,7 +289,7 @@ public void IsAcceptableSize_true_unlimited_30_minute()
|
||||
|
||||
|
||||
parseResultSingle.Series = series30minutes;
|
||||
parseResultSingle.Report.Size = 18457280000;
|
||||
parseResultSingle.Release.Size = 18457280000;
|
||||
qualityType.MaxSize = 0;
|
||||
|
||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
||||
@ -311,7 +311,7 @@ public void IsAcceptableSize_true_unlimited_60_minute()
|
||||
|
||||
|
||||
parseResultSingle.Series = series60minutes;
|
||||
parseResultSingle.Report.Size = 36857280000;
|
||||
parseResultSingle.Release.Size = 36857280000;
|
||||
qualityType.MaxSize = 0;
|
||||
|
||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
||||
@ -334,7 +334,7 @@ public void IsAcceptableSize_should_treat_daily_series_as_single_episode()
|
||||
parseResultSingle.Series = series60minutes;
|
||||
parseResultSingle.Series.SeriesType = SeriesTypes.Daily;
|
||||
|
||||
parseResultSingle.Report.Size = 300.Megabytes();
|
||||
parseResultSingle.Release.Size = 300.Megabytes();
|
||||
|
||||
qualityType.MaxSize = (int)600.Megabytes();
|
||||
|
||||
|
@ -0,0 +1,48 @@
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class CutoffSpecificationFixture : CoreTest<QualityUpgradableSpecification>
|
||||
{
|
||||
[Test]
|
||||
public void should_return_true_if_current_episode_is_less_than_cutoff()
|
||||
{
|
||||
Subject.CutoffNotMet(new QualityProfile { Cutoff = Quality.Bluray1080p },
|
||||
new QualityModel(Quality.DVD, true)).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_if_current_episode_is_equal_to_cutoff()
|
||||
{
|
||||
Subject.CutoffNotMet(new QualityProfile { Cutoff = Quality.HDTV720p },
|
||||
new QualityModel(Quality.HDTV720p, true)).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_if_current_episode_is_greater_than_cutoff()
|
||||
{
|
||||
Subject.CutoffNotMet(new QualityProfile { Cutoff = Quality.HDTV720p },
|
||||
new QualityModel(Quality.Bluray1080p, true)).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_when_new_episode_is_proper_but_existing_is_not()
|
||||
{
|
||||
Subject.CutoffNotMet(new QualityProfile { Cutoff = Quality.HDTV720p },
|
||||
new QualityModel(Quality.HDTV720p, false), new QualityModel(Quality.HDTV720p, true)).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_if_cutoff_is_met_and_quality_is_higher()
|
||||
{
|
||||
Subject.CutoffNotMet(new QualityProfile { Cutoff = Quality.HDTV720p },
|
||||
new QualityModel(Quality.HDTV720p, true), new QualityModel(Quality.Bluray1080p, true)).Should().BeFalse();
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
@ -15,7 +16,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
[TestFixture]
|
||||
public class DownloadDecisionMakerFixture : CoreTest<DownloadDecisionMaker>
|
||||
{
|
||||
private List<ReportInfo> _reports;
|
||||
private List<ReleaseInfo> _reports;
|
||||
private RemoteEpisode _remoteEpisode;
|
||||
|
||||
private Mock<IDecisionEngineSpecification> _pass1;
|
||||
@ -56,10 +57,11 @@ public void Setup()
|
||||
_fail3.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null)).Returns(false);
|
||||
_fail3.Setup(c => c.RejectionReason).Returns("_fail3");
|
||||
|
||||
_reports = new List<ReportInfo> { new ReportInfo { Title = "The.Office.S03E115.DVDRip.XviD-OSiTV" } };
|
||||
_reports = new List<ReleaseInfo> { new ReleaseInfo { Title = "The.Office.S03E115.DVDRip.XviD-OSiTV" } };
|
||||
_remoteEpisode = new RemoteEpisode { Series = new Series() };
|
||||
|
||||
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>()))
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Setup(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()))
|
||||
.Returns(_remoteEpisode);
|
||||
}
|
||||
|
||||
@ -130,7 +132,7 @@ public void should_not_attempt_to_map_episode_if_not_parsable()
|
||||
|
||||
var results = Subject.GetRssDecision(_reports).ToList();
|
||||
|
||||
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>()), Times.Never());
|
||||
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
|
||||
|
||||
_pass1.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
|
||||
_pass2.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
|
||||
@ -146,7 +148,7 @@ [Test] public void should_not_attempt_to_map_episode_series_title_is_blank()
|
||||
|
||||
var results = Subject.GetRssDecision(_reports).ToList();
|
||||
|
||||
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>()), Times.Never());
|
||||
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()), Times.Never());
|
||||
|
||||
_pass1.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
|
||||
_pass2.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null), Times.Never());
|
||||
@ -174,19 +176,19 @@ public void broken_report_shouldnt_blowup_the_process()
|
||||
{
|
||||
GivenSpecifications(_pass1);
|
||||
|
||||
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>()))
|
||||
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()))
|
||||
.Throws<TestException>();
|
||||
|
||||
_reports = new List<ReportInfo>
|
||||
_reports = new List<ReleaseInfo>
|
||||
{
|
||||
new ReportInfo{Title = "The.Office.S03E115.DVDRip.XviD-OSiTV"},
|
||||
new ReportInfo{Title = "The.Office.S03E115.DVDRip.XviD-OSiTV"},
|
||||
new ReportInfo{Title = "The.Office.S03E115.DVDRip.XviD-OSiTV"}
|
||||
new ReleaseInfo{Title = "The.Office.S03E115.DVDRip.XviD-OSiTV"},
|
||||
new ReleaseInfo{Title = "The.Office.S03E115.DVDRip.XviD-OSiTV"},
|
||||
new ReleaseInfo{Title = "The.Office.S03E115.DVDRip.XviD-OSiTV"}
|
||||
};
|
||||
|
||||
Subject.GetRssDecision(_reports);
|
||||
|
||||
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>()), Times.Exactly(_reports.Count));
|
||||
Mocker.GetMock<IParsingService>().Verify(c => c.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<SearchCriteriaBase>()), Times.Exactly(_reports.Count));
|
||||
|
||||
ExceptionVerification.ExpectedErrors(3);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public void Setup()
|
||||
{
|
||||
_parseResult = new RemoteEpisode
|
||||
{
|
||||
Report = new ReportInfo
|
||||
Release = new ReleaseInfo
|
||||
{
|
||||
Title = "Dexter.S08E01.EDITED.WEBRip.x264-KYR"
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class QualityUpgradableSpecificationFixture : CoreTest<QualityUpgradableSpecification>
|
||||
{
|
||||
[Test]
|
||||
public void IsUpgradePossible_should_return_true_if_current_episode_is_less_than_cutoff()
|
||||
{
|
||||
Subject.IsUpgradable(new QualityProfile { Cutoff = Quality.Bluray1080p },
|
||||
new QualityModel(Quality.DVD, true)).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsUpgradePossible_should_return_false_if_current_episode_is_equal_to_cutoff()
|
||||
{
|
||||
Subject.IsUpgradable(new QualityProfile { Cutoff = Quality.HDTV720p },
|
||||
new QualityModel(Quality.HDTV720p, true)).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsUpgradePossible_should_return_false_if_current_episode_is_greater_than_cutoff()
|
||||
{
|
||||
Subject.IsUpgradable(new QualityProfile { Cutoff = Quality.HDTV720p },
|
||||
new QualityModel(Quality.Bluray1080p, true)).Should().BeFalse();
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,6 @@ public class QualityUpgradeSpecificationFixture : CoreTest<QualityUpgradableSpec
|
||||
new object[] { Quality.SDTV, false, Quality.SDTV, true, Quality.SDTV, true },
|
||||
new object[] { Quality.WEBDL720p, false, Quality.WEBDL720p, true, Quality.WEBDL720p, true },
|
||||
new object[] { Quality.SDTV, false, Quality.SDTV, false, Quality.SDTV, false },
|
||||
new object[] { Quality.SDTV, false, Quality.DVD, true, Quality.SDTV, false },
|
||||
new object[] { Quality.WEBDL720p, false, Quality.HDTV720p, true, Quality.Bluray720p, false },
|
||||
new object[] { Quality.WEBDL720p, false, Quality.HDTV720p, true, Quality.WEBDL720p, false },
|
||||
new object[] { Quality.WEBDL720p, false, Quality.WEBDL720p, false, Quality.WEBDL720p, false },
|
||||
@ -37,7 +36,7 @@ public void IsUpgradeTest(Quality current, bool currentProper, Quality newQualit
|
||||
{
|
||||
GivenAutoDownloadPropers(true);
|
||||
|
||||
Subject.IsUpgradable(new QualityProfile() { Cutoff = cutoff }, new QualityModel(current, currentProper), new QualityModel(newQuality, newProper))
|
||||
Subject.IsUpgradable(new QualityModel(current, currentProper), new QualityModel(newQuality, newProper))
|
||||
.Should().Be(expected);
|
||||
}
|
||||
|
||||
@ -46,8 +45,7 @@ public void should_return_false_if_proper_and_autoDownloadPropers_is_false()
|
||||
{
|
||||
GivenAutoDownloadPropers(false);
|
||||
|
||||
Subject.IsUpgradable(new QualityProfile { Cutoff = Quality.Bluray1080p },
|
||||
new QualityModel(Quality.DVD, true),
|
||||
Subject.IsUpgradable(new QualityModel(Quality.DVD, true),
|
||||
new QualityModel(Quality.DVD, false)).Should().BeFalse();
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
@ -19,9 +20,9 @@ public void Setup()
|
||||
{
|
||||
parseResult = new RemoteEpisode
|
||||
{
|
||||
Report = new ReportInfo
|
||||
Release = new ReleaseInfo
|
||||
{
|
||||
Age = 100
|
||||
PublishDate = DateTime.Now.AddDays(-100)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -0,0 +1,137 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications.RssSync;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
|
||||
{
|
||||
[TestFixture]
|
||||
|
||||
public class ProperSpecificationFixture : CoreTest<ProperSpecification>
|
||||
{
|
||||
private RemoteEpisode _parseResultMulti;
|
||||
private RemoteEpisode _parseResultSingle;
|
||||
private EpisodeFile _firstFile;
|
||||
private EpisodeFile _secondFile;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Mocker.Resolve<QualityUpgradableSpecification>();
|
||||
|
||||
_firstFile = new EpisodeFile { Quality = new QualityModel(Quality.Bluray1080p, false), DateAdded = DateTime.Now };
|
||||
_secondFile = new EpisodeFile { Quality = new QualityModel(Quality.Bluray1080p, false), DateAdded = DateTime.Now };
|
||||
|
||||
var singleEpisodeList = new List<Episode> { new Episode { EpisodeFile = _firstFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = null } };
|
||||
var doubleEpisodeList = new List<Episode> { new Episode { EpisodeFile = _firstFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = _secondFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = null } };
|
||||
|
||||
var fakeSeries = Builder<Series>.CreateNew()
|
||||
.With(c => c.QualityProfile = new QualityProfile { Cutoff = Quality.Bluray1080p })
|
||||
.Build();
|
||||
|
||||
_parseResultMulti = new RemoteEpisode
|
||||
{
|
||||
Series = fakeSeries,
|
||||
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.DVD, true) },
|
||||
Episodes = doubleEpisodeList
|
||||
};
|
||||
|
||||
_parseResultSingle = new RemoteEpisode
|
||||
{
|
||||
Series = fakeSeries,
|
||||
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.DVD, true) },
|
||||
Episodes = singleEpisodeList
|
||||
};
|
||||
}
|
||||
|
||||
private void WithFirstFileUpgradable()
|
||||
{
|
||||
_firstFile.Quality = new QualityModel(Quality.SDTV);
|
||||
}
|
||||
|
||||
private void GivenAutoDownloadPropers()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.Setup(s => s.AutoDownloadPropers)
|
||||
.Returns(true);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_when_episodeFile_was_added_more_than_7_days_ago()
|
||||
{
|
||||
_firstFile.Quality.Quality = Quality.DVD;
|
||||
|
||||
_firstFile.DateAdded = DateTime.Today.AddDays(-30);
|
||||
Subject.IsSatisfiedBy(_parseResultSingle, null).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_when_first_episodeFile_was_added_more_than_7_days_ago()
|
||||
{
|
||||
_firstFile.Quality.Quality = Quality.DVD;
|
||||
_secondFile.Quality.Quality = Quality.DVD;
|
||||
|
||||
_firstFile.DateAdded = DateTime.Today.AddDays(-30);
|
||||
Subject.IsSatisfiedBy(_parseResultMulti, null).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_when_second_episodeFile_was_added_more_than_7_days_ago()
|
||||
{
|
||||
_firstFile.Quality.Quality = Quality.DVD;
|
||||
_secondFile.Quality.Quality = Quality.DVD;
|
||||
|
||||
_secondFile.DateAdded = DateTime.Today.AddDays(-30);
|
||||
Subject.IsSatisfiedBy(_parseResultMulti, null).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_when_episodeFile_was_added_more_than_7_days_ago_but_proper_is_for_better_quality()
|
||||
{
|
||||
WithFirstFileUpgradable();
|
||||
|
||||
_firstFile.DateAdded = DateTime.Today.AddDays(-30);
|
||||
Subject.IsSatisfiedBy(_parseResultSingle, null).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_when_episodeFile_was_added_more_than_7_days_ago_but_is_for_search()
|
||||
{
|
||||
WithFirstFileUpgradable();
|
||||
|
||||
_firstFile.DateAdded = DateTime.Today.AddDays(-30);
|
||||
Subject.IsSatisfiedBy(_parseResultSingle, new SingleEpisodeSearchCriteria()).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_when_proper_but_auto_download_propers_is_false()
|
||||
{
|
||||
_firstFile.Quality.Quality = Quality.DVD;
|
||||
|
||||
_firstFile.DateAdded = DateTime.Today;
|
||||
Subject.IsSatisfiedBy(_parseResultSingle, null).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_when_episodeFile_was_added_today()
|
||||
{
|
||||
GivenAutoDownloadPropers();
|
||||
|
||||
_firstFile.Quality.Quality = Quality.DVD;
|
||||
|
||||
_firstFile.DateAdded = DateTime.Today;
|
||||
Subject.IsSatisfiedBy(_parseResultSingle, null).Should().BeTrue();
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
@ -124,52 +123,5 @@ public void should_not_be_upgradable_if_qualities_are_the_same()
|
||||
_parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.WEBDL1080p, false);
|
||||
_upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_when_episodeFile_was_added_more_than_7_days_ago()
|
||||
{
|
||||
_firstFile.Quality.Quality = Quality.DVD;
|
||||
|
||||
_firstFile.DateAdded = DateTime.Today.AddDays(-30);
|
||||
_upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_when_first_episodeFile_was_added_more_than_7_days_ago()
|
||||
{
|
||||
_firstFile.Quality.Quality = Quality.DVD;
|
||||
_secondFile.Quality.Quality = Quality.DVD;
|
||||
|
||||
_firstFile.DateAdded = DateTime.Today.AddDays(-30);
|
||||
_upgradeDisk.IsSatisfiedBy(_parseResultMulti, null).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_when_second_episodeFile_was_added_more_than_7_days_ago()
|
||||
{
|
||||
_firstFile.Quality.Quality = Quality.DVD;
|
||||
_secondFile.Quality.Quality = Quality.DVD;
|
||||
|
||||
_secondFile.DateAdded = DateTime.Today.AddDays(-30);
|
||||
_upgradeDisk.IsSatisfiedBy(_parseResultMulti, null).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_when_episodeFile_was_added_more_than_7_days_ago_but_proper_is_for_better_quality()
|
||||
{
|
||||
WithFirstFileUpgradable();
|
||||
|
||||
_firstFile.DateAdded = DateTime.Today.AddDays(-30);
|
||||
_upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_when_episodeFile_was_added_more_than_7_days_ago_but_is_for_search()
|
||||
{
|
||||
WithFirstFileUpgradable();
|
||||
|
||||
_firstFile.DateAdded = DateTime.Today.AddDays(-30);
|
||||
_upgradeDisk.IsSatisfiedBy(_parseResultSingle, new SingleEpisodeSearchCriteria()).Should().BeTrue();
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,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;
|
||||
@ -34,8 +34,8 @@ private RemoteEpisode GetRemoteEpisode(List<Episode> episodes, QualityModel qual
|
||||
remoteEpisode.Episodes = new List<Episode>();
|
||||
remoteEpisode.Episodes.AddRange(episodes);
|
||||
|
||||
remoteEpisode.Report = new ReportInfo();
|
||||
remoteEpisode.Report.Age = 0;
|
||||
remoteEpisode.Release = new ReleaseInfo();
|
||||
remoteEpisode.Release.PublishDate = DateTime.UtcNow;
|
||||
|
||||
return remoteEpisode;
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
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;
|
||||
@ -32,9 +33,9 @@ private RemoteEpisode GetRemoteEpisode(List<Episode> episodes, QualityModel qual
|
||||
remoteEpisode.Episodes = new List<Episode>();
|
||||
remoteEpisode.Episodes.AddRange(episodes);
|
||||
|
||||
remoteEpisode.Report = new ReportInfo();
|
||||
remoteEpisode.Report.Age = Age;
|
||||
remoteEpisode.Report.Size = size;
|
||||
remoteEpisode.Release = new ReleaseInfo();
|
||||
remoteEpisode.Release.PublishDate = DateTime.Now.AddDays(-Age);
|
||||
remoteEpisode.Release.Size = size;
|
||||
|
||||
return remoteEpisode;
|
||||
}
|
||||
@ -110,9 +111,9 @@ public void should_order_by_lowest_number_of_episodes_with_multiple_episodes()
|
||||
public void should_order_by_smallest_rounded_to_200mb_then_age()
|
||||
{
|
||||
var remoteEpisodeSd = GetRemoteEpisode(new List<Episode> { GetEpisode(1) }, new QualityModel(Quality.SDTV), size: 100.Megabytes(), Age: 1);
|
||||
var remoteEpisodeHdSmallOld = GetRemoteEpisode(new List<Episode> { GetEpisode(1) }, new QualityModel(Quality.HDTV720p), size:1200.Megabytes(), Age:1000);
|
||||
var remoteEpisodeHdSmallYounge = GetRemoteEpisode(new List<Episode> { GetEpisode(1) }, new QualityModel(Quality.HDTV720p), size:1250.Megabytes(), Age:10);
|
||||
var remoteEpisodeHdLargeYounge = GetRemoteEpisode(new List<Episode> { GetEpisode(1) }, new QualityModel(Quality.HDTV720p), size:3000.Megabytes(), Age:1);
|
||||
var remoteEpisodeHdSmallOld = GetRemoteEpisode(new List<Episode> { GetEpisode(1) }, new QualityModel(Quality.HDTV720p), size: 1200.Megabytes(), Age: 1000);
|
||||
var remoteEpisodeHdSmallYounge = GetRemoteEpisode(new List<Episode> { GetEpisode(1) }, new QualityModel(Quality.HDTV720p), size: 1250.Megabytes(), Age: 10);
|
||||
var remoteEpisodeHdLargeYounge = GetRemoteEpisode(new List<Episode> { GetEpisode(1) }, new QualityModel(Quality.HDTV720p), size: 3000.Megabytes(), Age: 1);
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisodeSd));
|
||||
|
@ -30,9 +30,9 @@ public void Setup()
|
||||
Mocker.GetMock<IConfigService>().SetupGet(c => c.BlackholeFolder).Returns(_blackHoleFolder);
|
||||
|
||||
_remoteEpisode = new RemoteEpisode();
|
||||
_remoteEpisode.Report = new ReportInfo();
|
||||
_remoteEpisode.Report.Title = _title;
|
||||
_remoteEpisode.Report.NzbUrl = _nzbUrl;
|
||||
_remoteEpisode.Release = new ReleaseInfo();
|
||||
_remoteEpisode.Release.Title = _title;
|
||||
_remoteEpisode.Release.DownloadUrl = _nzbUrl;
|
||||
}
|
||||
|
||||
private void WithExistingFile()
|
||||
@ -58,7 +58,7 @@ public void should_replace_illegal_characters_in_title()
|
||||
{
|
||||
var illegalTitle = "Saturday Night Live - S38E08 - Jeremy Renner/Maroon 5 [SDTV]";
|
||||
var expectedFilename = Path.Combine(_blackHoleFolder, "Saturday Night Live - S38E08 - Jeremy Renner+Maroon 5 [SDTV].nzb");
|
||||
_remoteEpisode.Report.Title = illegalTitle;
|
||||
_remoteEpisode.Release.Title = illegalTitle;
|
||||
|
||||
Subject.DownloadNzb(_remoteEpisode);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user