Merge branch 'develop'
This commit is contained in:
commit
b8779b554c
|
@ -39,6 +39,7 @@ src/**/[Oo]bj/
|
|||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*
|
||||
_dotCover*
|
||||
|
||||
# NCrunch
|
||||
*.ncrunch*
|
||||
|
|
|
@ -27,7 +27,7 @@ module.exports = function (grunt) {
|
|||
},
|
||||
|
||||
bootstrap: {
|
||||
src : srcContent + 'Bootstrap/bootstrap.less',
|
||||
src : srcContent + 'bootstrap.less',
|
||||
dest: destContent + 'bootstrap.css'
|
||||
},
|
||||
general : {
|
||||
|
@ -118,7 +118,7 @@ module.exports = function (grunt) {
|
|||
requirejs: {
|
||||
compile:{
|
||||
options: {
|
||||
mainConfigFile: "src/UI/app.js",
|
||||
mainConfigFile: 'src/UI/app.js',
|
||||
fileExclusionRegExp: /^.*\.(?!js$)[^.]+$/,
|
||||
preserveLicenseComments: false,
|
||||
dir: outputDir,
|
||||
|
@ -139,11 +139,11 @@ module.exports = function (grunt) {
|
|||
nospawn: false
|
||||
},
|
||||
bootstrap : {
|
||||
files: [ srcContent + 'Bootstrap/**', srcContent + 'FontAwesome/**'],
|
||||
files: [ srcContent + 'Bootstrap/**', srcContent + 'FontAwesome/**', srcContent + 'bootstrap.less'],
|
||||
tasks: ['less:bootstrap','less:general']
|
||||
},
|
||||
generalLess: {
|
||||
files: [ srcRoot + '**/*.less', '!**/Bootstrap/**', '!**/FontAwesome/**'],
|
||||
files: [ srcRoot + '**/*.less', '!**/Bootstrap/**', '!**/FontAwesome/**', '!' + srcContent + '/bootstrap.less'],
|
||||
tasks: ['less:general']
|
||||
},
|
||||
handlebars : {
|
||||
|
|
|
@ -6,6 +6,7 @@ $testPackageFolder = '.\_tests\'
|
|||
$testSearchPattern = '*.Test\bin\x86\Release'
|
||||
$sourceFolder = '.\src'
|
||||
$updateFolder = $outputFolder + '\NzbDrone.Update'
|
||||
$updateFolderMono = $outputFolderMono + '\NzbDrone.Update'
|
||||
|
||||
Function Build()
|
||||
{
|
||||
|
@ -73,9 +74,6 @@ Function PackageMono()
|
|||
|
||||
Copy-Item $outputFolder $outputFolderMono -recurse
|
||||
|
||||
Write-Host Removing Update Client
|
||||
Remove-Item -Recurse -Force "$outputFolderMono\NzbDrone.Update"
|
||||
|
||||
Write-Host Creating MDBs
|
||||
get-childitem $outputFolderMono -File -Include @("*.exe", "*.dll") -Exclude @("MediaInfo.dll", "sqlite3.dll") -Recurse | foreach ($_) {
|
||||
Write-Host "Creating .mdb for $_"
|
||||
|
@ -110,6 +108,9 @@ Function PackageMono()
|
|||
|
||||
Remove-Item "$outputFolderMono\NzbDrone.Console.vshost.exe"
|
||||
|
||||
Write-Host Adding NzbDrone.Mono to UpdatePackage
|
||||
Copy-Item $outputFolderMono\* $updateFolderMono -Filter NzbDrone.Mono.*
|
||||
|
||||
Write-Host "##teamcity[progressFinish 'Creating Mono Package']"
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
using Nancy;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Nancy;
|
||||
using Nancy.Authentication.Basic;
|
||||
using Nancy.Security;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
||||
namespace NzbDrone.Api.Authentication
|
||||
|
@ -15,10 +19,12 @@ namespace NzbDrone.Api.Authentication
|
|||
{
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private static readonly NzbDroneUser AnonymousUser = new NzbDroneUser { UserName = "Anonymous" };
|
||||
private static String API_KEY;
|
||||
|
||||
public AuthenticationService(IConfigFileProvider configFileProvider)
|
||||
{
|
||||
_configFileProvider = configFileProvider;
|
||||
API_KEY = configFileProvider.ApiKey;
|
||||
}
|
||||
|
||||
public IUserIdentity Validate(string username, string password)
|
||||
|
@ -47,9 +53,71 @@ namespace NzbDrone.Api.Authentication
|
|||
|
||||
public bool IsAuthenticated(NancyContext context)
|
||||
{
|
||||
if (context.CurrentUser == null && _configFileProvider.AuthenticationEnabled) return false;
|
||||
var apiKey = GetApiKey(context);
|
||||
|
||||
if (context.Request.IsApiRequest())
|
||||
{
|
||||
return ValidApiKey(apiKey);
|
||||
}
|
||||
|
||||
if (context.Request.IsFeedRequest())
|
||||
{
|
||||
if (!Enabled)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ValidUser(context) || ValidApiKey(apiKey))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Enabled)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ValidUser(context))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool ValidUser(NancyContext context)
|
||||
{
|
||||
if (context.CurrentUser != null) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool ValidApiKey(string apiKey)
|
||||
{
|
||||
if (API_KEY.Equals(apiKey)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private string GetApiKey(NancyContext context)
|
||||
{
|
||||
var apiKeyHeader = context.Request.Headers["X-Api-Key"].FirstOrDefault();
|
||||
var apiKeyQueryString = context.Request.Query["ApiKey"];
|
||||
|
||||
if (!apiKeyHeader.IsNullOrWhiteSpace())
|
||||
{
|
||||
return apiKeyHeader;
|
||||
}
|
||||
|
||||
if (apiKeyQueryString.HasValue)
|
||||
{
|
||||
return apiKeyQueryString.Value;
|
||||
}
|
||||
|
||||
return context.Request.Headers.Authorization;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
using Nancy;
|
||||
using Nancy.Authentication.Basic;
|
||||
using Nancy.Bootstrapper;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Api.Extensions.Pipelines;
|
||||
|
||||
namespace NzbDrone.Api.Authentication
|
||||
{
|
||||
public class EnableBasicAuthInNancy : IRegisterNancyPipeline
|
||||
public class EnableAuthInNancy : IRegisterNancyPipeline
|
||||
{
|
||||
private readonly IAuthenticationService _authenticationService;
|
||||
|
||||
public EnableBasicAuthInNancy(IAuthenticationService authenticationService)
|
||||
public EnableAuthInNancy(IAuthenticationService authenticationService)
|
||||
{
|
||||
_authenticationService = authenticationService;
|
||||
}
|
||||
|
@ -25,7 +24,7 @@ namespace NzbDrone.Api.Authentication
|
|||
{
|
||||
Response response = null;
|
||||
|
||||
if (!context.Request.IsApiRequest() && !_authenticationService.IsAuthenticated(context))
|
||||
if (!_authenticationService.IsAuthenticated(context))
|
||||
{
|
||||
response = new Response { StatusCode = HttpStatusCode.Unauthorized };
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Nancy;
|
||||
using Nancy.Bootstrapper;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Api.Extensions.Pipelines;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
||||
namespace NzbDrone.Api.Authentication
|
||||
{
|
||||
public class EnableStatelessAuthInNancy : IRegisterNancyPipeline
|
||||
{
|
||||
private static String API_KEY;
|
||||
|
||||
public EnableStatelessAuthInNancy(IConfigFileProvider configFileProvider)
|
||||
{
|
||||
API_KEY = configFileProvider.ApiKey;
|
||||
}
|
||||
|
||||
public void Register(IPipelines pipelines)
|
||||
{
|
||||
pipelines.BeforeRequest.AddItemToEndOfPipeline(ValidateApiKey);
|
||||
}
|
||||
|
||||
public Response ValidateApiKey(NancyContext context)
|
||||
{
|
||||
Response response = null;
|
||||
|
||||
var apiKey = GetApiKey(context);
|
||||
|
||||
if ((context.Request.IsApiRequest() || context.Request.IsFeedRequest()) && !ValidApiKey(apiKey))
|
||||
{
|
||||
response = new Response { StatusCode = HttpStatusCode.Unauthorized };
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
private bool ValidApiKey(string apiKey)
|
||||
{
|
||||
if (!API_KEY.Equals(apiKey)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private string GetApiKey(NancyContext context)
|
||||
{
|
||||
var apiKeyHeader = context.Request.Headers["X-Api-Key"].FirstOrDefault();
|
||||
var apiKeyQueryString = context.Request.Query["ApiKey"];
|
||||
|
||||
if (!apiKeyHeader.IsNullOrWhiteSpace())
|
||||
{
|
||||
return apiKeyHeader;
|
||||
}
|
||||
|
||||
if (apiKeyQueryString.HasValue)
|
||||
{
|
||||
return apiKeyQueryString.Value;
|
||||
}
|
||||
|
||||
return context.Request.Headers.Authorization;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Api.Series;
|
||||
|
||||
namespace NzbDrone.Api.Blacklist
|
||||
{
|
||||
|
@ -12,5 +13,7 @@ namespace NzbDrone.Api.Blacklist
|
|||
public string SourceTitle { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
|
||||
public SeriesResource Series { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace NzbDrone.Api.Calendar
|
|||
foreach (var episode in message.Episode.Episodes)
|
||||
{
|
||||
var resource = episode.InjectTo<EpisodeResource>();
|
||||
resource.Downloading = true;
|
||||
resource.Grabbed = true;
|
||||
|
||||
BroadcastResourceChange(ModelAction.Updated, resource);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@ using System.Reflection;
|
|||
using FluentValidation;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Update;
|
||||
using NzbDrone.Core.Validation;
|
||||
using NzbDrone.Core.Validation.Paths;
|
||||
using Omu.ValueInjecter;
|
||||
|
||||
namespace NzbDrone.Api.Config
|
||||
|
@ -12,7 +14,7 @@ namespace NzbDrone.Api.Config
|
|||
{
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
|
||||
public HostConfigModule(ConfigFileProvider configFileProvider)
|
||||
public HostConfigModule(IConfigFileProvider configFileProvider)
|
||||
: base("/config/host")
|
||||
{
|
||||
_configFileProvider = configFileProvider;
|
||||
|
@ -29,6 +31,8 @@ namespace NzbDrone.Api.Config
|
|||
|
||||
SharedValidator.RuleFor(c => c.SslPort).ValidPort().When(c => c.EnableSsl);
|
||||
SharedValidator.RuleFor(c => c.SslCertHash).NotEmpty().When(c => c.EnableSsl && OsInfo.IsWindows);
|
||||
|
||||
SharedValidator.RuleFor(c => c.UpdateScriptPath).IsValidPath().When(c => c.UpdateMechanism == UpdateMechanism.Script);
|
||||
}
|
||||
|
||||
private HostConfigResource GetHostConfig()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.Update;
|
||||
|
||||
namespace NzbDrone.Api.Config
|
||||
{
|
||||
|
@ -14,10 +15,12 @@ namespace NzbDrone.Api.Config
|
|||
public String Password { get; set; }
|
||||
public String LogLevel { get; set; }
|
||||
public String Branch { get; set; }
|
||||
public Boolean AutoUpdate { get; set; }
|
||||
public String ApiKey { get; set; }
|
||||
public Boolean Torrent { get; set; }
|
||||
public String SslCertHash { get; set; }
|
||||
public String UrlBase { get; set; }
|
||||
public Boolean UpdateAutomatically { get; set; }
|
||||
public UpdateMechanism UpdateMechanism { get; set; }
|
||||
public String UpdateScriptPath { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ namespace NzbDrone.Api.Directories
|
|||
return dirs;
|
||||
}
|
||||
|
||||
|
||||
private List<string> GetSubDirectories(string path)
|
||||
{
|
||||
try
|
||||
|
@ -47,12 +46,15 @@ namespace NzbDrone.Api.Directories
|
|||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
return new List<string>();
|
||||
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace NzbDrone.Api.Episodes
|
|||
foreach (var episode in message.Episode.Episodes)
|
||||
{
|
||||
var resource = episode.InjectTo<EpisodeResource>();
|
||||
resource.Downloading = true;
|
||||
resource.Grabbed = true;
|
||||
|
||||
BroadcastResourceChange(ModelAction.Updated, resource);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
|
||||
|
@ -27,6 +28,8 @@ namespace NzbDrone.Api.Episodes
|
|||
public Core.Tv.Series Series { get; set; }
|
||||
public String SeriesTitle { get; set; }
|
||||
|
||||
public Boolean Downloading { get; set; }
|
||||
//Hiding this so people don't think its usable (only used to set the initial state)
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public Boolean Grabbed { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,11 @@
|
|||
using Nancy;
|
||||
using Nancy.Bootstrapper;
|
||||
using NzbDrone.Api.Frontend;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Api.Extensions.Pipelines
|
||||
{
|
||||
public class CacheHeaderPipeline : IRegisterNancyPipeline
|
||||
public class NzbDroneVersionPipeline : IRegisterNancyPipeline
|
||||
{
|
||||
private readonly ICacheableSpecification _cacheableSpecification;
|
||||
|
||||
public CacheHeaderPipeline(ICacheableSpecification cacheableSpecification)
|
||||
{
|
||||
_cacheableSpecification = cacheableSpecification;
|
||||
}
|
||||
|
||||
public void Register(IPipelines pipelines)
|
||||
{
|
||||
pipelines.AfterRequest.AddItemToStartOfPipeline(Handle);
|
||||
|
@ -20,14 +13,7 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
|||
|
||||
private void Handle(NancyContext context)
|
||||
{
|
||||
if (_cacheableSpecification.IsCacheable(context))
|
||||
{
|
||||
context.Response.Headers.EnableCache();
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Response.Headers.DisableCache();
|
||||
}
|
||||
context.Response.Headers.Add("X-ApplicationVersion", BuildInfo.Version.ToString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
using Nancy;
|
||||
using Nancy.Bootstrapper;
|
||||
using NzbDrone.Api.Frontend;
|
||||
|
||||
namespace NzbDrone.Api.Extensions.Pipelines
|
||||
{
|
||||
public class CacheHeaderPipeline : IRegisterNancyPipeline
|
||||
{
|
||||
private readonly ICacheableSpecification _cacheableSpecification;
|
||||
|
||||
public CacheHeaderPipeline(ICacheableSpecification cacheableSpecification)
|
||||
{
|
||||
_cacheableSpecification = cacheableSpecification;
|
||||
}
|
||||
|
||||
public void Register(IPipelines pipelines)
|
||||
{
|
||||
pipelines.AfterRequest.AddItemToStartOfPipeline(Handle);
|
||||
}
|
||||
|
||||
private void Handle(NancyContext context)
|
||||
{
|
||||
if (_cacheableSpecification.IsCacheable(context))
|
||||
{
|
||||
context.Response.Headers.EnableCache();
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Response.Headers.DisableCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ namespace NzbDrone.Api.Frontend
|
|||
if (context.Request.Path.StartsWith("/api", StringComparison.CurrentCultureIgnoreCase)) return false;
|
||||
if (context.Request.Path.StartsWith("/signalr", StringComparison.CurrentCultureIgnoreCase)) return false;
|
||||
if (context.Request.Path.EndsWith("main.js")) return false;
|
||||
if (context.Request.Path.StartsWith("/feed", StringComparison.CurrentCultureIgnoreCase)) return false;
|
||||
|
||||
if (context.Request.Path.StartsWith("/log", StringComparison.CurrentCultureIgnoreCase) &&
|
||||
context.Request.Path.EndsWith(".txt", StringComparison.CurrentCultureIgnoreCase))
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
using System.IO;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Api.Frontend.Mappers
|
||||
{
|
||||
public class FaviconMapper : StaticResourceMapperBase
|
||||
{
|
||||
private readonly IAppFolderInfo _appFolderInfo;
|
||||
|
||||
public FaviconMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, Logger logger)
|
||||
: base(diskProvider, logger)
|
||||
{
|
||||
_appFolderInfo = appFolderInfo;
|
||||
}
|
||||
|
||||
protected override string Map(string resourceUrl)
|
||||
{
|
||||
var path = Path.Combine("Content", "Images", "favicon.ico");
|
||||
|
||||
return Path.Combine(_appFolderInfo.StartUpFolder, "UI", path);
|
||||
}
|
||||
|
||||
public override bool CanHandle(string resourceUrl)
|
||||
{
|
||||
return resourceUrl.Equals("/favicon.ico");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
using System.IO;
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
|
@ -29,7 +28,7 @@ namespace NzbDrone.Api.Frontend.Mappers
|
|||
return resourceUrl.StartsWith("/Content") ||
|
||||
resourceUrl.EndsWith(".js") ||
|
||||
resourceUrl.EndsWith(".css") ||
|
||||
resourceUrl.EndsWith(".ico") ||
|
||||
(resourceUrl.EndsWith(".ico") && !resourceUrl.Equals("/favicon.ico")) ||
|
||||
resourceUrl.EndsWith(".swf");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,8 +85,7 @@
|
|||
<Link>Properties\SharedAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Authentication\AuthenticationService.cs" />
|
||||
<Compile Include="Authentication\EnableStatelessAuthInNancy.cs" />
|
||||
<Compile Include="Authentication\EnableBasicAuthInNancy.cs" />
|
||||
<Compile Include="Authentication\EnableAuthInNancy.cs" />
|
||||
<Compile Include="Authentication\NzbDroneUser.cs" />
|
||||
<Compile Include="Blacklist\BlacklistModule.cs" />
|
||||
<Compile Include="Blacklist\BlacklistResource.cs" />
|
||||
|
@ -123,12 +122,14 @@
|
|||
<Compile Include="Episodes\RenameEpisodeModule.cs" />
|
||||
<Compile Include="Episodes\RenameEpisodeResource.cs" />
|
||||
<Compile Include="Extensions\Pipelines\CacheHeaderPipeline.cs" />
|
||||
<Compile Include="Extensions\Pipelines\NzbDroneVersionPipeline.cs" />
|
||||
<Compile Include="Extensions\Pipelines\GZipPipeline.cs" />
|
||||
<Compile Include="Extensions\Pipelines\IfModifiedPipeline.cs" />
|
||||
<Compile Include="Extensions\Pipelines\IRegisterNancyPipeline.cs" />
|
||||
<Compile Include="Extensions\NancyJsonSerializer.cs" />
|
||||
<Compile Include="Extensions\RequestExtensions.cs" />
|
||||
<Compile Include="Frontend\IsCacheableSpecification.cs" />
|
||||
<Compile Include="Frontend\Mappers\FaviconMapper.cs" />
|
||||
<Compile Include="Frontend\Mappers\IndexHtmlMapper.cs" />
|
||||
<Compile Include="Frontend\Mappers\LogFileMapper.cs" />
|
||||
<Compile Include="Frontend\Mappers\MediaCoverMapper.cs" />
|
||||
|
@ -161,6 +162,7 @@
|
|||
<Compile Include="Mapping\MappingValidation.cs" />
|
||||
<Compile Include="Mapping\ResourceMappingException.cs" />
|
||||
<Compile Include="Mapping\ValueInjectorExtensions.cs" />
|
||||
<Compile Include="Update\UpdateResource.cs" />
|
||||
<Compile Include="Wanted\CutoffModule.cs" />
|
||||
<Compile Include="Wanted\LegacyMissingModule.cs" />
|
||||
<Compile Include="Wanted\MissingModule.cs" />
|
||||
|
|
|
@ -5,6 +5,8 @@ using NzbDrone.Api.Extensions;
|
|||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Lifecycle.Commands;
|
||||
|
||||
namespace NzbDrone.Api.System
|
||||
{
|
||||
|
@ -15,12 +17,14 @@ namespace NzbDrone.Api.System
|
|||
private readonly IRouteCacheProvider _routeCacheProvider;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IDatabase _database;
|
||||
private readonly ILifecycleService _lifecycleService;
|
||||
|
||||
public SystemModule(IAppFolderInfo appFolderInfo,
|
||||
IRuntimeInfo runtimeInfo,
|
||||
IRouteCacheProvider routeCacheProvider,
|
||||
IConfigFileProvider configFileProvider,
|
||||
IDatabase database)
|
||||
IDatabase database,
|
||||
ILifecycleService lifecycleService)
|
||||
: base("system")
|
||||
{
|
||||
_appFolderInfo = appFolderInfo;
|
||||
|
@ -28,8 +32,11 @@ namespace NzbDrone.Api.System
|
|||
_routeCacheProvider = routeCacheProvider;
|
||||
_configFileProvider = configFileProvider;
|
||||
_database = database;
|
||||
_lifecycleService = lifecycleService;
|
||||
Get["/status"] = x => GetStatus();
|
||||
Get["/routes"] = x => GetRoutes();
|
||||
Post["/shutdown"] = x => Shutdown();
|
||||
Post["/restart"] = x => Restart();
|
||||
}
|
||||
|
||||
private Response GetStatus()
|
||||
|
@ -62,5 +69,18 @@ namespace NzbDrone.Api.System
|
|||
{
|
||||
return _routeCacheProvider.GetCache().Values.AsResponse();
|
||||
}
|
||||
|
||||
private Response Shutdown()
|
||||
{
|
||||
_lifecycleService.Shutdown();
|
||||
return "".AsResponse();
|
||||
}
|
||||
|
||||
private Response Restart()
|
||||
{
|
||||
_lifecycleService.Restart();
|
||||
return "".AsResponse();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Core.Update;
|
||||
using NzbDrone.Api.Mapping;
|
||||
|
@ -44,18 +41,4 @@ namespace NzbDrone.Api.Update
|
|||
return resources;
|
||||
}
|
||||
}
|
||||
|
||||
public class UpdateResource : RestResource
|
||||
{
|
||||
[JsonConverter(typeof(Newtonsoft.Json.Converters.VersionConverter))]
|
||||
public Version Version { get; set; }
|
||||
|
||||
public String Branch { get; set; }
|
||||
public DateTime ReleaseDate { get; set; }
|
||||
public String FileName { get; set; }
|
||||
public String Url { get; set; }
|
||||
public Boolean IsUpgrade { get; set; }
|
||||
public Boolean Installed { get; set; }
|
||||
public UpdateChanges Changes { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.Update;
|
||||
|
||||
namespace NzbDrone.Api.Update
|
||||
{
|
||||
public class UpdateResource : RestResource
|
||||
{
|
||||
[JsonConverter(typeof(Newtonsoft.Json.Converters.VersionConverter))]
|
||||
public Version Version { get; set; }
|
||||
|
||||
public String Branch { get; set; }
|
||||
public DateTime ReleaseDate { get; set; }
|
||||
public String FileName { get; set; }
|
||||
public String Url { get; set; }
|
||||
public Boolean IsUpgrade { get; set; }
|
||||
public Boolean Installed { get; set; }
|
||||
public UpdateChanges Changes { get; set; }
|
||||
public String Hash { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Model;
|
||||
|
@ -18,18 +19,26 @@ namespace NzbDrone.App.Test
|
|||
{
|
||||
Mocker.GetMock<IProcessProvider>().Setup(c => c.GetCurrentProcess())
|
||||
.Returns(new ProcessInfo() { Id = CURRENT_PROCESS_ID });
|
||||
|
||||
Mocker.GetMock<IProcessProvider>()
|
||||
.Setup(s => s.FindProcessByName(ProcessProvider.NZB_DRONE_CONSOLE_PROCESS_NAME))
|
||||
.Returns(new List<ProcessInfo>());
|
||||
|
||||
Mocker.GetMock<IProcessProvider>()
|
||||
.Setup(s => s.FindProcessByName(ProcessProvider.NZB_DRONE_PROCESS_NAME))
|
||||
.Returns(new List<ProcessInfo>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_continue_if_only_instance()
|
||||
{
|
||||
Mocker.GetMock<INzbDroneProcessProvider>().Setup(c => c.FindNzbDroneProcesses())
|
||||
Mocker.GetMock<IProcessProvider>()
|
||||
.Setup(c => c.FindProcessByName(It.Is<String>(f => f.Contains("NzbDrone"))))
|
||||
.Returns(new List<ProcessInfo>
|
||||
{
|
||||
new ProcessInfo{Id = CURRENT_PROCESS_ID}
|
||||
new ProcessInfo {Id = CURRENT_PROCESS_ID}
|
||||
});
|
||||
|
||||
|
||||
Subject.PreventStartIfAlreadyRunning();
|
||||
|
||||
Mocker.GetMock<IBrowserService>().Verify(c => c.LaunchWebUI(), Times.Never());
|
||||
|
@ -38,12 +47,12 @@ namespace NzbDrone.App.Test
|
|||
[Test]
|
||||
public void should_enforce_if_another_console_is_running()
|
||||
{
|
||||
Mocker.GetMock<INzbDroneProcessProvider>()
|
||||
.Setup(c => c.FindNzbDroneProcesses())
|
||||
Mocker.GetMock<IProcessProvider>()
|
||||
.Setup(c => c.FindProcessByName(ProcessProvider.NZB_DRONE_CONSOLE_PROCESS_NAME))
|
||||
.Returns(new List<ProcessInfo>
|
||||
{
|
||||
new ProcessInfo{Id = 10},
|
||||
new ProcessInfo{Id = CURRENT_PROCESS_ID}
|
||||
new ProcessInfo {Id = 10},
|
||||
new ProcessInfo {Id = CURRENT_PROCESS_ID}
|
||||
});
|
||||
|
||||
Assert.Throws<TerminateApplicationException>(() => Subject.PreventStartIfAlreadyRunning());
|
||||
|
@ -54,12 +63,12 @@ namespace NzbDrone.App.Test
|
|||
[Test]
|
||||
public void should_return_false_if_another_gui_is_running()
|
||||
{
|
||||
Mocker.GetMock<INzbDroneProcessProvider>()
|
||||
.Setup(c => c.FindNzbDroneProcesses())
|
||||
Mocker.GetMock<IProcessProvider>()
|
||||
.Setup(c => c.FindProcessByName(ProcessProvider.NZB_DRONE_PROCESS_NAME))
|
||||
.Returns(new List<ProcessInfo>
|
||||
{
|
||||
new ProcessInfo{Id = CURRENT_PROCESS_ID},
|
||||
new ProcessInfo{Id = 10}
|
||||
new ProcessInfo {Id = CURRENT_PROCESS_ID},
|
||||
new ProcessInfo {Id = 10}
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -52,15 +52,17 @@
|
|||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="WebDriver">
|
||||
<HintPath>..\packages\Selenium.WebDriver.2.37.0\lib\net40\WebDriver.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WebDriver.Support">
|
||||
<HintPath>..\packages\Selenium.Support.2.37.0\lib\net40\WebDriver.Support.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FluentAssertions">
|
||||
<HintPath>..\packages\FluentAssertions.2.1.0.0\lib\net40\FluentAssertions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WebDriver, Version=2.41.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Selenium.WebDriver.2.41.0\lib\net40\WebDriver.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WebDriver.Support, Version=2.41.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Selenium.Support.2.41.0\lib\net40\WebDriver.Support.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AutomationTestAttribute.cs" />
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace NzbDrone.Automation.Test.PageModel
|
|||
public PageBase(RemoteWebDriver driver)
|
||||
{
|
||||
_driver = driver;
|
||||
driver.Manage().Window.Maximize();
|
||||
}
|
||||
|
||||
public IWebElement FindByClass(string className, int timeout = 5)
|
||||
|
@ -52,7 +53,7 @@ namespace NzbDrone.Automation.Test.PageModel
|
|||
{
|
||||
get
|
||||
{
|
||||
return Find(By.LinkText("Series"));
|
||||
return FindByClass("x-series-nav");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,7 +61,7 @@ namespace NzbDrone.Automation.Test.PageModel
|
|||
{
|
||||
get
|
||||
{
|
||||
return Find(By.LinkText("Calendar"));
|
||||
return FindByClass("x-calendar-nav");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,7 +69,7 @@ namespace NzbDrone.Automation.Test.PageModel
|
|||
{
|
||||
get
|
||||
{
|
||||
return Find(By.LinkText("History"));
|
||||
return FindByClass("x-history-nav");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,7 +77,7 @@ namespace NzbDrone.Automation.Test.PageModel
|
|||
{
|
||||
get
|
||||
{
|
||||
return Find(By.LinkText("Wanted"));
|
||||
return FindByClass("x-wanted-nav");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,7 +85,7 @@ namespace NzbDrone.Automation.Test.PageModel
|
|||
{
|
||||
get
|
||||
{
|
||||
return Find(By.LinkText("Settings"));
|
||||
return FindByClass("x-settings-nav");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,7 +93,7 @@ namespace NzbDrone.Automation.Test.PageModel
|
|||
{
|
||||
get
|
||||
{
|
||||
return Find(By.PartialLinkText("System"));
|
||||
return FindByClass("x-system-nav");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
<package id="FluentAssertions" version="2.1.0.0" targetFramework="net40" />
|
||||
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||
<package id="NUnit" version="2.6.2" targetFramework="net40" />
|
||||
<package id="Selenium.Support" version="2.37.0" targetFramework="net40" />
|
||||
<package id="Selenium.WebDriver" version="2.37.0" targetFramework="net40" />
|
||||
<package id="Selenium.Support" version="2.41.0" targetFramework="net40" />
|
||||
<package id="Selenium.WebDriver" version="2.41.0" targetFramework="net40" />
|
||||
</packages>
|
|
@ -10,30 +10,26 @@ namespace NzbDrone.Common.Test.DiskProviderTests
|
|||
{
|
||||
public class DiskProviderFixtureBase<TSubject> : TestBase<TSubject> where TSubject : class, IDiskProvider
|
||||
{
|
||||
DirectoryInfo _binFolder;
|
||||
DirectoryInfo _binFolderCopy;
|
||||
DirectoryInfo _binFolderMove;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_binFolder = new DirectoryInfo(Directory.GetCurrentDirectory());
|
||||
_binFolderCopy = new DirectoryInfo(Path.Combine(_binFolder.Parent.FullName, "bin_copy"));
|
||||
_binFolderMove = new DirectoryInfo(Path.Combine(_binFolder.Parent.FullName, "bin_move"));
|
||||
|
||||
if (_binFolderCopy.Exists)
|
||||
{
|
||||
foreach (var file in _binFolderCopy.GetFiles("*", SearchOption.AllDirectories))
|
||||
{
|
||||
file.Attributes = FileAttributes.Normal;
|
||||
}
|
||||
_binFolderCopy.Delete(true);
|
||||
}
|
||||
|
||||
if (_binFolderMove.Exists)
|
||||
public DirectoryInfo GetFilledTempFolder()
|
||||
{
|
||||
_binFolderMove.Delete(true);
|
||||
}
|
||||
var tempFolder = GetTempFilePath();
|
||||
Directory.CreateDirectory(tempFolder);
|
||||
|
||||
File.WriteAllText(Path.Combine(tempFolder, Path.GetRandomFileName()), "RootFile");
|
||||
|
||||
var subDir = Path.Combine(tempFolder, Path.GetRandomFileName());
|
||||
Directory.CreateDirectory(subDir);
|
||||
|
||||
File.WriteAllText(Path.Combine(subDir, Path.GetRandomFileName()), "SubFile1");
|
||||
File.WriteAllText(Path.Combine(subDir, Path.GetRandomFileName()), "SubFile2");
|
||||
|
||||
return new DirectoryInfo(tempFolder);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -57,79 +53,94 @@ namespace NzbDrone.Common.Test.DiskProviderTests
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void moveFile_should_overwrite_existing_file()
|
||||
public void MoveFile_should_overwrite_existing_file()
|
||||
{
|
||||
var source1 = GetTempFilePath();
|
||||
var source2 = GetTempFilePath();
|
||||
var destination = GetTempFilePath();
|
||||
|
||||
Subject.CopyFolder(_binFolder.FullName, _binFolderCopy.FullName);
|
||||
File.WriteAllText(source1, "SourceFile1");
|
||||
File.WriteAllText(source2, "SourceFile2");
|
||||
|
||||
var targetPath = Path.Combine(_binFolderCopy.FullName, "file.move");
|
||||
Subject.MoveFile(source1, destination);
|
||||
Subject.MoveFile(source2, destination);
|
||||
|
||||
Subject.MoveFile(_binFolderCopy.GetFiles("*.dll", SearchOption.AllDirectories).First().FullName, targetPath);
|
||||
Subject.MoveFile(_binFolderCopy.GetFiles("*.pdb", SearchOption.AllDirectories).First().FullName, targetPath);
|
||||
|
||||
File.Exists(targetPath).Should().BeTrue();
|
||||
File.Exists(destination).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void moveFile_should_not_move_overwrite_itself()
|
||||
public void MoveFile_should_not_move_overwrite_itself()
|
||||
{
|
||||
var source = GetTempFilePath();
|
||||
|
||||
Subject.CopyFolder(_binFolder.FullName, _binFolderCopy.FullName);
|
||||
File.WriteAllText(source, "SourceFile1");
|
||||
|
||||
var targetPath = _binFolderCopy.GetFiles("*.dll", SearchOption.AllDirectories).First().FullName;
|
||||
Subject.MoveFile(source, source);
|
||||
|
||||
Subject.MoveFile(targetPath, targetPath);
|
||||
|
||||
File.Exists(targetPath).Should().BeTrue();
|
||||
File.Exists(source).Should().BeTrue();
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyFolder_should_copy_folder()
|
||||
{
|
||||
Subject.CopyFolder(_binFolder.FullName, _binFolderCopy.FullName);
|
||||
VerifyCopy();
|
||||
var source = GetFilledTempFolder();
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
|
||||
Subject.CopyFolder(source.FullName, destination.FullName);
|
||||
|
||||
VerifyCopy(source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyFolder_should_overwrite_existing_folder()
|
||||
{
|
||||
|
||||
|
||||
|
||||
Subject.CopyFolder(_binFolder.FullName, _binFolderCopy.FullName);
|
||||
var source = GetFilledTempFolder();
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
Subject.CopyFolder(source.FullName, destination.FullName);
|
||||
|
||||
//Delete Random File
|
||||
_binFolderCopy.Refresh();
|
||||
_binFolderCopy.GetFiles("*.*", SearchOption.AllDirectories).First().Delete();
|
||||
destination.GetFiles("*.*", SearchOption.AllDirectories).First().Delete();
|
||||
|
||||
Subject.CopyFolder(_binFolder.FullName, _binFolderCopy.FullName);
|
||||
Subject.CopyFolder(source.FullName, destination.FullName);
|
||||
|
||||
VerifyCopy(source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
VerifyCopy();
|
||||
[Test]
|
||||
public void MoveFolder_should_move_folder()
|
||||
{
|
||||
var original = GetFilledTempFolder();
|
||||
var source = new DirectoryInfo(GetTempFilePath());
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
|
||||
Subject.CopyFolder(original.FullName, source.FullName);
|
||||
|
||||
Subject.MoveFolder(source.FullName, destination.FullName);
|
||||
|
||||
VerifyMove(original.FullName, source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MoveFolder_should_overwrite_existing_folder()
|
||||
{
|
||||
var original = GetFilledTempFolder();
|
||||
var source = new DirectoryInfo(GetTempFilePath());
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
|
||||
Subject.CopyFolder(original.FullName, source.FullName);
|
||||
Subject.CopyFolder(original.FullName, destination.FullName);
|
||||
|
||||
Subject.CopyFolder(_binFolder.FullName, _binFolderCopy.FullName);
|
||||
Subject.CopyFolder(_binFolder.FullName, _binFolderMove.FullName);
|
||||
VerifyCopy();
|
||||
Subject.MoveFolder(source.FullName, destination.FullName);
|
||||
|
||||
|
||||
Subject.MoveFolder(_binFolderCopy.FullName, _binFolderMove.FullName);
|
||||
|
||||
|
||||
VerifyMove();
|
||||
VerifyMove(original.FullName, source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void move_read_only_file()
|
||||
{
|
||||
var source = GetTestFilePath();
|
||||
var destination = GetTestFilePath();
|
||||
var source = GetTempFilePath();
|
||||
var destination = GetTempFilePath();
|
||||
|
||||
Subject.WriteAllText(source, "SourceFile");
|
||||
Subject.WriteAllText(destination, "DestinationFile");
|
||||
|
@ -150,23 +161,25 @@ namespace NzbDrone.Common.Test.DiskProviderTests
|
|||
[Test]
|
||||
public void folder_should_return_correct_value_for_last_write()
|
||||
{
|
||||
var testDir = Path.Combine(SandboxFolder, "LastWrite");
|
||||
var testDir = GetTempFilePath();
|
||||
var testFile = Path.Combine(testDir, Path.GetRandomFileName());
|
||||
|
||||
Directory.CreateDirectory(testDir);
|
||||
|
||||
Subject.FolderSetLastWriteTimeUtc(TempFolder, DateTime.UtcNow.AddMinutes(-5));
|
||||
|
||||
TestLogger.Info("Path is: {0}", testFile);
|
||||
|
||||
Subject.WriteAllText(testFile, "Test");
|
||||
|
||||
Subject.FolderGetLastWrite(SandboxFolder).Should().BeOnOrAfter(DateTime.UtcNow.AddMinutes(-1));
|
||||
Subject.FolderGetLastWrite(SandboxFolder).Should().BeBefore(DateTime.UtcNow.AddMinutes(1));
|
||||
Subject.FolderGetLastWrite(TempFolder).Should().BeOnOrAfter(DateTime.UtcNow.AddMinutes(-1));
|
||||
Subject.FolderGetLastWrite(TempFolder).Should().BeBefore(DateTime.UtcNow.AddMinutes(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_for_unlocked_file()
|
||||
{
|
||||
var testFile = GetTestFilePath();
|
||||
var testFile = GetTempFilePath();
|
||||
Subject.WriteAllText(testFile, new Guid().ToString());
|
||||
|
||||
Subject.IsFileLocked(testFile).Should().BeFalse();
|
||||
|
@ -175,7 +188,7 @@ namespace NzbDrone.Common.Test.DiskProviderTests
|
|||
[Test]
|
||||
public void should_return_false_for_unlocked_and_readonly_file()
|
||||
{
|
||||
var testFile = GetTestFilePath();
|
||||
var testFile = GetTempFilePath();
|
||||
Subject.WriteAllText(testFile, new Guid().ToString());
|
||||
|
||||
File.SetAttributes(testFile, FileAttributes.ReadOnly);
|
||||
|
@ -186,7 +199,7 @@ namespace NzbDrone.Common.Test.DiskProviderTests
|
|||
[Test]
|
||||
public void should_return_true_for_unlocked_file()
|
||||
{
|
||||
var testFile = GetTestFilePath();
|
||||
var testFile = GetTempFilePath();
|
||||
Subject.WriteAllText(testFile, new Guid().ToString());
|
||||
|
||||
using (var file = File.OpenWrite(testFile))
|
||||
|
@ -198,7 +211,7 @@ namespace NzbDrone.Common.Test.DiskProviderTests
|
|||
[Test]
|
||||
public void should_be_able_to_set_permission_from_parrent()
|
||||
{
|
||||
var testFile = GetTestFilePath();
|
||||
var testFile = GetTempFilePath();
|
||||
Subject.WriteAllText(testFile, new Guid().ToString());
|
||||
|
||||
Subject.InheritFolderPermissions(testFile);
|
||||
|
@ -208,33 +221,26 @@ namespace NzbDrone.Common.Test.DiskProviderTests
|
|||
[Explicit]
|
||||
public void check_last_write()
|
||||
{
|
||||
Console.WriteLine(Subject.FolderGetLastWrite(_binFolder.FullName));
|
||||
Console.WriteLine(_binFolder.LastWriteTimeUtc);
|
||||
Console.WriteLine(Subject.FolderGetLastWrite(GetFilledTempFolder().FullName));
|
||||
Console.WriteLine(GetFilledTempFolder().LastWriteTimeUtc);
|
||||
}
|
||||
|
||||
private void VerifyCopy()
|
||||
private void VerifyCopy(string source, string destination)
|
||||
{
|
||||
_binFolder.Refresh();
|
||||
_binFolderCopy.Refresh();
|
||||
var sourceFiles = Directory.GetFileSystemEntries(source, "*", SearchOption.AllDirectories).Select(v => v.Substring(source.Length + 1)).ToArray();
|
||||
var destFiles = Directory.GetFileSystemEntries(destination, "*", SearchOption.AllDirectories).Select(v => v.Substring(destination.Length + 1)).ToArray();
|
||||
|
||||
_binFolderCopy.GetFiles("*.*", SearchOption.AllDirectories)
|
||||
.Should().HaveSameCount(_binFolder.GetFiles("*.*", SearchOption.AllDirectories));
|
||||
|
||||
_binFolderCopy.GetDirectories().Should().HaveSameCount(_binFolder.GetDirectories());
|
||||
CollectionAssert.AreEquivalent(sourceFiles, destFiles);
|
||||
}
|
||||
|
||||
private void VerifyMove()
|
||||
private void VerifyMove(string source, string from, string destination)
|
||||
{
|
||||
_binFolder.Refresh();
|
||||
_binFolderCopy.Refresh();
|
||||
_binFolderMove.Refresh();
|
||||
Directory.Exists(from).Should().BeFalse();
|
||||
|
||||
_binFolderCopy.Exists.Should().BeFalse();
|
||||
var sourceFiles = Directory.GetFileSystemEntries(source, "*", SearchOption.AllDirectories).Select(v => v.Substring(source.Length + 1)).ToArray();
|
||||
var destFiles = Directory.GetFileSystemEntries(destination, "*", SearchOption.AllDirectories).Select(v => v.Substring(destination.Length + 1)).ToArray();
|
||||
|
||||
_binFolderMove.GetFiles("*.*", SearchOption.AllDirectories)
|
||||
.Should().HaveSameCount(_binFolder.GetFiles("*.*", SearchOption.AllDirectories));
|
||||
|
||||
_binFolderMove.GetDirectories().Should().HaveSameCount(_binFolder.GetDirectories());
|
||||
CollectionAssert.AreEquivalent(sourceFiles, destFiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Disk;
|
||||
|
@ -61,7 +62,17 @@ namespace NzbDrone.Common.Test.DiskProviderTests
|
|||
{
|
||||
WindowsOnly();
|
||||
|
||||
Assert.Throws<DirectoryNotFoundException>(() => Subject.GetAvailableSpace(@"Z:\NOT_A_REAL_PATH\DOES_NOT_EXIST".AsOsAgnostic()));
|
||||
// Find a drive that doesn't exist.
|
||||
for (char driveletter = 'Z'; driveletter > 'D' ; driveletter--)
|
||||
{
|
||||
if (new DriveInfo(driveletter.ToString()).IsReady)
|
||||
continue;
|
||||
|
||||
Assert.Throws<DirectoryNotFoundException>(() => Subject.GetAvailableSpace(driveletter + @":\NOT_A_REAL_PATH\DOES_NOT_EXIST".AsOsAgnostic()));
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.Inconclusive("No drive available for testing.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -120,7 +120,7 @@ namespace NzbDrone.Common.Test
|
|||
public void get_actual_casing_should_return_actual_casing_for_local_file_in_windows()
|
||||
{
|
||||
WindowsOnly();
|
||||
var path = Process.GetCurrentProcess().MainModule.FileName;
|
||||
var path = Environment.ExpandEnvironmentVariables("%SystemRoot%\\System32");
|
||||
path.ToUpper().GetActualCasing().Should().Be(path);
|
||||
path.ToLower().GetActualCasing().Should().Be(path);
|
||||
}
|
||||
|
@ -168,25 +168,25 @@ namespace NzbDrone.Common.Test
|
|||
[Test]
|
||||
public void Sanbox()
|
||||
{
|
||||
GetIAppDirectoryInfo().GetUpdateSandboxFolder().Should().BeEquivalentTo(@"C:\Temp\Nzbdrone_update\".AsOsAgnostic());
|
||||
GetIAppDirectoryInfo().GetUpdateSandboxFolder().Should().BeEquivalentTo(@"C:\Temp\nzbdrone_update\".AsOsAgnostic());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetUpdatePackageFolder()
|
||||
{
|
||||
GetIAppDirectoryInfo().GetUpdatePackageFolder().Should().BeEquivalentTo(@"C:\Temp\Nzbdrone_update\NzbDrone\".AsOsAgnostic());
|
||||
GetIAppDirectoryInfo().GetUpdatePackageFolder().Should().BeEquivalentTo(@"C:\Temp\nzbdrone_update\NzbDrone\".AsOsAgnostic());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetUpdateClientFolder()
|
||||
{
|
||||
GetIAppDirectoryInfo().GetUpdateClientFolder().Should().BeEquivalentTo(@"C:\Temp\Nzbdrone_update\NzbDrone\NzbDrone.Update\".AsOsAgnostic());
|
||||
GetIAppDirectoryInfo().GetUpdateClientFolder().Should().BeEquivalentTo(@"C:\Temp\nzbdrone_update\NzbDrone\NzbDrone.Update\".AsOsAgnostic());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetUpdateClientExePath()
|
||||
{
|
||||
GetIAppDirectoryInfo().GetUpdateClientExePath().Should().BeEquivalentTo(@"C:\Temp\Nzbdrone_update\NzbDrone.Update.exe".AsOsAgnostic());
|
||||
GetIAppDirectoryInfo().GetUpdateClientExePath().Should().BeEquivalentTo(@"C:\Temp\nzbdrone_update\NzbDrone.Update.exe".AsOsAgnostic());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Common.Test
|
||||
|
|
|
@ -447,5 +447,15 @@ namespace NzbDrone.Common.Disk
|
|||
|
||||
return driveInfo.VolumeLabel;
|
||||
}
|
||||
|
||||
public FileStream StreamFile(string path)
|
||||
{
|
||||
if (!FileExists(path))
|
||||
{
|
||||
throw new FileNotFoundException("Unable to find file: " + path, path);
|
||||
}
|
||||
|
||||
return new FileStream(path, FileMode.Open);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ namespace NzbDrone.Common.Disk
|
|||
void InheritFolderPermissions(string filename);
|
||||
void SetPermissions(string path, string mask, string user, string group);
|
||||
long? GetTotalSize(string path);
|
||||
|
||||
DateTime FolderGetLastWrite(string path);
|
||||
DateTime FileGetLastWrite(string path);
|
||||
DateTime FileGetLastWriteUtc(string path);
|
||||
|
@ -44,5 +43,6 @@ namespace NzbDrone.Common.Disk
|
|||
void EmptyFolder(string path);
|
||||
string[] GetFixedDrives();
|
||||
string GetVolumeLabel(string path);
|
||||
FileStream StreamFile(string path);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NzbDrone.Common.EnvironmentInfo
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@ using System.Text;
|
|||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Common
|
||||
namespace NzbDrone.Common.Http
|
||||
{
|
||||
public interface IHttpProvider
|
||||
{
|
||||
|
@ -15,7 +15,6 @@ namespace NzbDrone.Common
|
|||
string DownloadString(string url, string username, string password);
|
||||
string DownloadString(string url, ICredentials credentials);
|
||||
Dictionary<string, string> GetHeader(string url);
|
||||
|
||||
Stream DownloadStream(string url, NetworkCredential credential = null);
|
||||
void DownloadFile(string url, string fileName);
|
||||
string PostCommand(string address, string username, string password, string command);
|
||||
|
@ -33,6 +32,7 @@ namespace NzbDrone.Common
|
|||
{
|
||||
_logger = logger;
|
||||
_userAgent = String.Format("NzbDrone {0}", BuildInfo.Version);
|
||||
ServicePointManager.Expect100Continue = false;
|
||||
}
|
||||
|
||||
public string DownloadString(string url)
|
||||
|
@ -132,8 +132,9 @@ namespace NzbDrone.Common
|
|||
|
||||
byte[] byteArray = Encoding.ASCII.GetBytes(command);
|
||||
|
||||
var wc = new WebClient();
|
||||
var wc = new NzbDroneWebClient();
|
||||
wc.Credentials = new NetworkCredential(username, password);
|
||||
|
||||
var response = wc.UploadData(address, "POST", byteArray);
|
||||
var text = Encoding.ASCII.GetString(response);
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
|
||||
namespace NzbDrone.Common.Http
|
||||
{
|
||||
public class NzbDroneWebClient : WebClient
|
||||
{
|
||||
protected override WebRequest GetWebRequest(Uri address)
|
||||
{
|
||||
var request = base.GetWebRequest(address);
|
||||
if (request is HttpWebRequest)
|
||||
{
|
||||
((HttpWebRequest)request).KeepAlive = false;
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,5 +12,15 @@ namespace NzbDrone.Common
|
|||
|
||||
return source.Where(element => knownKeys.Add(keySelector(element)));
|
||||
}
|
||||
|
||||
public static void AddIfNotNull<TSource>(this List<TSource> source, TSource item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
source.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace NzbDrone.Common.Instrumentation
|
||||
{
|
||||
public class CleanseLogMessage
|
||||
{
|
||||
//TODO: remove password=
|
||||
private static readonly Regex CleansingRegex = new Regex(@"(?<=apikey=)(\w+?)(?=\W|$|_)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
public static string Cleanse(string message)
|
||||
{
|
||||
if (message.IsNullOrWhiteSpace())
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
return CleansingRegex.Replace(message, "<removed>");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -78,7 +78,7 @@ namespace NzbDrone.Common.Instrumentation
|
|||
|
||||
private static void RegisterAppFile(IAppFolderInfo appFolderInfo)
|
||||
{
|
||||
var fileTarget = new FileTarget();
|
||||
var fileTarget = new NzbDroneFileTarget();
|
||||
|
||||
fileTarget.Name = "rollingFileLogger";
|
||||
fileTarget.FileName = Path.Combine(appFolderInfo.GetLogFolder(), "nzbdrone.txt");
|
||||
|
@ -104,7 +104,7 @@ namespace NzbDrone.Common.Instrumentation
|
|||
var fileTarget = new FileTarget();
|
||||
|
||||
fileTarget.Name = "updateFileLogger";
|
||||
fileTarget.FileName = Path.Combine(appFolderInfo.GetUpdateLogFolder(), DateTime.Now.ToString("yy.MM.d-HH.mm") + ".txt");
|
||||
fileTarget.FileName = Path.Combine(appFolderInfo.GetUpdateLogFolder(), DateTime.Now.ToString("yyyy.MM.dd-HH.mm") + ".txt");
|
||||
fileTarget.AutoFlush = true;
|
||||
fileTarget.KeepFileOpen = false;
|
||||
fileTarget.ConcurrentWrites = false;
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
using NLog;
|
||||
using NLog.Targets;
|
||||
|
||||
namespace NzbDrone.Common.Instrumentation
|
||||
{
|
||||
public class NzbDroneFileTarget : FileTarget
|
||||
{
|
||||
protected override string GetFormattedMessage(LogEventInfo logEvent)
|
||||
{
|
||||
return CleanseLogMessage.Cleanse(Layout.Render(logEvent));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,7 +61,7 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="ArchiveProvider.cs" />
|
||||
<Compile Include="Cache\Cached.cs" />
|
||||
<Compile Include="Cache\CacheManger.cs" />
|
||||
<Compile Include="Cache\CacheManager.cs" />
|
||||
<Compile Include="Cache\ICached.cs" />
|
||||
<Compile Include="Composition\Container.cs" />
|
||||
<Compile Include="Composition\IContainer.cs" />
|
||||
|
@ -93,16 +93,20 @@
|
|||
<Compile Include="EnvironmentInfo\OsInfo.cs" />
|
||||
<Compile Include="Exceptions\NotParentException.cs" />
|
||||
<Compile Include="Exceptions\NzbDroneException.cs" />
|
||||
<Compile Include="Http\NzbDroneWebClient.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="IEnumerableExtensions.cs" />
|
||||
<Compile Include="Instrumentation\CleanseLogMessage.cs" />
|
||||
<Compile Include="Instrumentation\GlobalExceptionHandlers.cs" />
|
||||
<Compile Include="Instrumentation\ExceptronTarget.cs" />
|
||||
<Compile Include="Instrumentation\LogEventExtensions.cs" />
|
||||
<Compile Include="Instrumentation\NzbDroneFileTarget.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="Processes\INzbDroneProcessProvider.cs" />
|
||||
<Compile Include="Processes\PidFileProvider.cs" />
|
||||
<Compile Include="Processes\ProcessOutput.cs" />
|
||||
<Compile Include="RateGate.cs" />
|
||||
|
@ -125,7 +129,7 @@
|
|||
<Compile Include="Instrumentation\VersionLayoutRenderer.cs" />
|
||||
<Compile Include="Reflection\ReflectionExtensions.cs" />
|
||||
<Compile Include="ServiceFactory.cs" />
|
||||
<Compile Include="HttpProvider.cs" />
|
||||
<Compile Include="Http\HttpProvider.cs" />
|
||||
<Compile Include="ConsoleService.cs" />
|
||||
<Compile Include="PathExtensions.cs" />
|
||||
<Compile Include="Disk\IDiskProvider.cs" />
|
||||
|
|
|
@ -13,10 +13,10 @@ namespace NzbDrone.Common
|
|||
private const string NZBDRONE_LOG_DB = "logs.db";
|
||||
private const string BACKUP_ZIP_FILE = "NzbDrone_Backup.zip";
|
||||
private const string NLOG_CONFIG_FILE = "nlog.config";
|
||||
private const string UPDATE_CLIENT_EXE = "nzbdrone.update.exe";
|
||||
private const string UPDATE_CLIENT_EXE = "NzbDrone.Update.exe";
|
||||
|
||||
private static readonly string UPDATE_SANDBOX_FOLDER_NAME = "nzbdrone_update" + Path.DirectorySeparatorChar;
|
||||
private static readonly string UPDATE_PACKAGE_FOLDER_NAME = "nzbdrone" + Path.DirectorySeparatorChar;
|
||||
private static readonly string UPDATE_PACKAGE_FOLDER_NAME = "NzbDrone" + Path.DirectorySeparatorChar;
|
||||
private static readonly string UPDATE_BACKUP_FOLDER_NAME = "nzbdrone_backup" + Path.DirectorySeparatorChar;
|
||||
private static readonly string UPDATE_BACKUP_APPDATA_FOLDER_NAME = "nzbdrone_appdata_backup" + Path.DirectorySeparatorChar;
|
||||
private static readonly string UPDATE_CLIENT_FOLDER_NAME = "NzbDrone.Update" + Path.DirectorySeparatorChar;
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using NzbDrone.Common.Model;
|
||||
|
||||
namespace NzbDrone.Common.Processes
|
||||
{
|
||||
public interface INzbDroneProcessProvider
|
||||
{
|
||||
List<ProcessInfo> FindNzbDroneProcesses();
|
||||
}
|
||||
}
|
|
@ -21,7 +21,8 @@ namespace NzbDrone.Common.Processes
|
|||
void SetPriority(int processId, ProcessPriorityClass priority);
|
||||
void KillAll(string processName);
|
||||
void Kill(int processId);
|
||||
bool Exists(string processName);
|
||||
Boolean Exists(int processId);
|
||||
Boolean Exists(string processName);
|
||||
ProcessPriorityClass GetCurrentProcessPriority();
|
||||
Process Start(string path, string args = null, Action<string> onOutputDataReceived = null, Action<string> onErrorDataReceived = null);
|
||||
Process SpawnNewProcess(string path, string args = null);
|
||||
|
@ -35,20 +36,17 @@ namespace NzbDrone.Common.Processes
|
|||
public const string NZB_DRONE_PROCESS_NAME = "NzbDrone";
|
||||
public const string NZB_DRONE_CONSOLE_PROCESS_NAME = "NzbDrone.Console";
|
||||
|
||||
private static List<Process> GetProcessesByName(string name)
|
||||
{
|
||||
var monoProcesses = Process.GetProcessesByName("mono")
|
||||
.Where(process => process.Modules.Cast<ProcessModule>().Any(module => module.ModuleName.ToLower() == name.ToLower() + ".exe"));
|
||||
return Process.GetProcessesByName(name)
|
||||
.Union(monoProcesses).ToList();
|
||||
}
|
||||
|
||||
public ProcessInfo GetCurrentProcess()
|
||||
{
|
||||
return ConvertToProcessInfo(Process.GetCurrentProcess());
|
||||
}
|
||||
|
||||
public bool Exists(string processName)
|
||||
public bool Exists(int processId)
|
||||
{
|
||||
return GetProcessById(processId) != null;
|
||||
}
|
||||
|
||||
public Boolean Exists(string processName)
|
||||
{
|
||||
return GetProcessesByName(processName).Any();
|
||||
}
|
||||
|
@ -78,7 +76,7 @@ namespace NzbDrone.Common.Processes
|
|||
|
||||
public List<ProcessInfo> FindProcessByName(string name)
|
||||
{
|
||||
return Process.GetProcessesByName(name).Select(ConvertToProcessInfo).Where(c => c != null).ToList();
|
||||
return GetProcessesByName(name).Select(ConvertToProcessInfo).Where(c => c != null).ToList();
|
||||
}
|
||||
|
||||
public void OpenDefaultBrowser(string url)
|
||||
|
@ -203,12 +201,40 @@ namespace NzbDrone.Common.Processes
|
|||
process.PriorityClass = priority;
|
||||
}
|
||||
|
||||
public void Kill(int processId)
|
||||
{
|
||||
var process = Process.GetProcesses().FirstOrDefault(p => p.Id == processId);
|
||||
|
||||
if (process == null)
|
||||
{
|
||||
Logger.Warn("Cannot find process with id: {0}", processId);
|
||||
return;
|
||||
}
|
||||
|
||||
process.Refresh();
|
||||
|
||||
if (process.HasExited)
|
||||
{
|
||||
Logger.Debug("Process has already exited");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.Info("[{0}]: Killing process", process.Id);
|
||||
process.Kill();
|
||||
Logger.Info("[{0}]: Waiting for exit", process.Id);
|
||||
process.WaitForExit();
|
||||
Logger.Info("[{0}]: Process terminated successfully", process.Id);
|
||||
}
|
||||
|
||||
public void KillAll(string processName)
|
||||
{
|
||||
var processToKill = GetProcessesByName(processName);
|
||||
var processes = GetProcessesByName(processName);
|
||||
|
||||
foreach (var processInfo in processToKill)
|
||||
Logger.Debug("Found {0} processes to kill", processes.Count);
|
||||
|
||||
foreach (var processInfo in processes)
|
||||
{
|
||||
Logger.Debug("Killing process: {0} [{1}]", processInfo.Id, processInfo.ProcessName);
|
||||
Kill(processInfo.Id);
|
||||
}
|
||||
}
|
||||
|
@ -254,29 +280,23 @@ namespace NzbDrone.Common.Processes
|
|||
return process.Modules.Cast<ProcessModule>().FirstOrDefault(module => module.ModuleName.ToLower().EndsWith(".exe")).FileName;
|
||||
}
|
||||
|
||||
public void Kill(int processId)
|
||||
private static List<Process> GetProcessesByName(string name)
|
||||
{
|
||||
var process = Process.GetProcesses().FirstOrDefault(p => p.Id == processId);
|
||||
//TODO: move this to an OS specific class
|
||||
|
||||
if (process == null)
|
||||
{
|
||||
Logger.Warn("Cannot find process with id: {0}", processId);
|
||||
return;
|
||||
}
|
||||
var monoProcesses = Process.GetProcessesByName("mono")
|
||||
.Union(Process.GetProcessesByName("mono-sgen"))
|
||||
.Where(process =>
|
||||
process.Modules.Cast<ProcessModule>()
|
||||
.Any(module =>
|
||||
module.ModuleName.ToLower() == name.ToLower() + ".exe"));
|
||||
|
||||
process.Refresh();
|
||||
var processes = Process.GetProcessesByName(name)
|
||||
.Union(monoProcesses).ToList();
|
||||
|
||||
if (process.HasExited)
|
||||
{
|
||||
Logger.Debug("Process has already exited");
|
||||
return;
|
||||
}
|
||||
Logger.Debug("Found {0} processes with the name: {1}", processes.Count, name);
|
||||
|
||||
Logger.Info("[{0}]: Killing process", process.Id);
|
||||
process.Kill();
|
||||
Logger.Info("[{0}]: Waiting for exit", process.Id);
|
||||
process.WaitForExit();
|
||||
Logger.Info("[{0}]: Process terminated successfully", process.Id);
|
||||
return processes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,15 @@ namespace NzbDrone.Common.Security
|
|||
|
||||
private static bool ValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors)
|
||||
{
|
||||
var request = sender as HttpWebRequest;
|
||||
|
||||
if (request != null &&
|
||||
request.Address.OriginalString.ContainsIgnoreCase("nzbdrone.com") &&
|
||||
sslpolicyerrors != SslPolicyErrors.None)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Globalization;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
|
||||
namespace NzbDrone.Common
|
||||
{
|
||||
|
@ -65,5 +66,20 @@ namespace NzbDrone.Common
|
|||
{
|
||||
return String.IsNullOrWhiteSpace(text);
|
||||
}
|
||||
|
||||
public static bool ContainsIgnoreCase(this string text, string contains)
|
||||
{
|
||||
return text.IndexOf(contains, StringComparison.InvariantCultureIgnoreCase) > -1;
|
||||
}
|
||||
|
||||
public static string WrapInQuotes(this string text)
|
||||
{
|
||||
if (!text.Contains(" "))
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
return "\"" + text + "\"";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ using FluentAssertions;
|
|||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.DataAugmentation.Scene;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ using Marr.Data;
|
|||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Datastore.Converters;
|
||||
using NzbDrone.Core.Datastore.Extentions;
|
||||
using NzbDrone.Core.Datastore.Extensions;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Datastore.Extentions;
|
||||
using NzbDrone.Core.Datastore.Extensions;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.PagingSpecExtenstionsTests
|
||||
namespace NzbDrone.Core.Test.Datastore.PagingSpecExtensionsTests
|
||||
{
|
||||
public class PagingOffsetFixture
|
||||
{
|
|
@ -1,10 +1,10 @@
|
|||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Datastore.Extentions;
|
||||
using NzbDrone.Core.Datastore.Extensions;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.PagingSpecExtenstionsTests
|
||||
namespace NzbDrone.Core.Test.Datastore.PagingSpecExtensionsTests
|
||||
{
|
||||
public class ToSortDirectionFixture
|
||||
{
|
|
@ -48,7 +48,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
Series = series,
|
||||
Release = new ReleaseInfo(),
|
||||
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.SDTV, true) },
|
||||
Episodes = new List<Episode> { new Episode() }
|
||||
Episodes = new List<Episode> { new Episode() { Id = 2 } }
|
||||
|
||||
};
|
||||
|
||||
|
@ -59,13 +59,21 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
.Build();
|
||||
|
||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||
|
||||
Mocker.GetMock<IEpisodeService>().Setup(
|
||||
s => s.GetEpisodesBySeason(It.IsAny<int>(), It.IsAny<int>()))
|
||||
.Returns(new List<Episode>() {
|
||||
new Episode(), new Episode(), new Episode(), new Episode(), new Episode(),
|
||||
new Episode(), new Episode(), new Episode(), new Episode() { Id = 2 }, new Episode() });
|
||||
}
|
||||
|
||||
private void GivenLastEpisode()
|
||||
{
|
||||
Mocker.GetMock<IEpisodeService>().Setup(
|
||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||
.Returns(true);
|
||||
s => s.GetEpisodesBySeason(It.IsAny<int>(), It.IsAny<int>()))
|
||||
.Returns(new List<Episode>() {
|
||||
new Episode(), new Episode(), new Episode(), new Episode(), new Episode(),
|
||||
new Episode(), new Episode(), new Episode(), new Episode(), new Episode() { Id = 2 } });
|
||||
}
|
||||
|
||||
[TestCase(30, 50, false)]
|
||||
|
@ -110,10 +118,6 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
parseResultMulti.Series = series;
|
||||
parseResultMulti.Release.Size = sizeInMegaBytes.Megabytes();
|
||||
|
||||
Mocker.GetMock<IEpisodeService>().Setup(
|
||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||
.Returns(false);
|
||||
|
||||
Subject.IsSatisfiedBy(parseResultMulti, null).Should().Be(expectedResult);
|
||||
}
|
||||
|
||||
|
@ -129,10 +133,6 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
parseResultMultiSet.Series = series;
|
||||
parseResultMultiSet.Release.Size = sizeInMegaBytes.Megabytes();
|
||||
|
||||
Mocker.GetMock<IEpisodeService>().Setup(
|
||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||
.Returns(false);
|
||||
|
||||
Subject.IsSatisfiedBy(parseResultMultiSet, null).Should().Be(expectedResult);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ using Moq;
|
|||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.Clients;
|
||||
using NzbDrone.Core.Download.Clients.Blackhole;
|
||||
|
|
|
@ -5,6 +5,7 @@ using Moq;
|
|||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.Clients;
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Text;
|
|||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test
|
||||
{
|
||||
|
@ -22,10 +23,11 @@ namespace NzbDrone.Core.Test
|
|||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public void WithDefault_Fail()
|
||||
{
|
||||
"test".WithDefault(null);
|
||||
Assert.Throws<ArgumentNullException>(() => "test".WithDefault(null));
|
||||
|
||||
ExceptionVerification.IgnoreWarns();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.Framework
|
||||
|
|
|
@ -5,6 +5,7 @@ using FluentValidation.Results;
|
|||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
|
|
@ -4,6 +4,7 @@ using Moq;
|
|||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
|
|
|
@ -6,6 +6,7 @@ using FluentAssertions;
|
|||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Notifications.Plex;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Notifications.Xbmc;
|
||||
using NzbDrone.Core.Notifications.Xbmc.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Linq;
|
|||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Notifications.Xbmc;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Notifications.Xbmc;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using FizzWare.NBuilder;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Notifications.Xbmc;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
|
|
@ -3,6 +3,7 @@ using FluentAssertions;
|
|||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Notifications.Xbmc;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Notifications.Xbmc;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
|
|
@ -3,6 +3,7 @@ using FizzWare.NBuilder;
|
|||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Notifications.Xbmc;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
@ -13,7 +14,7 @@ namespace NzbDrone.Core.Test.NotificationTests.Xbmc.Json
|
|||
public class UpdateFixture : CoreTest<JsonApiProvider>
|
||||
{
|
||||
private XbmcSettings _settings;
|
||||
const string _expectedJson = "{\"jsonrpc\":\"2.0\",\"method\":\"VideoLibrary.GetTvShows\",\"params\":{\"properties\":[\"file\",\"imdbnumber\"]},\"id\":10}";
|
||||
const string _expectedJson = "{\"jsonrpc\":\"2.0\",\"method\":\"VideoLibrary.GetTvShows\",\"params\":{\"properties\":[\"file\",\"imdbnumber\"]},\"id\":";
|
||||
|
||||
private const string _tvshowsResponse = "{\"id\":10,\"jsonrpc\":\"2.0\",\"result\":{\"limits\":" +
|
||||
"{\"end\":5,\"start\":0,\"total\":5},\"tvshows\":[{\"file\"" +
|
||||
|
@ -41,7 +42,7 @@ namespace NzbDrone.Core.Test.NotificationTests.Xbmc.Json
|
|||
|
||||
Mocker.GetMock<IHttpProvider>()
|
||||
.Setup(s => s.PostCommand(_settings.Address, _settings.Username, _settings.Password,
|
||||
It.Is<string>(e => e.Replace(" ", "").Replace("\r\n", "").Replace("\t", "") == _expectedJson.Replace(" ", ""))))
|
||||
It.Is<string>(e => e.Replace(" ", "").Replace("\r\n", "").Replace("\t", "").Contains(_expectedJson.Replace(" ", "")))))
|
||||
.Returns(_tvshowsResponse);
|
||||
}
|
||||
|
||||
|
|
|
@ -103,8 +103,8 @@
|
|||
<Compile Include="Datastore\DatabaseRelationshipFixture.cs" />
|
||||
<Compile Include="Datastore\MappingExtentionFixture.cs" />
|
||||
<Compile Include="Datastore\ObjectDatabaseFixture.cs" />
|
||||
<Compile Include="Datastore\PagingSpecExtenstionsTests\ToSortDirectionFixture.cs" />
|
||||
<Compile Include="Datastore\PagingSpecExtenstionsTests\PagingOffsetFixture.cs" />
|
||||
<Compile Include="Datastore\PagingSpecExtensionsTests\ToSortDirectionFixture.cs" />
|
||||
<Compile Include="Datastore\PagingSpecExtensionsTests\PagingOffsetFixture.cs" />
|
||||
<Compile Include="Datastore\ReflectionStrategyFixture\Benchmarks.cs" />
|
||||
<Compile Include="Datastore\SQLiteMigrationHelperTests\AlterFixture.cs" />
|
||||
<Compile Include="Datastore\SQLiteMigrationHelperTests\DuplicateFixture.cs" />
|
||||
|
@ -233,6 +233,7 @@
|
|||
<Compile Include="ProviderTests\DiskProviderTests\ArchiveProviderFixture.cs" />
|
||||
<Compile Include="MediaFiles\DownloadedEpisodesImportServiceFixture.cs" />
|
||||
<Compile Include="SeriesStatsTests\SeriesStatisticsFixture.cs" />
|
||||
<Compile Include="TvTests\RefreshSeriesServiceFixture.cs" />
|
||||
<Compile Include="TvTests\SeriesRepositoryTests\QualityProfileRepositoryFixture.cs" />
|
||||
<Compile Include="TvTests\SeriesServiceTests\UpdateMultipleSeriesFixture.cs" />
|
||||
<Compile Include="TvTests\SeriesServiceTests\UpdateSeriesFixture.cs" />
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
[TestCase("2020.NZ.2012.13.02.PDTV.XviD-C4TV", "2020nz", 2012, 2, 13)]
|
||||
[TestCase("2020.NZ.2011.12.02.PDTV.XviD-C4TV", "2020nz", 2011, 12, 2)]
|
||||
[TestCase("Series Title - 2013-10-30 - Episode Title (1) [HDTV-720p]", "Series Title", 2013, 10, 30)]
|
||||
[TestCase("The_Voice_US_04.28.2014_hdtv.x264.Poke.mp4", "The Voice US", 2014, 4, 28)]
|
||||
public void should_parse_daily_episode(string postTitle, string title, int year, int month, int day)
|
||||
{
|
||||
var result = Parser.Parser.ParseTitle(postTitle);
|
||||
|
|
|
@ -37,6 +37,8 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
[TestCase("Kaamelott.S01E91-E100", "Kaamelott", 1, new[] { 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 })]
|
||||
[TestCase("Neighbours.S29E161-E165.PDTV.x264-FQM", "Neighbours", 29, new[] { 161, 162, 163, 164, 165 })]
|
||||
[TestCase("Shortland.Street.S22E5363-E5366.HDTV.x264-FiHTV", "Shortland Street", 22, new[] { 5363, 5364, 5365, 5366 })]
|
||||
[TestCase("the.office.101.102.hdtv-lol", "The Office", 1, new[] { 1, 2 })]
|
||||
//[TestCase("Adventure Time - 5x01 - x02 - Finn the Human (2) & Jake the Dog (3)", "Adventure Time", 5, new [] { 1, 2 })]
|
||||
public void should_parse_multiple_episodes(string postTitle, string title, int season, int[] episodes)
|
||||
{
|
||||
var result = Parser.Parser.ParseTitle(postTitle);
|
||||
|
|
|
@ -55,6 +55,9 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
[TestCase("The.Girls.Next.Door.S03E06.DVDRip.XviD-WiDE", false)]
|
||||
[TestCase("The.Girls.Next.Door.S03E06.DVD.Rip.XviD-WiDE", false)]
|
||||
[TestCase("the.shield.1x13.circles.ws.xvidvd-tns", false)]
|
||||
[TestCase("the_x-files.9x18.sunshine_days.ac3.ws_dvdrip_xvid-fov.avi", false)]
|
||||
[TestCase("Hannibal.S01E05.576p.BluRay.DD5.1.x264-HiSD", false)]
|
||||
[TestCase("Hannibal.S01E05.480p.BluRay.DD5.1.x264-HiSD", false)]
|
||||
public void should_parse_dvd_quality(string title, bool proper)
|
||||
{
|
||||
ParseAndVerifyQuality(title, Quality.DVD, proper);
|
||||
|
@ -115,6 +118,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
[TestCase("Two and a Half Men S10E03 1080p WEB DL DD5 1 H 264 REPACK NFHD", true)]
|
||||
[TestCase("Glee.S04E09.Swan.Song.1080p.WEB-DL.DD5.1.H.264-ECI", false)]
|
||||
[TestCase("The.Big.Bang.Theory.S06E11.The.Santa.Simulation.1080p.WEB-DL.DD5.1.H.264", false)]
|
||||
[TestCase("Rosemary's.Baby.S01E02.Night.2.[WEBDL-1080p].mkv", false)]
|
||||
public void should_parse_webdl1080p_quality(string title, bool proper)
|
||||
{
|
||||
ParseAndVerifyQuality(title, Quality.WEBDL1080p, proper);
|
||||
|
@ -123,6 +127,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
[TestCase("WEEDS.S03E01-06.DUAL.Bluray.AC3.-HELLYWOOD.avi", false)]
|
||||
[TestCase("Chuck - S01E03 - Come Fly With Me - 720p BluRay.mkv", false)]
|
||||
[TestCase("The Big Bang Theory.S03E01.The Electric Can Opener Fluctuation.m2ts", false)]
|
||||
[TestCase("Revolution.S01E02.Chained.Heat.[Bluray720p].mkv", false)]
|
||||
public void should_parse_bluray720p_quality(string title, bool proper)
|
||||
{
|
||||
ParseAndVerifyQuality(title, Quality.Bluray720p, proper);
|
||||
|
@ -130,6 +135,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
|
||||
[TestCase("Chuck - S01E03 - Come Fly With Me - 1080p BluRay.mkv", false)]
|
||||
[TestCase("Sons.Of.Anarchy.S02E13.1080p.BluRay.x264-AVCDVD", false)]
|
||||
[TestCase("Revolution.S01E02.Chained.Heat.[Bluray1080p].mkv", false)]
|
||||
public void should_parse_bluray1080p_quality(string title, bool proper)
|
||||
{
|
||||
ParseAndVerifyQuality(title, Quality.Bluray1080p, proper);
|
||||
|
|
|
@ -9,8 +9,8 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
public class ReleaseGroupParserFixture : CoreTest
|
||||
{
|
||||
[TestCase("Castle.2009.S01E14.English.HDTV.XviD-LOL", "LOL")]
|
||||
[TestCase("Castle 2009 S01E14 English HDTV XviD LOL", "LOL")]
|
||||
[TestCase("Acropolis Now S05 EXTRAS DVDRip XviD RUNNER", "RUNNER")]
|
||||
[TestCase("Castle 2009 S01E14 English HDTV XviD LOL", "DRONE")]
|
||||
[TestCase("Acropolis Now S05 EXTRAS DVDRip XviD RUNNER", "DRONE")]
|
||||
[TestCase("Punky.Brewster.S01.EXTRAS.DVDRip.XviD-RUNNER", "RUNNER")]
|
||||
[TestCase("2020.NZ.2011.12.02.PDTV.XviD-C4TV", "C4TV")]
|
||||
[TestCase("The.Office.S03E115.DVDRip.XviD-OSiTV", "OSiTV")]
|
||||
|
@ -18,6 +18,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
[TestCase("The Office - S01E01 - Pilot [HTDV-720p]", "DRONE")]
|
||||
[TestCase("The Office - S01E01 - Pilot [HTDV-1080p]", "DRONE")]
|
||||
[TestCase("The.Walking.Dead.S04E13.720p.WEB-DL.AAC2.0.H.264-Cyphanix", "Cyphanix")]
|
||||
[TestCase("Arrow.S02E01.720p.WEB-DL.DD5.1.H.264.mkv", "DRONE")]
|
||||
public void should_parse_release_group(string title, string expected)
|
||||
{
|
||||
Parser.Parser.ParseReleaseGroup(title).Should().Be(expected);
|
||||
|
|
|
@ -83,6 +83,8 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
[TestCase("Homeland - 2x12 - The Choice [HDTV-1080p].mkv", "Homeland", 2, 12)]
|
||||
[TestCase("Homeland - 2x4 - New Car Smell [HDTV-1080p].mkv", "Homeland", 2, 4)]
|
||||
[TestCase("Top Gear - 06x11 - 2005.08.07", "Top Gear", 6, 11)]
|
||||
[TestCase("The_Voice_US_s06e19_04.28.2014_hdtv.x264.Poke.mp4", "The Voice US", 6, 19)]
|
||||
[TestCase("the.100.110.hdtv-lol", "The 100", 1, 10)]
|
||||
public void should_parse_single_episode(string postTitle, string title, int seasonNumber, int episodeNumber)
|
||||
{
|
||||
var result = Parser.Parser.ParseTitle(postTitle);
|
||||
|
|
|
@ -13,12 +13,10 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskProviderTests
|
|||
[Test]
|
||||
public void Should_extract_to_correct_folder()
|
||||
{
|
||||
var destination = Path.Combine(TempFolder, "destination");
|
||||
var destinationFolder = new DirectoryInfo(GetTempFilePath());
|
||||
var testArchive = OsInfo.IsWindows ? "TestArchive.zip" : "TestArchive.tar.gz";
|
||||
|
||||
Subject.Extract(GetTestFilePath(testArchive), destination);
|
||||
|
||||
var destinationFolder = new DirectoryInfo(destination);
|
||||
Subject.Extract(Path.Combine("Files", testArchive), destinationFolder.FullName);
|
||||
|
||||
destinationFolder.Exists.Should().BeTrue();
|
||||
destinationFolder.GetDirectories().Should().HaveCount(1);
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.MetadataSource;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Tv.Commands;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.TvTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class RefreshSeriesServiceFixture : CoreTest<RefreshSeriesService>
|
||||
{
|
||||
private Series _series;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
var season1 = Builder<Season>.CreateNew()
|
||||
.With(s => s.SeasonNumber = 1)
|
||||
.Build();
|
||||
|
||||
_series = Builder<Series>.CreateNew()
|
||||
.With(s => s.Seasons = new List<Season>
|
||||
{
|
||||
season1
|
||||
})
|
||||
.Build();
|
||||
|
||||
Mocker.GetMock<ISeriesService>()
|
||||
.Setup(s => s.GetSeries(_series.Id))
|
||||
.Returns(_series);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void GivenNewSeriesInfo(Series series)
|
||||
{
|
||||
Mocker.GetMock<IProvideSeriesInfo>()
|
||||
.Setup(s => s.GetSeriesInfo(It.IsAny<Int32>()))
|
||||
.Returns(new Tuple<Series, List<Episode>>(series, new List<Episode>()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_monitor_new_seasons_automatically()
|
||||
{
|
||||
var series = _series.JsonClone();
|
||||
series.Seasons.Add(Builder<Season>.CreateNew()
|
||||
.With(s => s.SeasonNumber = 2)
|
||||
.Build());
|
||||
|
||||
GivenNewSeriesInfo(series);
|
||||
|
||||
Subject.Execute(new RefreshSeriesCommand(_series.Id));
|
||||
|
||||
Mocker.GetMock<ISeriesService>()
|
||||
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.Seasons.Count == 2 && s.Seasons.Single(season => season.SeasonNumber == 2).Monitored == true)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_monitor_new_special_season_automatically()
|
||||
{
|
||||
var series = _series.JsonClone();
|
||||
series.Seasons.Add(Builder<Season>.CreateNew()
|
||||
.With(s => s.SeasonNumber = 0)
|
||||
.Build());
|
||||
|
||||
GivenNewSeriesInfo(series);
|
||||
|
||||
Subject.Execute(new RefreshSeriesCommand(_series.Id));
|
||||
|
||||
Mocker.GetMock<ISeriesService>()
|
||||
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.Seasons.Count == 2 && s.Seasons.Single(season => season.SeasonNumber == 0).Monitored == false)));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,8 +6,10 @@ using NUnit.Framework;
|
|||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Model;
|
||||
using NzbDrone.Common.Processes;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Update;
|
||||
using NzbDrone.Core.Update.Commands;
|
||||
|
@ -48,12 +50,28 @@ namespace NzbDrone.Core.Test.UpdateTests
|
|||
|
||||
Mocker.GetMock<IAppFolderInfo>().SetupGet(c => c.TempFolder).Returns(TempFolder);
|
||||
Mocker.GetMock<ICheckUpdateService>().Setup(c => c.AvailableUpdate()).Returns(_updatePackage);
|
||||
Mocker.GetMock<IVerifyUpdates>().Setup(c => c.Verify(It.IsAny<UpdatePackage>(), It.IsAny<String>())).Returns(true);
|
||||
|
||||
Mocker.GetMock<IProcessProvider>().Setup(c => c.GetCurrentProcess()).Returns(new ProcessInfo { Id = 12 });
|
||||
Mocker.GetMock<IRuntimeInfo>().Setup(c => c.ExecutingApplication).Returns(@"C:\Test\NzbDrone.exe");
|
||||
|
||||
_sandboxFolder = Mocker.GetMock<IAppFolderInfo>().Object.GetUpdateSandboxFolder();
|
||||
}
|
||||
|
||||
private void GivenInstallScript(string path)
|
||||
{
|
||||
Mocker.GetMock<IConfigFileProvider>()
|
||||
.SetupGet(s => s.UpdateMechanism)
|
||||
.Returns(UpdateMechanism.Script);
|
||||
|
||||
Mocker.GetMock<IConfigFileProvider>()
|
||||
.SetupGet(s => s.UpdateScriptPath)
|
||||
.Returns(path);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(s => s.FileExists(path, true))
|
||||
.Returns(true);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_delete_sandbox_before_update_if_folder_exists()
|
||||
|
@ -76,7 +94,6 @@ namespace NzbDrone.Core.Test.UpdateTests
|
|||
Mocker.GetMock<IDiskProvider>().Verify(c => c.DeleteFolder(_sandboxFolder, true), Times.Never());
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Should_download_update_package()
|
||||
{
|
||||
|
@ -117,18 +134,87 @@ namespace NzbDrone.Core.Test.UpdateTests
|
|||
Subject.Execute(new ApplicationUpdateCommand());
|
||||
|
||||
Mocker.GetMock<IProcessProvider>()
|
||||
.Verify(c => c.Start(It.IsAny<string>(), "12", null, null), Times.Once());
|
||||
.Verify(c => c.Start(It.IsAny<string>(), It.Is<String>(s => s.StartsWith("12")), null, null), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void when_no_updates_are_available_should_return_without_error_or_warnings()
|
||||
public void should_return_without_error_or_warnings_when_no_updates_are_available()
|
||||
{
|
||||
Mocker.GetMock<ICheckUpdateService>().Setup(c => c.AvailableUpdate()).Returns<UpdatePackage>(null);
|
||||
|
||||
Subject.Execute(new ApplicationUpdateCommand());
|
||||
|
||||
|
||||
ExceptionVerification.AssertNoUnexcpectedLogs();
|
||||
ExceptionVerification.AssertNoUnexpectedLogs();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_extract_if_verification_fails()
|
||||
{
|
||||
Mocker.GetMock<IVerifyUpdates>().Setup(c => c.Verify(It.IsAny<UpdatePackage>(), It.IsAny<String>())).Returns(false);
|
||||
|
||||
Subject.Execute(new ApplicationUpdateCommand());
|
||||
|
||||
Mocker.GetMock<IArchiveService>().Verify(v => v.Extract(It.IsAny<String>(), It.IsAny<String>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Platform("Mono")]
|
||||
public void should_run_script_if_configured()
|
||||
{
|
||||
const string scriptPath = "/tmp/nzbdrone/update.sh";
|
||||
|
||||
GivenInstallScript(scriptPath);
|
||||
|
||||
Subject.Execute(new ApplicationUpdateCommand());
|
||||
|
||||
Mocker.GetMock<IProcessProvider>().Verify(v => v.Start(scriptPath, It.IsAny<String>(), null, null), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Platform("Mono")]
|
||||
public void should_throw_if_script_is_not_set()
|
||||
{
|
||||
const string scriptPath = "/tmp/nzbdrone/update.sh";
|
||||
|
||||
GivenInstallScript("");
|
||||
|
||||
Subject.Execute(new ApplicationUpdateCommand());
|
||||
|
||||
ExceptionVerification.ExpectedErrors(1);
|
||||
Mocker.GetMock<IProcessProvider>().Verify(v => v.Start(scriptPath, It.IsAny<String>(), null, null), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Platform("Mono")]
|
||||
public void should_throw_if_script_is_null()
|
||||
{
|
||||
const string scriptPath = "/tmp/nzbdrone/update.sh";
|
||||
|
||||
GivenInstallScript(null);
|
||||
|
||||
Subject.Execute(new ApplicationUpdateCommand());
|
||||
|
||||
ExceptionVerification.ExpectedErrors(1);
|
||||
Mocker.GetMock<IProcessProvider>().Verify(v => v.Start(scriptPath, It.IsAny<String>(), null, null), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Platform("Mono")]
|
||||
public void should_throw_if_script_path_does_not_exist()
|
||||
{
|
||||
const string scriptPath = "/tmp/nzbdrone/update.sh";
|
||||
|
||||
GivenInstallScript(scriptPath);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(s => s.FileExists(scriptPath, true))
|
||||
.Returns(false);
|
||||
|
||||
Subject.Execute(new ApplicationUpdateCommand());
|
||||
|
||||
ExceptionVerification.ExpectedErrors(1);
|
||||
Mocker.GetMock<IProcessProvider>().Verify(v => v.Start(scriptPath, It.IsAny<String>(), null, null), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Blacklisting
|
||||
{
|
||||
public class Blacklist : ModelBase
|
||||
{
|
||||
public Int32 SeriesId { get; set; }
|
||||
public Series Series { get; set; }
|
||||
public List<Int32> EpisodeIds { get; set; }
|
||||
public String SourceTitle { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using Marr.Data.QGen;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Blacklisting
|
||||
{
|
||||
|
@ -27,5 +29,12 @@ namespace NzbDrone.Core.Blacklisting
|
|||
{
|
||||
return Query.Where(b => b.SeriesId == seriesId);
|
||||
}
|
||||
|
||||
protected override SortBuilder<Blacklist> GetPagedQuery(QueryBuilder<Blacklist> query, PagingSpec<Blacklist> pagingSpec)
|
||||
{
|
||||
var baseQuery = query.Join<Blacklist, Series>(JoinType.Inner, h => h.Series, (h, s) => h.SeriesId == s.Id);
|
||||
|
||||
return base.GetPagedQuery(baseQuery, pagingSpec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ using NzbDrone.Core.Configuration.Events;
|
|||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Update;
|
||||
|
||||
|
||||
namespace NzbDrone.Core.Configuration
|
||||
|
@ -30,11 +31,13 @@ namespace NzbDrone.Core.Configuration
|
|||
string Password { get; }
|
||||
string LogLevel { get; }
|
||||
string Branch { get; }
|
||||
bool AutoUpdate { get; }
|
||||
string ApiKey { get; }
|
||||
bool Torrent { get; }
|
||||
string SslCertHash { get; }
|
||||
string UrlBase { get; }
|
||||
Boolean UpdateAutomatically { get; }
|
||||
UpdateMechanism UpdateMechanism { get; }
|
||||
String UpdateScriptPath { get; }
|
||||
}
|
||||
|
||||
public class ConfigFileProvider : IConfigFileProvider
|
||||
|
@ -141,11 +144,6 @@ namespace NzbDrone.Core.Configuration
|
|||
get { return GetValue("Branch", "master").ToLowerInvariant(); }
|
||||
}
|
||||
|
||||
public bool AutoUpdate
|
||||
{
|
||||
get { return GetValueBoolean("AutoUpdate", false, persist: false); }
|
||||
}
|
||||
|
||||
public string Username
|
||||
{
|
||||
get { return GetValue("Username", ""); }
|
||||
|
@ -181,6 +179,21 @@ namespace NzbDrone.Core.Configuration
|
|||
}
|
||||
}
|
||||
|
||||
public bool UpdateAutomatically
|
||||
{
|
||||
get { return GetValueBoolean("UpdateAutomatically", false, false); }
|
||||
}
|
||||
|
||||
public UpdateMechanism UpdateMechanism
|
||||
{
|
||||
get { return GetValueEnum("UpdateMechanism", UpdateMechanism.BuiltIn, false); }
|
||||
}
|
||||
|
||||
public string UpdateScriptPath
|
||||
{
|
||||
get { return GetValue("UpdateScriptPath", "", false ); }
|
||||
}
|
||||
|
||||
public int GetValueInt(string key, int defaultValue)
|
||||
{
|
||||
return Convert.ToInt32(GetValue(key, defaultValue));
|
||||
|
@ -191,9 +204,9 @@ namespace NzbDrone.Core.Configuration
|
|||
return Convert.ToBoolean(GetValue(key, defaultValue, persist));
|
||||
}
|
||||
|
||||
public T GetValueEnum<T>(string key, T defaultValue)
|
||||
public T GetValueEnum<T>(string key, T defaultValue, bool persist = true)
|
||||
{
|
||||
return (T)Enum.Parse(typeof(T), GetValue(key, defaultValue), true);
|
||||
return (T)Enum.Parse(typeof(T), GetValue(key, defaultValue), persist);
|
||||
}
|
||||
|
||||
public string GetValue(string key, object defaultValue, bool persist = true)
|
||||
|
@ -210,7 +223,9 @@ namespace NzbDrone.Core.Configuration
|
|||
var valueHolder = parentContainer.Descendants(key).ToList();
|
||||
|
||||
if (valueHolder.Count() == 1)
|
||||
{
|
||||
return valueHolder.First().Value.Trim();
|
||||
}
|
||||
|
||||
//Save the value
|
||||
if (persist)
|
||||
|
|
|
@ -6,6 +6,7 @@ using NzbDrone.Common.EnsureThat;
|
|||
using NzbDrone.Core.Configuration.Events;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Update;
|
||||
|
||||
|
||||
namespace NzbDrone.Core.Configuration
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Update;
|
||||
|
||||
namespace NzbDrone.Core.Configuration
|
||||
{
|
||||
|
@ -23,7 +24,6 @@ namespace NzbDrone.Core.Configuration
|
|||
Int32 BlacklistRetryInterval { get; set; }
|
||||
Int32 BlacklistRetryLimit { get; set; }
|
||||
|
||||
|
||||
//Media Management
|
||||
Boolean AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
|
||||
String RecycleBin { get; set; }
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Serializer;
|
||||
|
||||
namespace NzbDrone.Core.DataAugmentation.DailySeries
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Serializer;
|
||||
|
||||
namespace NzbDrone.Core.DataAugmentation.Scene
|
||||
|
|
|
@ -6,7 +6,7 @@ using Marr.Data;
|
|||
using Marr.Data.QGen;
|
||||
using NzbDrone.Core.Datastore.Events;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Core.Datastore.Extentions;
|
||||
using NzbDrone.Core.Datastore.Extensions;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ using Marr.Data;
|
|||
using Marr.Data.Mapping;
|
||||
using NzbDrone.Common.Reflection;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Extentions
|
||||
namespace NzbDrone.Core.Datastore.Extensions
|
||||
{
|
||||
public static class MappingExtensions
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Extentions
|
||||
namespace NzbDrone.Core.Datastore.Extensions
|
||||
{
|
||||
public static class PagingSpecExtensions
|
||||
{
|
|
@ -4,7 +4,7 @@ using System.Linq.Expressions;
|
|||
using Marr.Data;
|
||||
using Marr.Data.Mapping;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Extentions
|
||||
namespace NzbDrone.Core.Datastore.Extensions
|
||||
{
|
||||
public static class RelationshipExtensions
|
||||
{
|
|
@ -0,0 +1,14 @@
|
|||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
using FluentMigrator;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(50)]
|
||||
public class add_hash_to_metadata_files : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Alter.Table("MetadataFiles").AddColumn("Hash").AsString().Nullable();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ using NzbDrone.Core.Blacklisting;
|
|||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.DataAugmentation.Scene;
|
||||
using NzbDrone.Core.Datastore.Converters;
|
||||
using NzbDrone.Core.Datastore.Extentions;
|
||||
using NzbDrone.Core.Datastore.Extensions;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Instrumentation;
|
||||
|
|
|
@ -4,6 +4,7 @@ using NzbDrone.Core.IndexerSearch.Definitions;
|
|||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
{
|
||||
|
@ -66,11 +67,28 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
|||
//Multiply maxSize by Series.Runtime
|
||||
maxSize = maxSize * subject.Series.Runtime * subject.Episodes.Count;
|
||||
|
||||
//Check if there was only one episode parsed and it is the first
|
||||
if (subject.Episodes.Count == 1 && _episodeService.IsFirstOrLastEpisodeOfSeason(subject.Episodes.First().Id))
|
||||
if (subject.Episodes.Count == 1)
|
||||
{
|
||||
Episode episode = subject.Episodes.First();
|
||||
List<Episode> seasonEpisodes;
|
||||
|
||||
var seasonSearchCriteria = searchCriteria as SeasonSearchCriteria;
|
||||
if (seasonSearchCriteria != null && !seasonSearchCriteria.Series.UseSceneNumbering && seasonSearchCriteria.Episodes.Any(v => v.Id == episode.Id))
|
||||
{
|
||||
seasonEpisodes = (searchCriteria as SeasonSearchCriteria).Episodes;
|
||||
}
|
||||
else
|
||||
{
|
||||
seasonEpisodes = _episodeService.GetEpisodesBySeason(episode.SeriesId, episode.SeasonNumber);
|
||||
}
|
||||
|
||||
//Ensure that this is either the first episode
|
||||
//or is the last episode in a season that has 10 or more episodes
|
||||
if (seasonEpisodes.First().Id == episode.Id || (seasonEpisodes.Count() >= 10 && seasonEpisodes.Last().Id == episode.Id))
|
||||
{
|
||||
maxSize = maxSize * 2;
|
||||
}
|
||||
}
|
||||
|
||||
//If the parsed size is greater than maxSize we don't want it
|
||||
if (subject.Release.Size > maxSize)
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.IO;
|
|||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Organizer;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.IO;
|
|||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
|
|
@ -135,7 +135,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
|||
action,
|
||||
authentication);
|
||||
|
||||
_logger.CleansedDebug(url);
|
||||
_logger.Debug(url);
|
||||
|
||||
return new RestClient(url);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.HealthCheck.Checks
|
||||
{
|
||||
public class RootFolderCheck : HealthCheckBase
|
||||
{
|
||||
private readonly ISeriesService _seriesService;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
|
||||
public RootFolderCheck(ISeriesService seriesService, IDiskProvider diskProvider)
|
||||
{
|
||||
_seriesService = seriesService;
|
||||
_diskProvider = diskProvider;
|
||||
}
|
||||
|
||||
public override HealthCheck Check()
|
||||
{
|
||||
var missingRootFolders = _seriesService.GetAllSeries()
|
||||
.Select(s => _diskProvider.GetParentFolder(s.Path))
|
||||
.Distinct()
|
||||
.Where(s => !_diskProvider.FolderExists(s))
|
||||
.ToList();
|
||||
|
||||
if (missingRootFolders.Any())
|
||||
{
|
||||
if (missingRootFolders.Count == 1)
|
||||
{
|
||||
return new HealthCheck(GetType(), HealthCheckResult.Error, "Missing root folder: " + missingRootFolders.First());
|
||||
}
|
||||
|
||||
var message = String.Format("Multiple root folders are missing: {0}", String.Join(" | ", missingRootFolders));
|
||||
return new HealthCheck(GetType(), HealthCheckResult.Error, message);
|
||||
}
|
||||
|
||||
return new HealthCheck(GetType());
|
||||
}
|
||||
|
||||
public override bool CheckOnConfigChange
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ namespace NzbDrone.Core.HealthCheck.Checks
|
|||
|
||||
public override HealthCheck Check()
|
||||
{
|
||||
//TODO: Check on mono as well
|
||||
if (OsInfo.IsWindows)
|
||||
{
|
||||
try
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
|
@ -14,7 +15,7 @@ namespace NzbDrone.Core.Housekeeping
|
|||
private readonly Logger _logger;
|
||||
private readonly IDatabase _mainDb;
|
||||
|
||||
public HousekeepingService(IEnumerable<IHousekeepingTask> housekeepers, Logger logger, IDatabase mainDb)
|
||||
public HousekeepingService(IEnumerable<IHousekeepingTask> housekeepers, IDatabase mainDb, Logger logger)
|
||||
{
|
||||
_housekeepers = housekeepers;
|
||||
_logger = logger;
|
||||
|
@ -37,10 +38,14 @@ namespace NzbDrone.Core.Housekeeping
|
|||
}
|
||||
}
|
||||
|
||||
//Only Vaccuum the DB in production
|
||||
if (RuntimeInfo.IsProduction)
|
||||
{
|
||||
// Vacuuming the log db isn't needed since that's done hourly at the TrimLogCommand.
|
||||
_logger.Debug("Compressing main database after housekeeping");
|
||||
_mainDb.Vacuum();
|
||||
}
|
||||
}
|
||||
|
||||
public void Execute(HousekeepingCommand message)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Net;
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Indexers.Exceptions;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Instrumentation.Extensions;
|
||||
|
@ -116,7 +117,7 @@ namespace NzbDrone.Core.Indexers
|
|||
{
|
||||
try
|
||||
{
|
||||
_logger.CleansedDebug("Downloading Feed " + url);
|
||||
_logger.Debug("Downloading Feed " + url);
|
||||
var xml = _httpProvider.DownloadString(url);
|
||||
if (!string.IsNullOrWhiteSpace(xml))
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@ using FluentValidation;
|
|||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Indexers.Exceptions;
|
||||
using NzbDrone.Core.Indexers.Newznab;
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ using NLog.Config;
|
|||
using NLog;
|
||||
using NLog.Layouts;
|
||||
using NLog.Targets;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
|
||||
|
@ -52,7 +53,7 @@ namespace NzbDrone.Core.Instrumentation
|
|||
{
|
||||
var log = new Log();
|
||||
log.Time = logEvent.TimeStamp;
|
||||
log.Message = logEvent.FormattedMessage;
|
||||
log.Message = CleanseLogMessage.Cleanse(logEvent.FormattedMessage);
|
||||
log.Method = Layout.Render(logEvent);
|
||||
|
||||
log.Logger = logEvent.LoggerName;
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using NLog;
|
||||
|
||||
namespace NzbDrone.Core.Instrumentation.Extensions
|
||||
{
|
||||
public static class LoggerCleansedExtensions
|
||||
{
|
||||
private static readonly Regex CleansingRegex = new Regex(@"(?<=apikey=)(\w+?)(?=\W|$|_)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
public static void CleansedInfo(this Logger logger, string message, params object[] args)
|
||||
{
|
||||
var formattedMessage = String.Format(message, args);
|
||||
LogCleansedMessage(logger, LogLevel.Info, formattedMessage);
|
||||
}
|
||||
|
||||
public static void CleansedDebug(this Logger logger, string message, params object[] args)
|
||||
{
|
||||
var formattedMessage = String.Format(message, args);
|
||||
LogCleansedMessage(logger, LogLevel.Debug, formattedMessage);
|
||||
}
|
||||
|
||||
public static void CleansedTrace(this Logger logger, string message, params object[] args)
|
||||
{
|
||||
var formattedMessage = String.Format(message, args);
|
||||
LogCleansedMessage(logger, LogLevel.Trace, formattedMessage);
|
||||
}
|
||||
|
||||
private static void LogCleansedMessage(Logger logger, LogLevel level, string message)
|
||||
{
|
||||
message = Cleanse(message);
|
||||
|
||||
var logEvent = new LogEventInfo(level, logger.Name, message);
|
||||
|
||||
logger.Log(logEvent);
|
||||
}
|
||||
|
||||
private static string Cleanse(string message)
|
||||
{
|
||||
//TODO: password=
|
||||
|
||||
return CleansingRegex.Replace(message, "<removed>");
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue