Merge branch 'develop'
This commit is contained in:
commit
e97cd5b13b
|
@ -238,6 +238,12 @@ namespace Microsoft.AspNet.SignalR.Infrastructure
|
||||||
|
|
||||||
if (command == null)
|
if (command == null)
|
||||||
{
|
{
|
||||||
|
var platform = (int)Environment.OSVersion.Platform;
|
||||||
|
if (platform == 4 || platform == 6 || platform == 128)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
throw new SerializationException("Couldn't parse message " + message.Value);
|
throw new SerializationException("Couldn't parse message " + message.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,8 @@ namespace NzbDrone.Api.Test.MappingTests
|
||||||
[TestCase(typeof(ParsedEpisodeInfo), typeof(ReleaseResource))]
|
[TestCase(typeof(ParsedEpisodeInfo), typeof(ReleaseResource))]
|
||||||
[TestCase(typeof(DownloadDecision), typeof(ReleaseResource))]
|
[TestCase(typeof(DownloadDecision), typeof(ReleaseResource))]
|
||||||
[TestCase(typeof(Core.History.History), typeof(HistoryResource))]
|
[TestCase(typeof(Core.History.History), typeof(HistoryResource))]
|
||||||
[TestCase(typeof(Quality), typeof(QualityResource))]
|
[TestCase(typeof(QualityProfile), typeof(QualityProfileResource))]
|
||||||
|
[TestCase(typeof(QualityProfileItem), typeof(QualityProfileItemResource))]
|
||||||
[TestCase(typeof(Log), typeof(LogResource))]
|
[TestCase(typeof(Log), typeof(LogResource))]
|
||||||
[TestCase(typeof(Command), typeof(CommandResource))]
|
[TestCase(typeof(Command), typeof(CommandResource))]
|
||||||
public void matching_fields(Type modelType, Type resourceType)
|
public void matching_fields(Type modelType, Type resourceType)
|
||||||
|
@ -107,10 +108,10 @@ namespace NzbDrone.Api.Test.MappingTests
|
||||||
[Test]
|
[Test]
|
||||||
public void should_map_qualityprofile()
|
public void should_map_qualityprofile()
|
||||||
{
|
{
|
||||||
|
|
||||||
var profileResource = new QualityProfileResource
|
var profileResource = new QualityProfileResource
|
||||||
{
|
{
|
||||||
Allowed = Builder<QualityResource>.CreateListOfSize(1).Build().ToList(),
|
Cutoff = Quality.WEBDL1080p,
|
||||||
|
Items = new List<QualityProfileItemResource> { new QualityProfileItemResource { Quality = Quality.WEBDL1080p, Allowed = true } }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Blacklist
|
namespace NzbDrone.Api.Blacklist
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace NzbDrone.Api.Calendar
|
||||||
var resources = ToListResource(() => _episodeService.EpisodesBetweenDates(start, end))
|
var resources = ToListResource(() => _episodeService.EpisodesBetweenDates(start, end))
|
||||||
.LoadSubtype(e => e.SeriesId, _seriesRepository);
|
.LoadSubtype(e => e.SeriesId, _seriesRepository);
|
||||||
|
|
||||||
return resources.OrderBy(e => e.AirDate).ToList();
|
return resources.OrderBy(e => e.AirDateUtc).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(EpisodeGrabbedEvent message)
|
public void Handle(EpisodeGrabbedEvent message)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Api.EpisodeFiles
|
namespace NzbDrone.Api.EpisodeFiles
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace NzbDrone.Api.Episodes
|
||||||
private readonly IEpisodeService _episodeService;
|
private readonly IEpisodeService _episodeService;
|
||||||
|
|
||||||
public EpisodeModule(ICommandExecutor commandExecutor, IEpisodeService episodeService)
|
public EpisodeModule(ICommandExecutor commandExecutor, IEpisodeService episodeService)
|
||||||
: base(commandExecutor, "episodes")
|
: base(commandExecutor)
|
||||||
{
|
{
|
||||||
_episodeService = episodeService;
|
_episodeService = episodeService;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ using NzbDrone.Api.Episodes;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Api.Series;
|
using NzbDrone.Api.Series;
|
||||||
using NzbDrone.Core.History;
|
using NzbDrone.Core.History;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Api.History
|
namespace NzbDrone.Api.History
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Indexers
|
namespace NzbDrone.Api.Indexers
|
||||||
|
|
|
@ -3,6 +3,7 @@ using Nancy.Bootstrapper;
|
||||||
using Nancy.Diagnostics;
|
using Nancy.Diagnostics;
|
||||||
using NzbDrone.Api.ErrorManagement;
|
using NzbDrone.Api.ErrorManagement;
|
||||||
using NzbDrone.Api.Extensions.Pipelines;
|
using NzbDrone.Api.Extensions.Pipelines;
|
||||||
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
using NzbDrone.Common.Instrumentation;
|
using NzbDrone.Common.Instrumentation;
|
||||||
using NzbDrone.Core.Instrumentation;
|
using NzbDrone.Core.Instrumentation;
|
||||||
using NzbDrone.Core.Lifecycle;
|
using NzbDrone.Core.Lifecycle;
|
||||||
|
@ -26,6 +27,11 @@ namespace NzbDrone.Api
|
||||||
{
|
{
|
||||||
_logger.Info("Starting NzbDrone API");
|
_logger.Info("Starting NzbDrone API");
|
||||||
|
|
||||||
|
if (RuntimeInfo.IsProduction)
|
||||||
|
{
|
||||||
|
DiagnosticsHook.Disable(pipelines);
|
||||||
|
}
|
||||||
|
|
||||||
RegisterPipelines(pipelines);
|
RegisterPipelines(pipelines);
|
||||||
|
|
||||||
container.Resolve<DatabaseTarget>().Register();
|
container.Resolve<DatabaseTarget>().Register();
|
||||||
|
|
|
@ -7,6 +7,7 @@ namespace NzbDrone.Api.Notifications
|
||||||
public String Link { get; set; }
|
public String Link { get; set; }
|
||||||
public Boolean OnGrab { get; set; }
|
public Boolean OnGrab { get; set; }
|
||||||
public Boolean OnDownload { get; set; }
|
public Boolean OnDownload { get; set; }
|
||||||
|
public Boolean OnUpgrade { get; set; }
|
||||||
public String TestCommand { get; set; }
|
public String TestCommand { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -139,6 +139,7 @@
|
||||||
<Compile Include="Missing\MissingModule.cs" />
|
<Compile Include="Missing\MissingModule.cs" />
|
||||||
<Compile Include="Config\NamingSampleResource.cs" />
|
<Compile Include="Config\NamingSampleResource.cs" />
|
||||||
<Compile Include="NzbDroneRestModuleWithSignalR.cs" />
|
<Compile Include="NzbDroneRestModuleWithSignalR.cs" />
|
||||||
|
<Compile Include="Qualities\QualityProfileValidation.cs" />
|
||||||
<Compile Include="Queue\QueueModule.cs" />
|
<Compile Include="Queue\QueueModule.cs" />
|
||||||
<Compile Include="Queue\QueueResource.cs" />
|
<Compile Include="Queue\QueueResource.cs" />
|
||||||
<Compile Include="ResourceChangeMessage.cs" />
|
<Compile Include="ResourceChangeMessage.cs" />
|
||||||
|
@ -168,8 +169,8 @@
|
||||||
<Compile Include="NzbDroneApiModule.cs" />
|
<Compile Include="NzbDroneApiModule.cs" />
|
||||||
<Compile Include="Qualities\QualityProfileResource.cs" />
|
<Compile Include="Qualities\QualityProfileResource.cs" />
|
||||||
<Compile Include="Qualities\QualityProfileModule.cs" />
|
<Compile Include="Qualities\QualityProfileModule.cs" />
|
||||||
<Compile Include="Qualities\QualitySizeResource.cs" />
|
<Compile Include="Qualities\QualityDefinitionResource.cs" />
|
||||||
<Compile Include="Qualities\QualitySizeModule.cs" />
|
<Compile Include="Qualities\QualityDefinitionModule.cs" />
|
||||||
<Compile Include="Extensions\ReqResExtensions.cs" />
|
<Compile Include="Extensions\ReqResExtensions.cs" />
|
||||||
<Compile Include="Config\SettingsModule.cs" />
|
<Compile Include="Config\SettingsModule.cs" />
|
||||||
<Compile Include="System\SystemModule.cs" />
|
<Compile Include="System\SystemModule.cs" />
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Qualities
|
||||||
|
{
|
||||||
|
public class QualityDefinitionModule : NzbDroneRestModule<QualityDefinitionResource>
|
||||||
|
{
|
||||||
|
private readonly IQualityDefinitionService _qualityDefinitionService;
|
||||||
|
|
||||||
|
public QualityDefinitionModule(IQualityDefinitionService qualityDefinitionService)
|
||||||
|
{
|
||||||
|
_qualityDefinitionService = qualityDefinitionService;
|
||||||
|
|
||||||
|
GetResourceAll = GetAll;
|
||||||
|
|
||||||
|
GetResourceById = GetById;
|
||||||
|
|
||||||
|
UpdateResource = Update;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update(QualityDefinitionResource resource)
|
||||||
|
{
|
||||||
|
var model = resource.InjectTo<QualityDefinition>();
|
||||||
|
_qualityDefinitionService.Update(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
private QualityDefinitionResource GetById(int id)
|
||||||
|
{
|
||||||
|
return _qualityDefinitionService.Get((Quality)id).InjectTo<QualityDefinitionResource>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<QualityDefinitionResource> GetAll()
|
||||||
|
{
|
||||||
|
return ToListResource(_qualityDefinitionService.All);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
using NzbDrone.Api.REST;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Qualities
|
||||||
|
{
|
||||||
|
public class QualityDefinitionResource : RestResource
|
||||||
|
{
|
||||||
|
public Quality Quality { get; set; }
|
||||||
|
|
||||||
|
public String Title { get; set; }
|
||||||
|
|
||||||
|
public Int32 Weight { get; set; }
|
||||||
|
|
||||||
|
public Int32 MinSize { get; set; }
|
||||||
|
public Int32 MaxSize { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Api.Mapping;
|
using NzbDrone.Api.Mapping;
|
||||||
using System.Linq;
|
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Qualities
|
namespace NzbDrone.Api.Qualities
|
||||||
|
@ -14,19 +13,14 @@ namespace NzbDrone.Api.Qualities
|
||||||
: base("/qualityprofiles")
|
: base("/qualityprofiles")
|
||||||
{
|
{
|
||||||
_qualityProfileService = qualityProfileService;
|
_qualityProfileService = qualityProfileService;
|
||||||
|
|
||||||
SharedValidator.RuleFor(c => c.Name).NotEmpty();
|
SharedValidator.RuleFor(c => c.Name).NotEmpty();
|
||||||
SharedValidator.RuleFor(c => c.Cutoff).NotNull();
|
SharedValidator.RuleFor(c => c.Cutoff).NotNull();
|
||||||
SharedValidator.RuleFor(c => c.Allowed).NotEmpty();
|
SharedValidator.RuleFor(c => c.Items).MustHaveAllowedQuality();//.SetValidator(new AllowedValidator<QualityProfileItemResource>());
|
||||||
|
|
||||||
GetResourceAll = GetAll;
|
GetResourceAll = GetAll;
|
||||||
|
|
||||||
GetResourceById = GetById;
|
GetResourceById = GetById;
|
||||||
|
|
||||||
UpdateResource = Update;
|
UpdateResource = Update;
|
||||||
|
|
||||||
CreateResource = Create;
|
CreateResource = Create;
|
||||||
|
|
||||||
DeleteResource = DeleteProfile;
|
DeleteResource = DeleteProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,38 +38,24 @@ namespace NzbDrone.Api.Qualities
|
||||||
|
|
||||||
private void Update(QualityProfileResource resource)
|
private void Update(QualityProfileResource resource)
|
||||||
{
|
{
|
||||||
var model = resource.InjectTo<QualityProfile>();
|
var model = _qualityProfileService.Get(resource.Id);
|
||||||
|
|
||||||
|
model.Name = resource.Name;
|
||||||
|
model.Cutoff = (Quality)resource.Cutoff.Id;
|
||||||
|
model.Items = resource.Items.InjectTo<List<QualityProfileItem>>();
|
||||||
_qualityProfileService.Update(model);
|
_qualityProfileService.Update(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
private QualityProfileResource GetById(int id)
|
private QualityProfileResource GetById(int id)
|
||||||
{
|
{
|
||||||
return QualityToResource(_qualityProfileService.Get(id));
|
return _qualityProfileService.Get(id).InjectTo<QualityProfileResource>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<QualityProfileResource> GetAll()
|
private List<QualityProfileResource> GetAll()
|
||||||
{
|
{
|
||||||
var allProfiles = _qualityProfileService.All();
|
var profiles = _qualityProfileService.All().InjectTo<List<QualityProfileResource>>();
|
||||||
|
|
||||||
|
|
||||||
var profiles = allProfiles.Select(QualityToResource).ToList();
|
|
||||||
|
|
||||||
return profiles;
|
return profiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static QualityProfileResource QualityToResource(QualityProfile profile)
|
|
||||||
{
|
|
||||||
return new QualityProfileResource
|
|
||||||
{
|
|
||||||
Cutoff = profile.Cutoff.InjectTo<QualityResource>(),
|
|
||||||
Available = Quality.All()
|
|
||||||
.Where(c => !profile.Allowed.Any(q => c.Id == q.Id))
|
|
||||||
.InjectTo<List<QualityResource>>(),
|
|
||||||
|
|
||||||
Allowed = profile.Allowed.InjectTo<List<QualityResource>>(),
|
|
||||||
Name = profile.Name,
|
|
||||||
Id = profile.Id
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,20 +1,20 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Qualities
|
namespace NzbDrone.Api.Qualities
|
||||||
{
|
{
|
||||||
public class QualityProfileResource : RestResource
|
public class QualityProfileResource : RestResource
|
||||||
{
|
{
|
||||||
public String Name { get; set; }
|
public String Name { get; set; }
|
||||||
public QualityResource Cutoff { get; set; }
|
public Quality Cutoff { get; set; }
|
||||||
public List<QualityResource> Available { get; set; }
|
public List<QualityProfileItemResource> Items { get; set; }
|
||||||
public List<QualityResource> Allowed { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class QualityResource : RestResource
|
public class QualityProfileItemResource : RestResource
|
||||||
{
|
{
|
||||||
public Int32 Weight { get; set; }
|
public Quality Quality { get; set; }
|
||||||
public String Name { get; set; }
|
public bool Allowed { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,33 +7,28 @@ namespace NzbDrone.Api.Qualities
|
||||||
{
|
{
|
||||||
public class QualityProfileSchemaModule : NzbDroneRestModule<QualityProfileResource>
|
public class QualityProfileSchemaModule : NzbDroneRestModule<QualityProfileResource>
|
||||||
{
|
{
|
||||||
public QualityProfileSchemaModule()
|
private readonly IQualityDefinitionService _qualityDefinitionService;
|
||||||
|
|
||||||
|
public QualityProfileSchemaModule(IQualityDefinitionService qualityDefinitionService)
|
||||||
: base("/qualityprofiles/schema")
|
: base("/qualityprofiles/schema")
|
||||||
{
|
{
|
||||||
|
_qualityDefinitionService = qualityDefinitionService;
|
||||||
|
|
||||||
GetResourceAll = GetAll;
|
GetResourceAll = GetAll;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<QualityProfileResource> GetAll()
|
private List<QualityProfileResource> GetAll()
|
||||||
{
|
{
|
||||||
|
var items = _qualityDefinitionService.All()
|
||||||
|
.OrderBy(v => v.Weight)
|
||||||
|
.Select(v => new QualityProfileItem { Quality = v.Quality, Allowed = false })
|
||||||
|
.ToList();
|
||||||
|
|
||||||
var profile = new QualityProfile();
|
var profile = new QualityProfile();
|
||||||
profile.Cutoff = Quality.Unknown;
|
profile.Cutoff = Quality.Unknown;
|
||||||
profile.Allowed = new List<Quality>();
|
profile.Items = items;
|
||||||
|
|
||||||
return new List<QualityProfileResource>{ QualityToResource(profile)};
|
return new List<QualityProfileResource> { profile.InjectTo<QualityProfileResource>() };
|
||||||
}
|
|
||||||
|
|
||||||
private static QualityProfileResource QualityToResource(QualityProfile profile)
|
|
||||||
{
|
|
||||||
return new QualityProfileResource
|
|
||||||
{
|
|
||||||
Available = Quality.All()
|
|
||||||
.Where(c => !profile.Allowed.Any(q => c.Id == q.Id))
|
|
||||||
.InjectTo<List<QualityResource>>(),
|
|
||||||
|
|
||||||
Allowed = profile.Allowed.InjectTo<List<QualityResource>>(),
|
|
||||||
Name = profile.Name,
|
|
||||||
Id = profile.Id
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentValidation;
|
||||||
|
using FluentValidation.Validators;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Qualities
|
||||||
|
{
|
||||||
|
public static class QualityProfileValidation
|
||||||
|
{
|
||||||
|
public static IRuleBuilderOptions<T, IList<QualityProfileItemResource>> MustHaveAllowedQuality<T>(this IRuleBuilder<T, IList<QualityProfileItemResource>> ruleBuilder)
|
||||||
|
{
|
||||||
|
ruleBuilder.SetValidator(new NotEmptyValidator(null));
|
||||||
|
|
||||||
|
return ruleBuilder.SetValidator(new AllowedValidator<T>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AllowedValidator<T> : PropertyValidator
|
||||||
|
{
|
||||||
|
public AllowedValidator()
|
||||||
|
: base("Must contain at least one allowed quality")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
|
{
|
||||||
|
var list = context.PropertyValue as IList<QualityProfileItemResource>;
|
||||||
|
|
||||||
|
if (list == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!list.Any(c => c.Allowed))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,38 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using NzbDrone.Core.Qualities;
|
|
||||||
using NzbDrone.Api.Mapping;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Qualities
|
|
||||||
{
|
|
||||||
public class QualitySizeModule : NzbDroneRestModule<QualitySizeResource>
|
|
||||||
{
|
|
||||||
private readonly IQualitySizeService _qualityTypeProvider;
|
|
||||||
|
|
||||||
public QualitySizeModule(IQualitySizeService qualityTypeProvider)
|
|
||||||
{
|
|
||||||
_qualityTypeProvider = qualityTypeProvider;
|
|
||||||
|
|
||||||
GetResourceAll = GetAll;
|
|
||||||
|
|
||||||
GetResourceById = GetById;
|
|
||||||
|
|
||||||
UpdateResource = Update;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Update(QualitySizeResource resource)
|
|
||||||
{
|
|
||||||
var model = resource.InjectTo<QualitySize>();
|
|
||||||
_qualityTypeProvider.Update(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
private QualitySizeResource GetById(int id)
|
|
||||||
{
|
|
||||||
return _qualityTypeProvider.Get(id).InjectTo<QualitySizeResource>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<QualitySizeResource> GetAll()
|
|
||||||
{
|
|
||||||
return ToListResource(_qualityTypeProvider.All);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
using System;
|
|
||||||
using NzbDrone.Api.REST;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Qualities
|
|
||||||
{
|
|
||||||
public class QualitySizeResource : RestResource
|
|
||||||
{
|
|
||||||
public Int32 QualityId { get; set; }
|
|
||||||
public String Name { get; set; }
|
|
||||||
public Int32 MinSize { get; set; }
|
|
||||||
public Int32 MaxSize { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Queue
|
namespace NzbDrone.Api.Queue
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using FluentValidation;
|
||||||
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.RootFolders;
|
using NzbDrone.Core.RootFolders;
|
||||||
using NzbDrone.Api.Mapping;
|
using NzbDrone.Api.Mapping;
|
||||||
|
@ -30,7 +33,15 @@ namespace NzbDrone.Api.RootFolders
|
||||||
|
|
||||||
private int CreateRootFolder(RootFolderResource rootFolderResource)
|
private int CreateRootFolder(RootFolderResource rootFolderResource)
|
||||||
{
|
{
|
||||||
return GetNewId<RootFolder>(_rootFolderService.Add, rootFolderResource);
|
try
|
||||||
|
{
|
||||||
|
return GetNewId<RootFolder>(_rootFolderService.Add, rootFolderResource);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new ValidationException(new [] { new ValidationFailure("Path", ex.Message) });
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<RootFolderResource> GetRootFolders()
|
private List<RootFolderResource> GetRootFolders()
|
||||||
|
|
|
@ -2,23 +2,39 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
|
using NzbDrone.Core.Datastore.Events;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.SeriesStats;
|
using NzbDrone.Core.SeriesStats;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Api.Validation;
|
using NzbDrone.Api.Validation;
|
||||||
using NzbDrone.Api.Mapping;
|
using NzbDrone.Api.Mapping;
|
||||||
|
using NzbDrone.Core.Tv.Events;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Series
|
namespace NzbDrone.Api.Series
|
||||||
{
|
{
|
||||||
public class SeriesModule : NzbDroneRestModule<SeriesResource>
|
public class SeriesModule : NzbDroneRestModuleWithSignalR<SeriesResource, Core.Tv.Series>,
|
||||||
|
IHandle<EpisodeImportedEvent>,
|
||||||
|
IHandle<EpisodeFileDeletedEvent>,
|
||||||
|
IHandle<SeriesUpdatedEvent>,
|
||||||
|
IHandle<SeriesEditedEvent>,
|
||||||
|
IHandle<SeriesDeletedEvent>
|
||||||
|
|
||||||
{
|
{
|
||||||
|
private readonly ICommandExecutor _commandExecutor;
|
||||||
private readonly ISeriesService _seriesService;
|
private readonly ISeriesService _seriesService;
|
||||||
private readonly ISeriesStatisticsService _seriesStatisticsService;
|
private readonly ISeriesStatisticsService _seriesStatisticsService;
|
||||||
private readonly IMapCoversToLocal _coverMapper;
|
private readonly IMapCoversToLocal _coverMapper;
|
||||||
|
|
||||||
public SeriesModule(ISeriesService seriesService, ISeriesStatisticsService seriesStatisticsService, IMapCoversToLocal coverMapper)
|
public SeriesModule(ICommandExecutor commandExecutor,
|
||||||
: base("/Series")
|
ISeriesService seriesService,
|
||||||
|
ISeriesStatisticsService seriesStatisticsService,
|
||||||
|
IMapCoversToLocal coverMapper)
|
||||||
|
: base(commandExecutor)
|
||||||
{
|
{
|
||||||
|
_commandExecutor = commandExecutor;
|
||||||
_seriesService = seriesService;
|
_seriesService = seriesService;
|
||||||
_seriesStatisticsService = seriesStatisticsService;
|
_seriesStatisticsService = seriesStatisticsService;
|
||||||
_coverMapper = coverMapper;
|
_coverMapper = coverMapper;
|
||||||
|
@ -74,6 +90,8 @@ namespace NzbDrone.Api.Series
|
||||||
private void UpdateSeries(SeriesResource seriesResource)
|
private void UpdateSeries(SeriesResource seriesResource)
|
||||||
{
|
{
|
||||||
GetNewId<Core.Tv.Series>(_seriesService.UpdateSeries, seriesResource);
|
GetNewId<Core.Tv.Series>(_seriesService.UpdateSeries, seriesResource);
|
||||||
|
|
||||||
|
BroadcastResourceChange(ModelAction.Updated, seriesResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteSeries(int id)
|
private void DeleteSeries(int id)
|
||||||
|
@ -119,5 +137,32 @@ namespace NzbDrone.Api.Series
|
||||||
resource.EpisodeFileCount = seriesStatistics.EpisodeFileCount;
|
resource.EpisodeFileCount = seriesStatistics.EpisodeFileCount;
|
||||||
resource.NextAiring = seriesStatistics.NextAiring;
|
resource.NextAiring = seriesStatistics.NextAiring;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Handle(EpisodeImportedEvent message)
|
||||||
|
{
|
||||||
|
BroadcastResourceChange(ModelAction.Updated, message.ImportedEpisode.SeriesId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(EpisodeFileDeletedEvent message)
|
||||||
|
{
|
||||||
|
if (message.ForUpgrade) return;
|
||||||
|
|
||||||
|
BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.SeriesId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(SeriesUpdatedEvent message)
|
||||||
|
{
|
||||||
|
BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(SeriesEditedEvent message)
|
||||||
|
{
|
||||||
|
BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(SeriesDeletedEvent message)
|
||||||
|
{
|
||||||
|
BroadcastResourceChange(ModelAction.Deleted, message.Series.InjectTo<SeriesResource>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,7 @@ namespace NzbDrone.App.Test
|
||||||
[Test]
|
[Test]
|
||||||
public void should_continue_if_only_instance()
|
public void should_continue_if_only_instance()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IProcessProvider>()
|
Mocker.GetMock<INzbDroneProcessProvider>().Setup(c => c.FindNzbDroneProcesses())
|
||||||
.Setup(c => c.FindProcessByName(ProcessProvider.NZB_DRONE_CONSOLE_PROCESS_NAME))
|
|
||||||
.Returns(new List<ProcessInfo>());
|
|
||||||
|
|
||||||
Mocker.GetMock<IProcessProvider>().Setup(c => c.FindProcessByName(ProcessProvider.NZB_DRONE_PROCESS_NAME))
|
|
||||||
.Returns(new List<ProcessInfo>
|
.Returns(new List<ProcessInfo>
|
||||||
{
|
{
|
||||||
new ProcessInfo{Id = CURRENT_PROCESS_ID}
|
new ProcessInfo{Id = CURRENT_PROCESS_ID}
|
||||||
|
@ -36,29 +32,20 @@ namespace NzbDrone.App.Test
|
||||||
|
|
||||||
Subject.PreventStartIfAlreadyRunning();
|
Subject.PreventStartIfAlreadyRunning();
|
||||||
|
|
||||||
|
|
||||||
Mocker.GetMock<IBrowserService>().Verify(c => c.LaunchWebUI(), Times.Never());
|
Mocker.GetMock<IBrowserService>().Verify(c => c.LaunchWebUI(), Times.Never());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_enforce_if_another_console_is_running()
|
public void should_enforce_if_another_console_is_running()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IProcessProvider>()
|
Mocker.GetMock<INzbDroneProcessProvider>()
|
||||||
.Setup(c => c.FindProcessByName(ProcessProvider.NZB_DRONE_CONSOLE_PROCESS_NAME))
|
.Setup(c => c.FindNzbDroneProcesses())
|
||||||
.Returns(new List<ProcessInfo>
|
.Returns(new List<ProcessInfo>
|
||||||
{
|
{
|
||||||
new ProcessInfo{Id = 10}
|
new ProcessInfo{Id = 10},
|
||||||
});
|
|
||||||
|
|
||||||
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 = CURRENT_PROCESS_ID}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Assert.Throws<TerminateApplicationException>(() => Subject.PreventStartIfAlreadyRunning());
|
Assert.Throws<TerminateApplicationException>(() => Subject.PreventStartIfAlreadyRunning());
|
||||||
Mocker.GetMock<IBrowserService>().Verify(c => c.LaunchWebUI(), Times.Once());
|
Mocker.GetMock<IBrowserService>().Verify(c => c.LaunchWebUI(), Times.Once());
|
||||||
ExceptionVerification.ExpectedWarns(1);
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
|
@ -67,22 +54,15 @@ namespace NzbDrone.App.Test
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_false_if_another_gui_is_running()
|
public void should_return_false_if_another_gui_is_running()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IProcessProvider>()
|
Mocker.GetMock<INzbDroneProcessProvider>()
|
||||||
.Setup(c => c.FindProcessByName(ProcessProvider.NZB_DRONE_CONSOLE_PROCESS_NAME))
|
.Setup(c => c.FindNzbDroneProcesses())
|
||||||
.Returns(new List<ProcessInfo>
|
.Returns(new List<ProcessInfo>
|
||||||
{
|
{
|
||||||
new ProcessInfo{Id = CURRENT_PROCESS_ID}
|
new ProcessInfo{Id = CURRENT_PROCESS_ID},
|
||||||
|
new ProcessInfo{Id = 10}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Mocker.GetMock<IProcessProvider>().Setup(c => c.FindProcessByName(ProcessProvider.NZB_DRONE_PROCESS_NAME))
|
|
||||||
.Returns(new List<ProcessInfo>
|
|
||||||
{
|
|
||||||
new ProcessInfo{Id = 10}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Assert.Throws<TerminateApplicationException>(() => Subject.PreventStartIfAlreadyRunning());
|
Assert.Throws<TerminateApplicationException>(() => Subject.PreventStartIfAlreadyRunning());
|
||||||
Mocker.GetMock<IBrowserService>().Verify(c => c.LaunchWebUI(), Times.Once());
|
Mocker.GetMock<IBrowserService>().Verify(c => c.LaunchWebUI(), Times.Once());
|
||||||
ExceptionVerification.ExpectedWarns(1);
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
|
|
|
@ -73,7 +73,6 @@
|
||||||
<Compile Include="EnvironmentProviderTest.cs" />
|
<Compile Include="EnvironmentProviderTest.cs" />
|
||||||
<Compile Include="ProcessProviderTests.cs" />
|
<Compile Include="ProcessProviderTests.cs" />
|
||||||
<Compile Include="ReflectionTests\ReflectionExtensionFixture.cs" />
|
<Compile Include="ReflectionTests\ReflectionExtensionFixture.cs" />
|
||||||
<Compile Include="ServiceFactoryFixture.cs" />
|
|
||||||
<Compile Include="ServiceProviderTests.cs" />
|
<Compile Include="ServiceProviderTests.cs" />
|
||||||
<Compile Include="WebClientTests.cs" />
|
<Compile Include="WebClientTests.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -204,6 +204,20 @@ namespace NzbDrone.Common.Disk
|
||||||
File.Delete(path);
|
File.Delete(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void CopyFile(string source, string destination, bool overwrite = false)
|
||||||
|
{
|
||||||
|
Ensure.That(source, () => source).IsValidPath();
|
||||||
|
Ensure.That(destination, () => destination).IsValidPath();
|
||||||
|
|
||||||
|
if (source.PathEquals(destination))
|
||||||
|
{
|
||||||
|
Logger.Warn("Source and destination can't be the same {0}", source);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File.Copy(source, destination, overwrite);
|
||||||
|
}
|
||||||
|
|
||||||
public void MoveFile(string source, string destination)
|
public void MoveFile(string source, string destination)
|
||||||
{
|
{
|
||||||
Ensure.That(source, () => source).IsValidPath();
|
Ensure.That(source, () => source).IsValidPath();
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace NzbDrone.Common.Disk
|
||||||
void CopyFolder(string source, string destination);
|
void CopyFolder(string source, string destination);
|
||||||
void MoveFolder(string source, string destination);
|
void MoveFolder(string source, string destination);
|
||||||
void DeleteFile(string path);
|
void DeleteFile(string path);
|
||||||
|
void CopyFile(string source, string destination, bool overwrite = false);
|
||||||
void MoveFile(string source, string destination);
|
void MoveFile(string source, string destination);
|
||||||
void DeleteFolder(string path, bool recursive);
|
void DeleteFolder(string path, bool recursive);
|
||||||
string ReadAllText(string filePath);
|
string ReadAllText(string filePath);
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Security.AccessControl;
|
|
||||||
using System.Security.Principal;
|
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Common.Disk;
|
|
||||||
using NzbDrone.Common.Instrumentation;
|
|
||||||
|
|
||||||
namespace NzbDrone.Common.EnvironmentInfo
|
namespace NzbDrone.Common.EnvironmentInfo
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,37 +1,45 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.ServiceProcess;
|
using System.ServiceProcess;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Common.Processes;
|
||||||
|
|
||||||
namespace NzbDrone.Common.EnvironmentInfo
|
namespace NzbDrone.Common.EnvironmentInfo
|
||||||
{
|
{
|
||||||
|
|
||||||
public interface IRuntimeInfo
|
public interface IRuntimeInfo
|
||||||
{
|
{
|
||||||
bool IsUserInteractive { get; }
|
bool IsUserInteractive { get; }
|
||||||
bool IsAdmin { get; }
|
bool IsAdmin { get; }
|
||||||
bool IsWindowsService { get; }
|
bool IsWindowsService { get; }
|
||||||
|
bool IsConsole { get; }
|
||||||
|
bool IsRunning { get; set; }
|
||||||
|
string ExecutingApplication { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RuntimeInfo : IRuntimeInfo
|
public class RuntimeInfo : IRuntimeInfo
|
||||||
{
|
{
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
private static readonly string ProcessName = Process.GetCurrentProcess().ProcessName.ToLower();
|
||||||
|
|
||||||
public RuntimeInfo(Logger logger, IServiceProvider serviceProvider)
|
public RuntimeInfo(Logger logger, IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
IsWindowsService = !IsUserInteractive &&
|
IsWindowsService = !IsUserInteractive &&
|
||||||
OsInfo.IsWindows &&
|
OsInfo.IsWindows &&
|
||||||
serviceProvider.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME) &&
|
serviceProvider.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME) &&
|
||||||
serviceProvider.GetStatus(ServiceProvider.NZBDRONE_SERVICE_NAME) == ServiceControllerStatus.StartPending;
|
serviceProvider.GetStatus(ServiceProvider.NZBDRONE_SERVICE_NAME) == ServiceControllerStatus.StartPending;
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsUserInteractive
|
//Guarded to avoid issues when running in a non-managed process
|
||||||
{
|
var entry = Assembly.GetEntryAssembly();
|
||||||
get { return Environment.UserInteractive; }
|
|
||||||
|
if (entry != null)
|
||||||
|
{
|
||||||
|
ExecutingApplication = entry.Location;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static RuntimeInfo()
|
static RuntimeInfo()
|
||||||
|
@ -39,6 +47,11 @@ namespace NzbDrone.Common.EnvironmentInfo
|
||||||
IsProduction = InternalIsProduction();
|
IsProduction = InternalIsProduction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsUserInteractive
|
||||||
|
{
|
||||||
|
get { return Environment.UserInteractive; }
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsAdmin
|
public bool IsAdmin
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -58,7 +71,19 @@ namespace NzbDrone.Common.EnvironmentInfo
|
||||||
|
|
||||||
public bool IsWindowsService { get; private set; }
|
public bool IsWindowsService { get; private set; }
|
||||||
|
|
||||||
private static readonly string ProcessName = Process.GetCurrentProcess().ProcessName.ToLower();
|
public bool IsConsole
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (OsInfo.IsWindows &&
|
||||||
|
IsUserInteractive &&
|
||||||
|
ProcessName.Equals(ProcessProvider.NZB_DRONE_CONSOLE_PROCESS_NAME, StringComparison.InvariantCultureIgnoreCase)) ||
|
||||||
|
OsInfo.IsLinux;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsRunning { get; set; }
|
||||||
|
public string ExecutingApplication { get; private set; }
|
||||||
|
|
||||||
public static bool IsProduction { get; private set; }
|
public static bool IsProduction { get; private set; }
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace NzbDrone.Common.EnvironmentInfo
|
||||||
internal const string INSTALL_SERVICE = "i";
|
internal const string INSTALL_SERVICE = "i";
|
||||||
internal const string UNINSTALL_SERVICE = "u";
|
internal const string UNINSTALL_SERVICE = "u";
|
||||||
public const string HELP = "?";
|
public const string HELP = "?";
|
||||||
|
public const string TERMINATE = "terminateexisting";
|
||||||
|
|
||||||
public StartupContext(params string[] args)
|
public StartupContext(params string[] args)
|
||||||
{
|
{
|
||||||
|
@ -58,6 +59,5 @@ namespace NzbDrone.Common.EnvironmentInfo
|
||||||
return Flags.Contains(UNINSTALL_SERVICE);
|
return Flags.Contains(UNINSTALL_SERVICE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,6 +5,7 @@ using NLog;
|
||||||
using NLog.Config;
|
using NLog.Config;
|
||||||
using NLog.Targets;
|
using NLog.Targets;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
using NzbDrone.Common.Processes;
|
||||||
|
|
||||||
namespace NzbDrone.Common.Instrumentation
|
namespace NzbDrone.Common.Instrumentation
|
||||||
{
|
{
|
||||||
|
@ -30,7 +31,7 @@ namespace NzbDrone.Common.Instrumentation
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (inConsole && (OsInfo.IsLinux || new RuntimeInfo(null, new ServiceProvider()).IsUserInteractive))
|
if (inConsole && (OsInfo.IsLinux || new RuntimeInfo(null, new ServiceProvider(new ProcessProvider())).IsUserInteractive))
|
||||||
{
|
{
|
||||||
RegisterConsole();
|
RegisterConsole();
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,7 @@
|
||||||
<Compile Include="Messaging\IEvent.cs" />
|
<Compile Include="Messaging\IEvent.cs" />
|
||||||
<Compile Include="Messaging\IMessage.cs" />
|
<Compile Include="Messaging\IMessage.cs" />
|
||||||
<Compile Include="PathEqualityComparer.cs" />
|
<Compile Include="PathEqualityComparer.cs" />
|
||||||
|
<Compile Include="Processes\INzbDroneProcessProvider.cs" />
|
||||||
<Compile Include="Processes\ProcessOutput.cs" />
|
<Compile Include="Processes\ProcessOutput.cs" />
|
||||||
<Compile Include="Serializer\IntConverter.cs" />
|
<Compile Include="Serializer\IntConverter.cs" />
|
||||||
<Compile Include="Services.cs" />
|
<Compile Include="Services.cs" />
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace NzbDrone.Common
|
||||||
private static readonly string UPDATE_SANDBOX_FOLDER_NAME = "nzbdrone_update" + Path.DirectorySeparatorChar;
|
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_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;
|
private static readonly string UPDATE_CLIENT_FOLDER_NAME = "NzbDrone.Update" + Path.DirectorySeparatorChar;
|
||||||
private static readonly string UPDATE_LOG_FOLDER_NAME = "UpdateLogs" + Path.DirectorySeparatorChar;
|
private static readonly string UPDATE_LOG_FOLDER_NAME = "UpdateLogs" + Path.DirectorySeparatorChar;
|
||||||
|
|
||||||
|
@ -155,6 +156,21 @@ namespace NzbDrone.Common
|
||||||
return Path.Combine(GetUpdateSandboxFolder(appFolderInfo), UPDATE_BACKUP_FOLDER_NAME);
|
return Path.Combine(GetUpdateSandboxFolder(appFolderInfo), UPDATE_BACKUP_FOLDER_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetUpdateBackUpAppDataFolder(this IAppFolderInfo appFolderInfo)
|
||||||
|
{
|
||||||
|
return Path.Combine(GetUpdateSandboxFolder(appFolderInfo), UPDATE_BACKUP_APPDATA_FOLDER_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetUpdateBackupConfigFile(this IAppFolderInfo appFolderInfo)
|
||||||
|
{
|
||||||
|
return Path.Combine(GetUpdateBackUpAppDataFolder(appFolderInfo), APP_CONFIG_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetUpdateBackupDatabase(this IAppFolderInfo appFolderInfo)
|
||||||
|
{
|
||||||
|
return Path.Combine(GetUpdateBackUpAppDataFolder(appFolderInfo), NZBDRONE_DB);
|
||||||
|
}
|
||||||
|
|
||||||
public static string GetUpdatePackageFolder(this IAppFolderInfo appFolderInfo)
|
public static string GetUpdatePackageFolder(this IAppFolderInfo appFolderInfo)
|
||||||
{
|
{
|
||||||
return Path.Combine(GetUpdateSandboxFolder(appFolderInfo), UPDATE_PACKAGE_FOLDER_NAME);
|
return Path.Combine(GetUpdateSandboxFolder(appFolderInfo), UPDATE_PACKAGE_FOLDER_NAME);
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Common.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Common.Processes
|
||||||
|
{
|
||||||
|
public interface INzbDroneProcessProvider
|
||||||
|
{
|
||||||
|
List<ProcessInfo> FindNzbDroneProcesses();
|
||||||
|
}
|
||||||
|
}
|
|
@ -269,6 +269,7 @@ namespace NzbDrone.Common.Processes
|
||||||
|
|
||||||
if (process.HasExited)
|
if (process.HasExited)
|
||||||
{
|
{
|
||||||
|
Logger.Trace("Process has already exited");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,15 +41,22 @@ namespace NzbDrone.Common.Serializer
|
||||||
return JsonConvert.DeserializeObject(json, type, SerializerSetting);
|
return JsonConvert.DeserializeObject(json, type, SerializerSetting);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T TryDeserialize<T>(string json) where T : new()
|
public static bool TryDeserialize<T>(string json, out T result) where T : new()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Deserialize<T>(json);
|
result = Deserialize<T>(json);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
catch (JsonReaderException ex)
|
catch (JsonReaderException ex)
|
||||||
{
|
{
|
||||||
return default(T);
|
result = default(T);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (JsonSerializationException ex)
|
||||||
|
{
|
||||||
|
result = default(T);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System.Linq;
|
||||||
using System.ServiceProcess;
|
using System.ServiceProcess;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Instrumentation;
|
using NzbDrone.Common.Instrumentation;
|
||||||
|
using NzbDrone.Common.Processes;
|
||||||
|
|
||||||
namespace NzbDrone.Common
|
namespace NzbDrone.Common
|
||||||
{
|
{
|
||||||
|
@ -20,14 +21,22 @@ namespace NzbDrone.Common
|
||||||
void Stop(string serviceName);
|
void Stop(string serviceName);
|
||||||
void Start(string serviceName);
|
void Start(string serviceName);
|
||||||
ServiceControllerStatus GetStatus(string serviceName);
|
ServiceControllerStatus GetStatus(string serviceName);
|
||||||
|
void Restart(string serviceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ServiceProvider : IServiceProvider
|
public class ServiceProvider : IServiceProvider
|
||||||
{
|
{
|
||||||
public const string NZBDRONE_SERVICE_NAME = "NzbDrone";
|
public const string NZBDRONE_SERVICE_NAME = "NzbDrone";
|
||||||
|
|
||||||
|
private readonly IProcessProvider _processProvider;
|
||||||
|
|
||||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
|
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
|
||||||
|
|
||||||
|
public ServiceProvider(IProcessProvider processProvider)
|
||||||
|
{
|
||||||
|
_processProvider = processProvider;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual bool ServiceExist(string name)
|
public virtual bool ServiceExist(string name)
|
||||||
{
|
{
|
||||||
Logger.Debug("Checking if service {0} exists.", name);
|
Logger.Debug("Checking if service {0} exists.", name);
|
||||||
|
@ -173,5 +182,12 @@ namespace NzbDrone.Common
|
||||||
Logger.Error("Service start request has timed out. {0}", service.Status);
|
Logger.Error("Service start request has timed out. {0}", service.Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Restart(string serviceName)
|
||||||
|
{
|
||||||
|
var args = String.Format("/C net.exe stop \"{0}\" && net.exe start \"{0}\"", serviceName);
|
||||||
|
|
||||||
|
_processProvider.Start("cmd.exe", args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,6 +25,9 @@ namespace NzbDrone.Console
|
||||||
Logger.FatalException("EPIC FAIL!", e);
|
Logger.FatalException("EPIC FAIL!", e);
|
||||||
System.Console.WriteLine("Press any key to exit...");
|
System.Console.WriteLine("Press any key to exit...");
|
||||||
System.Console.ReadLine();
|
System.Console.ReadLine();
|
||||||
|
|
||||||
|
//Need this to terminate on mono (thanks nlog)
|
||||||
|
LogManager.Configuration = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,7 @@ namespace NzbDrone.Core.Test.Datastore
|
||||||
public void one_to_one()
|
public void one_to_one()
|
||||||
{
|
{
|
||||||
var episodeFile = Builder<EpisodeFile>.CreateNew()
|
var episodeFile = Builder<EpisodeFile>.CreateNew()
|
||||||
|
.With(c => c.Quality = new QualityModel())
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
Db.Insert(episodeFile);
|
Db.Insert(episodeFile);
|
||||||
|
|
|
@ -81,31 +81,30 @@ namespace NzbDrone.Core.Test.Datastore.SQLiteMigrationHelperTests
|
||||||
[Test]
|
[Test]
|
||||||
public void should_read_existing_indexes()
|
public void should_read_existing_indexes()
|
||||||
{
|
{
|
||||||
var indexes = _subject.GetIndexes("QualitySizes");
|
var indexes = _subject.GetIndexes("QualityDefinitions");
|
||||||
|
|
||||||
indexes.Should().NotBeEmpty();
|
indexes.Should().NotBeEmpty();
|
||||||
|
|
||||||
indexes.Should().OnlyContain(c => c != null);
|
indexes.Should().OnlyContain(c => c != null);
|
||||||
indexes.Should().OnlyContain(c => !string.IsNullOrWhiteSpace(c.Column));
|
indexes.Should().OnlyContain(c => !string.IsNullOrWhiteSpace(c.Column));
|
||||||
indexes.Should().OnlyContain(c => c.Table == "QualitySizes");
|
indexes.Should().OnlyContain(c => c.Table == "QualityDefinitions");
|
||||||
indexes.Should().OnlyContain(c => c.Unique);
|
indexes.Should().OnlyContain(c => c.Unique);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_add_indexes_when_creating_new_table()
|
public void should_add_indexes_when_creating_new_table()
|
||||||
{
|
{
|
||||||
var columns = _subject.GetColumns("QualitySizes");
|
var columns = _subject.GetColumns("QualityDefinitions");
|
||||||
var indexes = _subject.GetIndexes("QualitySizes");
|
var indexes = _subject.GetIndexes("QualityDefinitions");
|
||||||
|
|
||||||
_subject.CreateTable("QualityB", columns.Values, indexes);
|
_subject.CreateTable("QualityDefinitionsB", columns.Values, indexes);
|
||||||
|
|
||||||
var newIndexes = _subject.GetIndexes("QualityB");
|
var newIndexes = _subject.GetIndexes("QualityDefinitionsB");
|
||||||
|
|
||||||
newIndexes.Should().HaveSameCount(indexes);
|
newIndexes.Should().HaveSameCount(indexes);
|
||||||
newIndexes.Select(c=>c.Column).Should().BeEquivalentTo(indexes.Select(c=>c.Column));
|
newIndexes.Select(c=>c.Column).Should().BeEquivalentTo(indexes.Select(c=>c.Column));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_be_able_to_create_table_with_new_indexes()
|
public void should_be_able_to_create_table_with_new_indexes()
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
private RemoteEpisode parseResultSingle;
|
private RemoteEpisode parseResultSingle;
|
||||||
private Series series30minutes;
|
private Series series30minutes;
|
||||||
private Series series60minutes;
|
private Series series60minutes;
|
||||||
private QualitySize qualityType;
|
private QualityDefinition qualityType;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
|
@ -47,10 +47,10 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
.With(c => c.Runtime = 60)
|
.With(c => c.Runtime = 60)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
qualityType = Builder<QualitySize>.CreateNew()
|
qualityType = Builder<QualityDefinition>.CreateNew()
|
||||||
.With(q => q.MinSize = 0)
|
.With(q => q.MinSize = 0)
|
||||||
.With(q => q.MaxSize = 10)
|
.With(q => q.MaxSize = 10)
|
||||||
.With(q => q.QualityId = 1)
|
.With(q => q.Quality = Quality.SDTV)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
parseResultSingle.Series = series30minutes;
|
parseResultSingle.Series = series30minutes;
|
||||||
parseResultSingle.Release.Size = 184572800;
|
parseResultSingle.Release.Size = 184572800;
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
Mocker.GetMock<IEpisodeService>().Setup(
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||||
|
@ -80,7 +80,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
parseResultSingle.Series = series60minutes;
|
parseResultSingle.Series = series60minutes;
|
||||||
parseResultSingle.Release.Size = 368572800;
|
parseResultSingle.Release.Size = 368572800;
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
Mocker.GetMock<IEpisodeService>().Setup(
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||||
|
@ -99,7 +99,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
parseResultSingle.Series = series30minutes;
|
parseResultSingle.Series = series30minutes;
|
||||||
parseResultSingle.Release.Size = 1.Gigabytes();
|
parseResultSingle.Release.Size = 1.Gigabytes();
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
Mocker.GetMock<IEpisodeService>().Setup(
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||||
|
@ -118,7 +118,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
parseResultSingle.Series = series60minutes;
|
parseResultSingle.Series = series60minutes;
|
||||||
parseResultSingle.Release.Size = 1.Gigabytes();
|
parseResultSingle.Release.Size = 1.Gigabytes();
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
Mocker.GetMock<IEpisodeService>().Setup(
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||||
|
@ -135,7 +135,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
parseResultMulti.Series = series30minutes;
|
parseResultMulti.Series = series30minutes;
|
||||||
parseResultMulti.Release.Size = 184572800;
|
parseResultMulti.Release.Size = 184572800;
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
Mocker.GetMock<IEpisodeService>().Setup(
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||||
|
@ -154,7 +154,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
parseResultMulti.Series = series60minutes;
|
parseResultMulti.Series = series60minutes;
|
||||||
parseResultMulti.Release.Size = 368572800;
|
parseResultMulti.Release.Size = 368572800;
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
Mocker.GetMock<IEpisodeService>().Setup(
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||||
|
@ -173,7 +173,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
parseResultMulti.Series = series30minutes;
|
parseResultMulti.Series = series30minutes;
|
||||||
parseResultMulti.Release.Size = 1.Gigabytes();
|
parseResultMulti.Release.Size = 1.Gigabytes();
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
Mocker.GetMock<IEpisodeService>().Setup(
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||||
|
@ -192,7 +192,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
parseResultMulti.Series = series60minutes;
|
parseResultMulti.Series = series60minutes;
|
||||||
parseResultMulti.Release.Size = 10.Gigabytes();
|
parseResultMulti.Release.Size = 10.Gigabytes();
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
Mocker.GetMock<IEpisodeService>().Setup(
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||||
|
@ -211,7 +211,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
parseResultSingle.Series = series30minutes;
|
parseResultSingle.Series = series30minutes;
|
||||||
parseResultSingle.Release.Size = 184572800;
|
parseResultSingle.Release.Size = 184572800;
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
Mocker.GetMock<IEpisodeService>().Setup(
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||||
|
@ -230,7 +230,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
parseResultSingle.Series = series60minutes;
|
parseResultSingle.Series = series60minutes;
|
||||||
parseResultSingle.Release.Size = 368572800;
|
parseResultSingle.Release.Size = 368572800;
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
Mocker.GetMock<IEpisodeService>().Setup(
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||||
|
@ -249,7 +249,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
parseResultSingle.Series = series30minutes;
|
parseResultSingle.Series = series30minutes;
|
||||||
parseResultSingle.Release.Size = 1.Gigabytes();
|
parseResultSingle.Release.Size = 1.Gigabytes();
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
Mocker.GetMock<IEpisodeService>().Setup(
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||||
|
@ -270,7 +270,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
parseResultSingle.Series = series60minutes;
|
parseResultSingle.Series = series60minutes;
|
||||||
parseResultSingle.Release.Size = 10.Gigabytes();
|
parseResultSingle.Release.Size = 10.Gigabytes();
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
Mocker.GetMock<IEpisodeService>().Setup(
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||||
|
@ -292,7 +292,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
parseResultSingle.Release.Size = 18457280000;
|
parseResultSingle.Release.Size = 18457280000;
|
||||||
qualityType.MaxSize = 0;
|
qualityType.MaxSize = 0;
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
Mocker.GetMock<IEpisodeService>().Setup(
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||||
|
@ -314,7 +314,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
parseResultSingle.Release.Size = 36857280000;
|
parseResultSingle.Release.Size = 36857280000;
|
||||||
qualityType.MaxSize = 0;
|
qualityType.MaxSize = 0;
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
Mocker.GetMock<IEpisodeService>().Setup(
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||||
|
@ -338,7 +338,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
|
|
||||||
qualityType.MaxSize = (int)600.Megabytes();
|
qualityType.MaxSize = (int)600.Megabytes();
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
|
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
Mocker.GetMock<IEpisodeService>().Setup(
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||||
|
@ -374,7 +374,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
Subject.IsSatisfiedBy(parseResult, null).Should().BeFalse();
|
Subject.IsSatisfiedBy(parseResult, null).Should().BeFalse();
|
||||||
|
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeService>().Verify(c=>c.Get(It.IsAny<int>()),Times.Never());
|
Mocker.GetMock<IQualityDefinitionService>().Verify(c => c.Get(It.IsAny<Quality>()), Times.Never());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,35 +13,35 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_true_if_current_episode_is_less_than_cutoff()
|
public void should_return_true_if_current_episode_is_less_than_cutoff()
|
||||||
{
|
{
|
||||||
Subject.CutoffNotMet(new QualityProfile { Cutoff = Quality.Bluray1080p },
|
Subject.CutoffNotMet(new QualityProfile { Cutoff = Quality.Bluray1080p, Items = Qualities.QualityFixture.GetDefaultQualities() },
|
||||||
new QualityModel(Quality.DVD, true)).Should().BeTrue();
|
new QualityModel(Quality.DVD, true)).Should().BeTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_false_if_current_episode_is_equal_to_cutoff()
|
public void should_return_false_if_current_episode_is_equal_to_cutoff()
|
||||||
{
|
{
|
||||||
Subject.CutoffNotMet(new QualityProfile { Cutoff = Quality.HDTV720p },
|
Subject.CutoffNotMet(new QualityProfile { Cutoff = Quality.HDTV720p, Items = Qualities.QualityFixture.GetDefaultQualities() },
|
||||||
new QualityModel(Quality.HDTV720p, true)).Should().BeFalse();
|
new QualityModel(Quality.HDTV720p, true)).Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_false_if_current_episode_is_greater_than_cutoff()
|
public void should_return_false_if_current_episode_is_greater_than_cutoff()
|
||||||
{
|
{
|
||||||
Subject.CutoffNotMet(new QualityProfile { Cutoff = Quality.HDTV720p },
|
Subject.CutoffNotMet(new QualityProfile { Cutoff = Quality.HDTV720p, Items = Qualities.QualityFixture.GetDefaultQualities() },
|
||||||
new QualityModel(Quality.Bluray1080p, true)).Should().BeFalse();
|
new QualityModel(Quality.Bluray1080p, true)).Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_true_when_new_episode_is_proper_but_existing_is_not()
|
public void should_return_true_when_new_episode_is_proper_but_existing_is_not()
|
||||||
{
|
{
|
||||||
Subject.CutoffNotMet(new QualityProfile { Cutoff = Quality.HDTV720p },
|
Subject.CutoffNotMet(new QualityProfile { Cutoff = Quality.HDTV720p, Items = Qualities.QualityFixture.GetDefaultQualities() },
|
||||||
new QualityModel(Quality.HDTV720p, false), new QualityModel(Quality.HDTV720p, true)).Should().BeTrue();
|
new QualityModel(Quality.HDTV720p, false), new QualityModel(Quality.HDTV720p, true)).Should().BeTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_false_if_cutoff_is_met_and_quality_is_higher()
|
public void should_return_false_if_cutoff_is_met_and_quality_is_higher()
|
||||||
{
|
{
|
||||||
Subject.CutoffNotMet(new QualityProfile { Cutoff = Quality.HDTV720p },
|
Subject.CutoffNotMet(new QualityProfile { Cutoff = Quality.HDTV720p, Items = Qualities.QualityFixture.GetDefaultQualities() },
|
||||||
new QualityModel(Quality.HDTV720p, true), new QualityModel(Quality.Bluray1080p, true)).Should().BeFalse();
|
new QualityModel(Quality.HDTV720p, true), new QualityModel(Quality.Bluray1080p, true)).Should().BeFalse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
};
|
};
|
||||||
|
|
||||||
_fakeSeries = Builder<Series>.CreateNew()
|
_fakeSeries = Builder<Series>.CreateNew()
|
||||||
.With(c => c.QualityProfile = new QualityProfile { Cutoff = Quality.Bluray1080p })
|
.With(c => c.QualityProfile = new QualityProfile { Cutoff = Quality.Bluray1080p, Items = Qualities.QualityFixture.GetDefaultQualities() })
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
_parseResultMulti = new RemoteEpisode
|
_parseResultMulti = new RemoteEpisode
|
||||||
|
@ -62,11 +62,9 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
_upgradableQuality = new QualityModel(Quality.SDTV, false);
|
_upgradableQuality = new QualityModel(Quality.SDTV, false);
|
||||||
_notupgradableQuality = new QualityModel(Quality.HDTV1080p, true);
|
_notupgradableQuality = new QualityModel(Quality.HDTV1080p, true);
|
||||||
|
|
||||||
|
Mocker.GetMock<IHistoryService>().Setup(c => c.GetBestQualityInHistory(It.IsAny<QualityProfile>(), 1)).Returns(_notupgradableQuality);
|
||||||
|
Mocker.GetMock<IHistoryService>().Setup(c => c.GetBestQualityInHistory(It.IsAny<QualityProfile>(), 2)).Returns(_notupgradableQuality);
|
||||||
Mocker.GetMock<IHistoryService>().Setup(c => c.GetBestQualityInHistory(1)).Returns(_notupgradableQuality);
|
Mocker.GetMock<IHistoryService>().Setup(c => c.GetBestQualityInHistory(It.IsAny<QualityProfile>(), 3)).Returns<QualityModel>(null);
|
||||||
Mocker.GetMock<IHistoryService>().Setup(c => c.GetBestQualityInHistory(2)).Returns(_notupgradableQuality);
|
|
||||||
Mocker.GetMock<IHistoryService>().Setup(c => c.GetBestQualityInHistory(3)).Returns<QualityModel>(null);
|
|
||||||
|
|
||||||
Mocker.GetMock<IProvideDownloadClient>()
|
Mocker.GetMock<IProvideDownloadClient>()
|
||||||
.Setup(c => c.GetDownloadClient()).Returns(Mocker.GetMock<IDownloadClient>().Object);
|
.Setup(c => c.GetDownloadClient()).Returns(Mocker.GetMock<IDownloadClient>().Object);
|
||||||
|
@ -74,12 +72,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
|
|
||||||
private void WithFirstReportUpgradable()
|
private void WithFirstReportUpgradable()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IHistoryService>().Setup(c => c.GetBestQualityInHistory(1)).Returns(_upgradableQuality);
|
Mocker.GetMock<IHistoryService>().Setup(c => c.GetBestQualityInHistory(It.IsAny<QualityProfile>(), 1)).Returns(_upgradableQuality);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WithSecondReportUpgradable()
|
private void WithSecondReportUpgradable()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IHistoryService>().Setup(c => c.GetBestQualityInHistory(2)).Returns(_upgradableQuality);
|
Mocker.GetMock<IHistoryService>().Setup(c => c.GetBestQualityInHistory(It.IsAny<QualityProfile>(), 2)).Returns(_upgradableQuality);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenSabnzbdDownloadClient()
|
private void GivenSabnzbdDownloadClient()
|
||||||
|
@ -132,11 +130,11 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_be_upgradable_if_episode_is_of_same_quality_as_existing()
|
public void should_not_be_upgradable_if_episode_is_of_same_quality_as_existing()
|
||||||
{
|
{
|
||||||
_fakeSeries.QualityProfile = new QualityProfile { Cutoff = Quality.WEBDL1080p };
|
_fakeSeries.QualityProfile = new QualityProfile { Cutoff = Quality.WEBDL1080p, Items = Qualities.QualityFixture.GetDefaultQualities() };
|
||||||
_parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.WEBDL1080p, false);
|
_parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.WEBDL1080p, false);
|
||||||
_upgradableQuality = new QualityModel(Quality.WEBDL1080p, false);
|
_upgradableQuality = new QualityModel(Quality.WEBDL1080p, false);
|
||||||
|
|
||||||
Mocker.GetMock<IHistoryService>().Setup(c => c.GetBestQualityInHistory(1)).Returns(_upgradableQuality);
|
Mocker.GetMock<IHistoryService>().Setup(c => c.GetBestQualityInHistory(It.IsAny<QualityProfile>(), 1)).Returns(_upgradableQuality);
|
||||||
|
|
||||||
_upgradeHistory.IsSatisfiedBy(_parseResultSingle, null).Should().BeFalse();
|
_upgradeHistory.IsSatisfiedBy(_parseResultSingle, null).Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,9 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_series = Builder<Series>.CreateNew().Build();
|
_series = Builder<Series>.CreateNew()
|
||||||
|
.With(e => e.QualityProfile = new QualityProfile { Items = Qualities.QualityFixture.GetDefaultQualities() })
|
||||||
|
.Build();
|
||||||
|
|
||||||
_episode = Builder<Episode>.CreateNew()
|
_episode = Builder<Episode>.CreateNew()
|
||||||
.With(e => e.SeriesId = _series.Id)
|
.With(e => e.SeriesId = _series.Id)
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
public void should_allow_if_quality_is_defined_in_profile(Quality qualityType)
|
public void should_allow_if_quality_is_defined_in_profile(Quality qualityType)
|
||||||
{
|
{
|
||||||
remoteEpisode.ParsedEpisodeInfo.Quality.Quality = qualityType;
|
remoteEpisode.ParsedEpisodeInfo.Quality.Quality = qualityType;
|
||||||
remoteEpisode.Series.QualityProfile.Value.Allowed = new List<Quality> { Quality.DVD, Quality.HDTV720p, Quality.Bluray1080p };
|
remoteEpisode.Series.QualityProfile.Value.Items = Qualities.QualityFixture.GetDefaultQualities(Quality.DVD, Quality.HDTV720p, Quality.Bluray1080p);
|
||||||
|
|
||||||
Subject.IsSatisfiedBy(remoteEpisode, null).Should().BeTrue();
|
Subject.IsSatisfiedBy(remoteEpisode, null).Should().BeTrue();
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
public void should_not_allow_if_quality_is_not_defined_in_profile(Quality qualityType)
|
public void should_not_allow_if_quality_is_not_defined_in_profile(Quality qualityType)
|
||||||
{
|
{
|
||||||
remoteEpisode.ParsedEpisodeInfo.Quality.Quality = qualityType;
|
remoteEpisode.ParsedEpisodeInfo.Quality.Quality = qualityType;
|
||||||
remoteEpisode.Series.QualityProfile.Value.Allowed = new List<Quality> { Quality.DVD, Quality.HDTV720p, Quality.Bluray1080p };
|
remoteEpisode.Series.QualityProfile.Value.Items = Qualities.QualityFixture.GetDefaultQualities(Quality.DVD, Quality.HDTV720p, Quality.Bluray1080p);
|
||||||
|
|
||||||
Subject.IsSatisfiedBy(remoteEpisode, null).Should().BeFalse();
|
Subject.IsSatisfiedBy(remoteEpisode, null).Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using FluentAssertions;
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
|
@ -23,6 +24,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
new object[] { Quality.SDTV, false, Quality.SDTV, true, Quality.SDTV, true },
|
new object[] { Quality.SDTV, false, Quality.SDTV, true, Quality.SDTV, true },
|
||||||
new object[] { Quality.WEBDL1080p, false, Quality.WEBDL1080p, false, Quality.WEBDL1080p, false }
|
new object[] { Quality.WEBDL1080p, false, Quality.WEBDL1080p, false, Quality.WEBDL1080p, false }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void GivenAutoDownloadPropers(bool autoDownloadPropers)
|
private void GivenAutoDownloadPropers(bool autoDownloadPropers)
|
||||||
{
|
{
|
||||||
|
@ -36,7 +43,9 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
{
|
{
|
||||||
GivenAutoDownloadPropers(true);
|
GivenAutoDownloadPropers(true);
|
||||||
|
|
||||||
Subject.IsUpgradable(new QualityModel(current, currentProper), new QualityModel(newQuality, newProper))
|
var qualityProfile = new QualityProfile { Items = Qualities.QualityFixture.GetDefaultQualities() };
|
||||||
|
|
||||||
|
Subject.IsUpgradable(qualityProfile, new QualityModel(current, currentProper), new QualityModel(newQuality, newProper))
|
||||||
.Should().Be(expected);
|
.Should().Be(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,8 +54,10 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
{
|
{
|
||||||
GivenAutoDownloadPropers(false);
|
GivenAutoDownloadPropers(false);
|
||||||
|
|
||||||
Subject.IsUpgradable(new QualityModel(Quality.DVD, true),
|
var qualityProfile = new QualityProfile { Items = Qualities.QualityFixture.GetDefaultQualities() };
|
||||||
new QualityModel(Quality.DVD, false)).Should().BeFalse();
|
|
||||||
|
Subject.IsUpgradable(qualityProfile, new QualityModel(Quality.DVD, true), new QualityModel(Quality.DVD, false))
|
||||||
|
.Should().BeFalse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -38,7 +38,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
var doubleEpisodeList = new List<Episode> { new Episode { EpisodeFile = _firstFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = _secondFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = null } };
|
var doubleEpisodeList = new List<Episode> { new Episode { EpisodeFile = _firstFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = _secondFile, EpisodeFileId = 1 }, new Episode { EpisodeFile = null } };
|
||||||
|
|
||||||
var fakeSeries = Builder<Series>.CreateNew()
|
var fakeSeries = Builder<Series>.CreateNew()
|
||||||
.With(c => c.QualityProfile = new QualityProfile { Cutoff = Quality.Bluray1080p })
|
.With(c => c.QualityProfile = new QualityProfile { Cutoff = Quality.Bluray1080p, Items = Qualities.QualityFixture.GetDefaultQualities() })
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
_parseResultMulti = new RemoteEpisode
|
_parseResultMulti = new RemoteEpisode
|
||||||
|
|
|
@ -37,6 +37,10 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||||
remoteEpisode.Release = new ReleaseInfo();
|
remoteEpisode.Release = new ReleaseInfo();
|
||||||
remoteEpisode.Release.PublishDate = DateTime.UtcNow;
|
remoteEpisode.Release.PublishDate = DateTime.UtcNow;
|
||||||
|
|
||||||
|
remoteEpisode.Series = Builder<Series>.CreateNew()
|
||||||
|
.With(e => e.QualityProfile = new QualityProfile { Items = Qualities.QualityFixture.GetDefaultQualities() })
|
||||||
|
.Build();
|
||||||
|
|
||||||
return remoteEpisode;
|
return remoteEpisode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,10 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||||
remoteEpisode.Release.PublishDate = DateTime.Now.AddDays(-Age);
|
remoteEpisode.Release.PublishDate = DateTime.Now.AddDays(-Age);
|
||||||
remoteEpisode.Release.Size = size;
|
remoteEpisode.Release.Size = size;
|
||||||
|
|
||||||
|
remoteEpisode.Series = Builder<Series>.CreateNew()
|
||||||
|
.With(e => e.QualityProfile = new QualityProfile { Items = Qualities.QualityFixture.GetDefaultQualities() })
|
||||||
|
.Build();
|
||||||
|
|
||||||
return remoteEpisode;
|
return remoteEpisode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,6 @@ namespace NzbDrone.Core.Test.Download
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IDownloadClient>().Setup(c => c.IsConfigured).Returns(false);
|
Mocker.GetMock<IDownloadClient>().Setup(c => c.IsConfigured).Returns(false);
|
||||||
|
|
||||||
|
|
||||||
Subject.DownloadReport(_parseResult);
|
Subject.DownloadReport(_parseResult);
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadClient>().Verify(c => c.DownloadNzb(It.IsAny<RemoteEpisode>()), Times.Never());
|
Mocker.GetMock<IDownloadClient>().Verify(c => c.DownloadNzb(It.IsAny<RemoteEpisode>()), Times.Never());
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.History;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.Test.Qualities;
|
||||||
|
using FluentAssertions;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.HistoryTests
|
||||||
|
{
|
||||||
|
public class HistoryServiceFixture : CoreTest<HistoryService>
|
||||||
|
{
|
||||||
|
private QualityProfile _profile;
|
||||||
|
private QualityProfile _profileCustom;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_profile = new QualityProfile { Cutoff = Quality.WEBDL720p, Items = QualityFixture.GetDefaultQualities() };
|
||||||
|
_profileCustom = new QualityProfile { Cutoff = Quality.WEBDL720p, Items = QualityFixture.GetDefaultQualities(Quality.DVD) };
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_null_if_no_history()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IHistoryRepository>()
|
||||||
|
.Setup(v => v.GetBestQualityInHistory(2))
|
||||||
|
.Returns(new List<QualityModel>());
|
||||||
|
|
||||||
|
var quality = Subject.GetBestQualityInHistory(_profile, 2);
|
||||||
|
|
||||||
|
quality.Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_best_quality()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IHistoryRepository>()
|
||||||
|
.Setup(v => v.GetBestQualityInHistory(2))
|
||||||
|
.Returns(new List<QualityModel> { new QualityModel(Quality.DVD), new QualityModel(Quality.Bluray1080p) });
|
||||||
|
|
||||||
|
var quality = Subject.GetBestQualityInHistory(_profile, 2);
|
||||||
|
|
||||||
|
quality.Should().Be(new QualityModel(Quality.Bluray1080p));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_best_quality_with_custom_order()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IHistoryRepository>()
|
||||||
|
.Setup(v => v.GetBestQualityInHistory(2))
|
||||||
|
.Returns(new List<QualityModel> { new QualityModel(Quality.DVD), new QualityModel(Quality.Bluray1080p) });
|
||||||
|
|
||||||
|
var quality = Subject.GetBestQualityInHistory(_profileCustom, 2);
|
||||||
|
|
||||||
|
quality.Should().Be(new QualityModel(Quality.DVD));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -80,6 +80,20 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
Subject.Execute(new DownloadedEpisodesScanCommand());
|
Subject.Execute(new DownloadedEpisodesScanCommand());
|
||||||
|
|
||||||
|
VerifyNoImport();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_skip_if_no_series_found()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IParsingService>().Setup(c => c.GetSeries("foldername")).Returns((Series)null);
|
||||||
|
|
||||||
|
Subject.Execute(new DownloadedEpisodesScanCommand());
|
||||||
|
|
||||||
|
Mocker.GetMock<IMakeImportDecision>()
|
||||||
|
.Verify(c => c.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Series>(), It.IsAny<bool>(), It.IsAny<Core.Qualities.QualityModel>()),
|
||||||
|
Times.Never());
|
||||||
|
|
||||||
VerifyNoImport();
|
VerifyNoImport();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
{
|
{
|
||||||
|
@ -63,7 +64,10 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
_fail3.Setup(c => c.RejectionReason).Returns("_fail3");
|
_fail3.Setup(c => c.RejectionReason).Returns("_fail3");
|
||||||
|
|
||||||
_videoFiles = new List<string> { @"C:\Test\Unsorted\The.Office.S03E115.DVDRip.XviD-OSiTV.avi" };
|
_videoFiles = new List<string> { @"C:\Test\Unsorted\The.Office.S03E115.DVDRip.XviD-OSiTV.avi" };
|
||||||
_series = new Series();
|
_series = Builder<Series>.CreateNew()
|
||||||
|
.With(e => e.QualityProfile = new QualityProfile { Items = Qualities.QualityFixture.GetDefaultQualities() })
|
||||||
|
.Build();
|
||||||
|
|
||||||
_quality = new QualityModel(Quality.DVD);
|
_quality = new QualityModel(Quality.DVD);
|
||||||
_localEpisode = new LocalEpisode
|
_localEpisode = new LocalEpisode
|
||||||
{
|
{
|
||||||
|
@ -80,7 +84,6 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
Mocker.GetMock<IMediaFileService>()
|
Mocker.GetMock<IMediaFileService>()
|
||||||
.Setup(c => c.FilterExistingFiles(_videoFiles, It.IsAny<int>()))
|
.Setup(c => c.FilterExistingFiles(_videoFiles, It.IsAny<int>()))
|
||||||
.Returns(_videoFiles);
|
.Returns(_videoFiles);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenSpecifications(params Mock<IImportDecisionEngineSpecification>[] mocks)
|
private void GivenSpecifications(params Mock<IImportDecisionEngineSpecification>[] mocks)
|
||||||
|
@ -162,7 +165,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
.Setup(c => c.FilterExistingFiles(_videoFiles, It.IsAny<int>()))
|
.Setup(c => c.FilterExistingFiles(_videoFiles, It.IsAny<int>()))
|
||||||
.Returns(_videoFiles);
|
.Returns(_videoFiles);
|
||||||
|
|
||||||
Subject.GetImportDecisions(_videoFiles, new Series(), false);
|
Subject.GetImportDecisions(_videoFiles, _series, false);
|
||||||
|
|
||||||
Mocker.GetMock<IParsingService>()
|
Mocker.GetMock<IParsingService>()
|
||||||
.Verify(c => c.GetEpisodes(It.IsAny<String>(), It.IsAny<Series>(), It.IsAny<Boolean>()), Times.Exactly(_videoFiles.Count));
|
.Verify(c => c.GetEpisodes(It.IsAny<String>(), It.IsAny<Series>(), It.IsAny<Boolean>()), Times.Exactly(_videoFiles.Count));
|
||||||
|
@ -176,7 +179,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
GivenSpecifications(_pass1, _pass2, _pass3);
|
GivenSpecifications(_pass1, _pass2, _pass3);
|
||||||
var expectedQuality = QualityParser.ParseQuality(_videoFiles.Single());
|
var expectedQuality = QualityParser.ParseQuality(_videoFiles.Single());
|
||||||
|
|
||||||
var result = Subject.GetImportDecisions(_videoFiles, new Series(), false, null);
|
var result = Subject.GetImportDecisions(_videoFiles, _series, false, null);
|
||||||
|
|
||||||
result.Single().LocalEpisode.Quality.Should().Be(expectedQuality);
|
result.Single().LocalEpisode.Quality.Should().Be(expectedQuality);
|
||||||
}
|
}
|
||||||
|
@ -187,7 +190,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
GivenSpecifications(_pass1, _pass2, _pass3);
|
GivenSpecifications(_pass1, _pass2, _pass3);
|
||||||
var expectedQuality = QualityParser.ParseQuality(_videoFiles.Single());
|
var expectedQuality = QualityParser.ParseQuality(_videoFiles.Single());
|
||||||
|
|
||||||
var result = Subject.GetImportDecisions(_videoFiles, new Series(), false, new QualityModel(Quality.SDTV));
|
var result = Subject.GetImportDecisions(_videoFiles, _series, false, new QualityModel(Quality.SDTV));
|
||||||
|
|
||||||
result.Single().LocalEpisode.Quality.Should().Be(expectedQuality);
|
result.Single().LocalEpisode.Quality.Should().Be(expectedQuality);
|
||||||
}
|
}
|
||||||
|
@ -198,7 +201,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
GivenSpecifications(_pass1, _pass2, _pass3);
|
GivenSpecifications(_pass1, _pass2, _pass3);
|
||||||
var expectedQuality = new QualityModel(Quality.Bluray1080p);
|
var expectedQuality = new QualityModel(Quality.Bluray1080p);
|
||||||
|
|
||||||
var result = Subject.GetImportDecisions(_videoFiles, new Series(), false, expectedQuality);
|
var result = Subject.GetImportDecisions(_videoFiles, _series, false, expectedQuality);
|
||||||
|
|
||||||
result.Single().LocalEpisode.Quality.Should().Be(expectedQuality);
|
result.Single().LocalEpisode.Quality.Should().Be(expectedQuality);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,13 +22,15 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_series = Builder<Series>.CreateNew()
|
_series = Builder<Series>.CreateNew()
|
||||||
.With(s => s.SeriesType = SeriesTypes.Standard)
|
.With(s => s.SeriesType = SeriesTypes.Standard)
|
||||||
|
.With(e => e.QualityProfile = new QualityProfile { Items = Qualities.QualityFixture.GetDefaultQualities() })
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
_localEpisode = new LocalEpisode
|
_localEpisode = new LocalEpisode
|
||||||
{
|
{
|
||||||
Path = @"C:\Test\30 Rock\30.rock.s01e01.avi",
|
Path = @"C:\Test\30 Rock\30.rock.s01e01.avi",
|
||||||
Quality = new QualityModel(Quality.HDTV720p, false)
|
Quality = new QualityModel(Quality.HDTV720p, false),
|
||||||
|
Series = _series
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
_approvedDecisions = new List<ImportDecision>();
|
_approvedDecisions = new List<ImportDecision>();
|
||||||
|
|
||||||
var series = Builder<Series>.CreateNew()
|
var series = Builder<Series>.CreateNew()
|
||||||
|
.With(e => e.QualityProfile = new QualityProfile { Items = Qualities.QualityFixture.GetDefaultQualities() })
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var episodes = Builder<Episode>.CreateListOfSize(5)
|
var episodes = Builder<Episode>.CreateListOfSize(5)
|
||||||
|
|
|
@ -131,6 +131,7 @@
|
||||||
<Compile Include="Framework\CoreTest.cs" />
|
<Compile Include="Framework\CoreTest.cs" />
|
||||||
<Compile Include="Framework\DbTest.cs" />
|
<Compile Include="Framework\DbTest.cs" />
|
||||||
<Compile Include="Framework\NBuilderExtensions.cs" />
|
<Compile Include="Framework\NBuilderExtensions.cs" />
|
||||||
|
<Compile Include="HistoryTests\HistoryServiceFixture.cs" />
|
||||||
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedHistoryItemsFixture.cs" />
|
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedHistoryItemsFixture.cs" />
|
||||||
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodeFilesFixture.cs" />
|
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodeFilesFixture.cs" />
|
||||||
<Compile Include="Housekeeping\Housekeepers\CleanupAdditionalNamingSpecsFixture.cs" />
|
<Compile Include="Housekeeping\Housekeepers\CleanupAdditionalNamingSpecsFixture.cs" />
|
||||||
|
@ -183,7 +184,7 @@
|
||||||
<Compile Include="ParserTests\ParsingServiceTests\MapFixture.cs" />
|
<Compile Include="ParserTests\ParsingServiceTests\MapFixture.cs" />
|
||||||
<Compile Include="ParserTests\SeriesTitleInfoFixture.cs" />
|
<Compile Include="ParserTests\SeriesTitleInfoFixture.cs" />
|
||||||
<Compile Include="Providers\XemProxyFixture.cs" />
|
<Compile Include="Providers\XemProxyFixture.cs" />
|
||||||
<Compile Include="Qualities\QualitySizeRepositoryFixture.cs" />
|
<Compile Include="Qualities\QualityDefinitionRepositoryFixture.cs" />
|
||||||
<Compile Include="Qualities\QualityProfileRepositoryFixture.cs" />
|
<Compile Include="Qualities\QualityProfileRepositoryFixture.cs" />
|
||||||
<Compile Include="RootFolderTests\FreeSpaceOnDrivesFixture.cs" />
|
<Compile Include="RootFolderTests\FreeSpaceOnDrivesFixture.cs" />
|
||||||
<Compile Include="Qualities\QualityFixture.cs" />
|
<Compile Include="Qualities\QualityFixture.cs" />
|
||||||
|
@ -218,14 +219,14 @@
|
||||||
<Compile Include="TvTests\SeriesServiceTests\UpdateSeriesFixture.cs" />
|
<Compile Include="TvTests\SeriesServiceTests\UpdateSeriesFixture.cs" />
|
||||||
<Compile Include="UpdateTests\UpdateServiceFixture.cs" />
|
<Compile Include="UpdateTests\UpdateServiceFixture.cs" />
|
||||||
<Compile Include="DecisionEngineTests\AcceptableSizeSpecificationFixture.cs" />
|
<Compile Include="DecisionEngineTests\AcceptableSizeSpecificationFixture.cs" />
|
||||||
<Compile Include="Qualities\QualitySizeServiceFixture.cs" />
|
<Compile Include="Qualities\QualityDefinitionServiceFixture.cs" />
|
||||||
<Compile Include="TvTests\EpisodeProviderTests\EpisodeProviderTest_GetEpisodesByParseResult.cs" />
|
<Compile Include="TvTests\EpisodeProviderTests\EpisodeProviderTest_GetEpisodesByParseResult.cs" />
|
||||||
<Compile Include="FluentTest.cs" />
|
<Compile Include="FluentTest.cs" />
|
||||||
<Compile Include="InstrumentationTests\DatabaseTargetFixture.cs" />
|
<Compile Include="InstrumentationTests\DatabaseTargetFixture.cs" />
|
||||||
<Compile Include="OrganizerTests\GetNewFilenameFixture.cs" />
|
<Compile Include="OrganizerTests\GetNewFilenameFixture.cs" />
|
||||||
<Compile Include="DecisionEngineTests\MonitoredEpisodeSpecificationFixture.cs" />
|
<Compile Include="DecisionEngineTests\MonitoredEpisodeSpecificationFixture.cs" />
|
||||||
<Compile Include="DecisionEngineTests\DownloadDecisionMakerFixture.cs" />
|
<Compile Include="DecisionEngineTests\DownloadDecisionMakerFixture.cs" />
|
||||||
<Compile Include="TvTests\QualityModelFixture.cs" />
|
<Compile Include="Qualities\QualityModelComparerFixture.cs" />
|
||||||
<Compile Include="RootFolderTests\RootFolderServiceFixture.cs" />
|
<Compile Include="RootFolderTests\RootFolderServiceFixture.cs" />
|
||||||
<Compile Include="HistoryTests\HistoryRepositoryFixture.cs" />
|
<Compile Include="HistoryTests\HistoryRepositoryFixture.cs" />
|
||||||
<Compile Include="MediaFiles\MediaFileServiceTest.cs" />
|
<Compile Include="MediaFiles\MediaFileServiceTest.cs" />
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
@ -50,6 +51,10 @@ namespace NzbDrone.Core.Test.OrganizerTests
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
_episodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV720p), ReleaseGroup = "DRONE" };
|
_episodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV720p), ReleaseGroup = "DRONE" };
|
||||||
|
|
||||||
|
Mocker.GetMock<IQualityDefinitionService>()
|
||||||
|
.Setup(v => v.Get(Moq.It.IsAny<Quality>()))
|
||||||
|
.Returns<Quality>(v => Quality.DefaultQualityDefinitions.First(c => c.Quality == v));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenProper()
|
private void GivenProper()
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
|
@ -150,9 +151,9 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, TestCaseSource("SelfQualityParserCases")]
|
[Test, TestCaseSource("SelfQualityParserCases")]
|
||||||
public void parsing_our_own_quality_enum(Quality quality)
|
public void parsing_our_own_quality_enum_name(Quality quality)
|
||||||
{
|
{
|
||||||
var fileName = String.Format("My series S01E01 [{0}]", quality);
|
var fileName = String.Format("My series S01E01 [{0}]", quality.Name);
|
||||||
var result = Parser.QualityParser.ParseQuality(fileName);
|
var result = Parser.QualityParser.ParseQuality(fileName);
|
||||||
result.Quality.Should().Be(quality);
|
result.Quality.Should().Be(quality);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,25 +4,27 @@ using NzbDrone.Core.Lifecycle;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.Qualities
|
namespace NzbDrone.Core.Test.Qualities
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
public class QualityDefinitionRepositoryFixture : DbTest<QualityDefinitionRepository, QualityDefinition>
|
||||||
public class QualitySizeRepositoryFixture : DbTest<QualitySizeRepository, QualitySize>
|
|
||||||
{
|
{
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
Mocker.SetConstant<IQualitySizeRepository>(Subject);
|
foreach (var qualityDefault in Quality.DefaultQualityDefinitions)
|
||||||
Mocker.Resolve<QualitySizeService>().Handle(new ApplicationStartedEvent());
|
{
|
||||||
|
qualityDefault.Id = 0;
|
||||||
|
Storage.Insert(qualityDefault);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_get_quality_size_by_id()
|
public void should_get_qualitydefinition_by_id()
|
||||||
{
|
{
|
||||||
var size = Subject.GetByQualityId(Quality.Bluray1080p.Id);
|
var size = Subject.GetByQualityId((int)Quality.Bluray1080p);
|
||||||
|
|
||||||
size.Should().NotBeNull();
|
size.Should().NotBeNull();
|
||||||
}
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Lifecycle;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Qualities
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class QualityDefinitionServiceFixture : CoreTest<QualityDefinitionService>
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void init_should_add_all_definitions()
|
||||||
|
{
|
||||||
|
Subject.Handle(new ApplicationStartedEvent());
|
||||||
|
|
||||||
|
Mocker.GetMock<IQualityDefinitionRepository>()
|
||||||
|
.Verify(v => v.Insert(It.IsAny<QualityDefinition>()), Times.Exactly(Quality.All.Count));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void init_should_insert_any_missing_definitions()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IQualityDefinitionRepository>()
|
||||||
|
.Setup(s => s.All())
|
||||||
|
.Returns(new List<QualityDefinition>
|
||||||
|
{
|
||||||
|
new QualityDefinition(Quality.SDTV) { Weight = 1, MinSize = 0, MaxSize = 100, Id = 20 }
|
||||||
|
});
|
||||||
|
|
||||||
|
Subject.Handle(new ApplicationStartedEvent());
|
||||||
|
|
||||||
|
Mocker.GetMock<IQualityDefinitionRepository>()
|
||||||
|
.Verify(v => v.Insert(It.IsAny<QualityDefinition>()), Times.Exactly(Quality.All.Count - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void init_should_insert_missing_definitions_preserving_weight()
|
||||||
|
{
|
||||||
|
// User moved HDTV1080p to a higher weight.
|
||||||
|
var currentQualities = new List<QualityDefinition>
|
||||||
|
{
|
||||||
|
new QualityDefinition(Quality.SDTV) { Id = 5, Title = "SDTV", Weight = 1, MinSize=0, MaxSize=100 },
|
||||||
|
new QualityDefinition(Quality.WEBDL720p) { Id = 2, Title = "720p WEB-DL", Weight = 2, MinSize=0, MaxSize=100 },
|
||||||
|
new QualityDefinition(Quality.HDTV1080p) { Id = 4, Title = "1080p HDTV", Weight = 3, MinSize=0, MaxSize=100 },
|
||||||
|
new QualityDefinition(Quality.WEBDL1080p) { Id = 8, Title = "1080p WEB-DL", Weight = 4, MinSize=0, MaxSize=100 },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Expected to insert Bluray720p above HDTV1080p.
|
||||||
|
// Expected to insert Bluray1080p above WEBDL1080p.
|
||||||
|
var addBluray1080p = new List<QualityDefinition>
|
||||||
|
{
|
||||||
|
new QualityDefinition(Quality.SDTV) { Title = "SDTV", Weight = 1, MinSize=0, MaxSize=100 },
|
||||||
|
new QualityDefinition(Quality.HDTV1080p) { Title = "1080p HDTV", Weight = 2, MinSize=0, MaxSize=100 },
|
||||||
|
new QualityDefinition(Quality.WEBDL720p) { Title = "720p WEB-DL", Weight = 3, MinSize=0, MaxSize=100 },
|
||||||
|
new QualityDefinition(Quality.Bluray720p) { Title = "720p BluRay", Weight = 4, MinSize=0, MaxSize=100 },
|
||||||
|
new QualityDefinition(Quality.WEBDL1080p) { Title = "1080p WEB-DL", Weight = 5, MinSize=0, MaxSize=100 },
|
||||||
|
new QualityDefinition(Quality.Bluray1080p) { Title = "1080p BluRay", Weight = 6, MinSize=0, MaxSize=100 }
|
||||||
|
};
|
||||||
|
|
||||||
|
Mocker.GetMock<IQualityDefinitionRepository>()
|
||||||
|
.Setup(v => v.All())
|
||||||
|
.Returns(currentQualities);
|
||||||
|
|
||||||
|
Subject.InsertMissingDefinitions(addBluray1080p);
|
||||||
|
|
||||||
|
Mocker.GetMock<IQualityDefinitionRepository>()
|
||||||
|
.Verify(v => v.Insert(It.Is<QualityDefinition>(p => p.Quality == Quality.Bluray720p && p.Weight == 4)), Times.Once());
|
||||||
|
|
||||||
|
Mocker.GetMock<IQualityDefinitionRepository>()
|
||||||
|
.Verify(v => v.Update(It.Is<QualityDefinition>(p => p.Quality == Quality.WEBDL1080p && p.Weight == 5)), Times.Once());
|
||||||
|
|
||||||
|
Mocker.GetMock<IQualityDefinitionRepository>()
|
||||||
|
.Verify(v => v.Insert(It.Is<QualityDefinition>(p => p.Quality == Quality.Bluray1080p && p.Weight == 6)), Times.Once());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
using FluentAssertions;
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
@ -42,81 +44,31 @@ namespace NzbDrone.Core.Test.Qualities
|
||||||
i.Should().Be(expected);
|
i.Should().Be(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<QualityProfileItem> GetDefaultQualities(params Quality[] allowed)
|
||||||
[Test]
|
|
||||||
public void Icomparer_greater_test()
|
|
||||||
{
|
{
|
||||||
var first = Quality.DVD;
|
var qualities = new List<Quality>
|
||||||
var second = Quality.Bluray1080p;
|
{
|
||||||
|
Quality.SDTV,
|
||||||
|
Quality.WEBDL480p,
|
||||||
|
Quality.DVD,
|
||||||
|
Quality.HDTV720p,
|
||||||
|
Quality.HDTV1080p,
|
||||||
|
Quality.RAWHD,
|
||||||
|
Quality.WEBDL720p,
|
||||||
|
Quality.Bluray720p,
|
||||||
|
Quality.WEBDL1080p,
|
||||||
|
Quality.Bluray1080p
|
||||||
|
};
|
||||||
|
|
||||||
second.Should().BeGreaterThan(first);
|
if (allowed.Length == 0)
|
||||||
}
|
allowed = qualities.ToArray();
|
||||||
|
|
||||||
[Test]
|
var items = qualities
|
||||||
public void Icomparer_lesser()
|
.Except(allowed)
|
||||||
{
|
.Concat(allowed)
|
||||||
var first = Quality.DVD;
|
.Select(v => new QualityProfileItem { Quality = v, Allowed = allowed.Contains(v) }).ToList();
|
||||||
var second = Quality.Bluray1080p;
|
|
||||||
|
|
||||||
first.Should().BeLessThan(second);
|
return items;
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void equal_operand()
|
|
||||||
{
|
|
||||||
var first = Quality.Bluray1080p;
|
|
||||||
var second = Quality.Bluray1080p;
|
|
||||||
|
|
||||||
(first == second).Should().BeTrue();
|
|
||||||
(first >= second).Should().BeTrue();
|
|
||||||
(first <= second).Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void equal_operand_false()
|
|
||||||
{
|
|
||||||
var first = Quality.Bluray1080p;
|
|
||||||
var second = Quality.Unknown;
|
|
||||||
|
|
||||||
(first == second).Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void not_equal_operand()
|
|
||||||
{
|
|
||||||
var first = Quality.Bluray1080p;
|
|
||||||
var second = Quality.Bluray1080p;
|
|
||||||
|
|
||||||
(first != second).Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void not_equal_operand_false()
|
|
||||||
{
|
|
||||||
var first = Quality.Bluray1080p;
|
|
||||||
var second = Quality.Unknown;
|
|
||||||
|
|
||||||
(first != second).Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void greater_operand()
|
|
||||||
{
|
|
||||||
var first = Quality.DVD;
|
|
||||||
var second = Quality.Bluray1080p;
|
|
||||||
|
|
||||||
(first < second).Should().BeTrue();
|
|
||||||
(first <= second).Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void lesser_operand()
|
|
||||||
{
|
|
||||||
var first = Quality.DVD;
|
|
||||||
var second = Quality.Bluray1080p;
|
|
||||||
|
|
||||||
(second > first).Should().BeTrue();
|
|
||||||
(second >= first).Should().BeTrue();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Qualities
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class QualityModelComparerFixture : CoreTest
|
||||||
|
{
|
||||||
|
public QualityModelComparer Subject { get; set; }
|
||||||
|
|
||||||
|
private void GivenDefaultQualityProfile()
|
||||||
|
{
|
||||||
|
Subject = new QualityModelComparer(new QualityProfile { Items = QualityFixture.GetDefaultQualities() });
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenCustomQualityProfile()
|
||||||
|
{
|
||||||
|
Subject = new QualityModelComparer(new QualityProfile { Items = QualityFixture.GetDefaultQualities(Quality.Bluray720p, Quality.DVD) });
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Icomparer_greater_test()
|
||||||
|
{
|
||||||
|
GivenDefaultQualityProfile();
|
||||||
|
|
||||||
|
var first = new QualityModel(Quality.DVD, true);
|
||||||
|
var second = new QualityModel(Quality.Bluray1080p, true);
|
||||||
|
|
||||||
|
var compare = Subject.Compare(second, first);
|
||||||
|
|
||||||
|
compare.Should().BeGreaterThan(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Icomparer_greater_proper()
|
||||||
|
{
|
||||||
|
GivenDefaultQualityProfile();
|
||||||
|
|
||||||
|
var first = new QualityModel(Quality.Bluray1080p, false);
|
||||||
|
var second = new QualityModel(Quality.Bluray1080p, true);
|
||||||
|
|
||||||
|
var compare = Subject.Compare(second, first);
|
||||||
|
|
||||||
|
compare.Should().BeGreaterThan(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Icomparer_lesser()
|
||||||
|
{
|
||||||
|
GivenDefaultQualityProfile();
|
||||||
|
|
||||||
|
var first = new QualityModel(Quality.DVD, true);
|
||||||
|
var second = new QualityModel(Quality.Bluray1080p, true);
|
||||||
|
|
||||||
|
var compare = Subject.Compare(first, second);
|
||||||
|
|
||||||
|
compare.Should().BeLessThan(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Icomparer_lesser_proper()
|
||||||
|
{
|
||||||
|
GivenDefaultQualityProfile();
|
||||||
|
|
||||||
|
var first = new QualityModel(Quality.DVD, false);
|
||||||
|
var second = new QualityModel(Quality.DVD, true);
|
||||||
|
|
||||||
|
var compare = Subject.Compare(first, second);
|
||||||
|
|
||||||
|
compare.Should().BeLessThan(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Icomparer_greater_custom_order()
|
||||||
|
{
|
||||||
|
GivenCustomQualityProfile();
|
||||||
|
|
||||||
|
var first = new QualityModel(Quality.DVD, true);
|
||||||
|
var second = new QualityModel(Quality.Bluray720p, true);
|
||||||
|
|
||||||
|
var compare = Subject.Compare(first, second);
|
||||||
|
|
||||||
|
compare.Should().BeGreaterThan(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,6 @@ using NzbDrone.Core.Test.Framework;
|
||||||
namespace NzbDrone.Core.Test.Qualities
|
namespace NzbDrone.Core.Test.Qualities
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
|
||||||
public class QualityProfileRepositoryFixture : DbTest<QualityProfileRepository, QualityProfile>
|
public class QualityProfileRepositoryFixture : DbTest<QualityProfileRepository, QualityProfile>
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -15,13 +14,7 @@ namespace NzbDrone.Core.Test.Qualities
|
||||||
{
|
{
|
||||||
var profile = new QualityProfile
|
var profile = new QualityProfile
|
||||||
{
|
{
|
||||||
Allowed = new List<Quality>
|
Items = Qualities.QualityFixture.GetDefaultQualities(Quality.Bluray1080p, Quality.DVD, Quality.HDTV720p),
|
||||||
{
|
|
||||||
Quality.Bluray1080p,
|
|
||||||
Quality.DVD,
|
|
||||||
Quality.HDTV720p
|
|
||||||
},
|
|
||||||
|
|
||||||
Cutoff = Quality.Bluray1080p,
|
Cutoff = Quality.Bluray1080p,
|
||||||
Name = "TestProfile"
|
Name = "TestProfile"
|
||||||
};
|
};
|
||||||
|
@ -30,8 +23,8 @@ namespace NzbDrone.Core.Test.Qualities
|
||||||
|
|
||||||
StoredModel.Name.Should().Be(profile.Name);
|
StoredModel.Name.Should().Be(profile.Name);
|
||||||
StoredModel.Cutoff.Should().Be(profile.Cutoff);
|
StoredModel.Cutoff.Should().Be(profile.Cutoff);
|
||||||
|
|
||||||
StoredModel.Allowed.Should().BeEquivalentTo(profile.Allowed);
|
StoredModel.Items.Should().Equal(profile.Items, (a,b) => a.Quality == b.Quality && a.Allowed == b.Allowed);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Core.Lifecycle;
|
|
||||||
using NzbDrone.Core.Qualities;
|
|
||||||
using NzbDrone.Core.Test.Framework;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.Qualities
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
|
|
||||||
public class QualitySizeServiceFixture : CoreTest<QualitySizeService>
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void Init_should_add_all_sizes()
|
|
||||||
{
|
|
||||||
Subject.Handle(new ApplicationStartedEvent());
|
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeRepository>()
|
|
||||||
.Verify(v => v.Insert(It.IsAny<QualitySize>()), Times.Exactly(Quality.All().Count));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Init_should_insert_any_missing_sizes()
|
|
||||||
{
|
|
||||||
Mocker.GetMock<IQualitySizeRepository>()
|
|
||||||
.Setup(s => s.All())
|
|
||||||
.Returns(new List<QualitySize>
|
|
||||||
{
|
|
||||||
new QualitySize { QualityId = 1, Name = "SDTV", MinSize = 0, MaxSize = 100 }
|
|
||||||
});
|
|
||||||
|
|
||||||
Subject.Handle(new ApplicationStartedEvent());
|
|
||||||
|
|
||||||
Mocker.GetMock<IQualitySizeRepository>()
|
|
||||||
.Verify(v => v.Insert(It.IsAny<QualitySize>()), Times.Exactly(Quality.All().Count - 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,125 +0,0 @@
|
||||||
using FluentAssertions;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Core.Qualities;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
using NzbDrone.Core.Test.Framework;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.TvTests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
|
|
||||||
public class QualityModelFixture : CoreTest
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void Icomparer_greater_test()
|
|
||||||
{
|
|
||||||
var first = new QualityModel(Quality.DVD, true);
|
|
||||||
var second = new QualityModel(Quality.Bluray1080p, true);
|
|
||||||
|
|
||||||
second.Should().BeGreaterThan(first);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Icomparer_greater_proper()
|
|
||||||
{
|
|
||||||
var first = new QualityModel(Quality.Bluray1080p, false);
|
|
||||||
var second = new QualityModel(Quality.Bluray1080p, true);
|
|
||||||
|
|
||||||
second.Should().BeGreaterThan(first);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Icomparer_lesser()
|
|
||||||
{
|
|
||||||
var first = new QualityModel(Quality.DVD, true);
|
|
||||||
var second = new QualityModel(Quality.Bluray1080p, true);
|
|
||||||
|
|
||||||
first.Should().BeLessThan(second);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Icomparer_lesser_proper()
|
|
||||||
{
|
|
||||||
var first = new QualityModel(Quality.DVD, false);
|
|
||||||
var second = new QualityModel(Quality.DVD, true);
|
|
||||||
|
|
||||||
first.Should().BeLessThan(second);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void equal_operand()
|
|
||||||
{
|
|
||||||
var first = new QualityModel(Quality.Bluray1080p, true);
|
|
||||||
var second = new QualityModel(Quality.Bluray1080p, true);
|
|
||||||
|
|
||||||
(first == second).Should().BeTrue();
|
|
||||||
(first >= second).Should().BeTrue();
|
|
||||||
(first <= second).Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void equal_operand_false()
|
|
||||||
{
|
|
||||||
var first = new QualityModel(Quality.Bluray1080p, true);
|
|
||||||
var second = new QualityModel(Quality.Unknown, true);
|
|
||||||
|
|
||||||
(first == second).Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void equal_operand_false_proper()
|
|
||||||
{
|
|
||||||
var first = new QualityModel(Quality.Bluray1080p, true);
|
|
||||||
var second = new QualityModel(Quality.Bluray1080p, false);
|
|
||||||
|
|
||||||
(first == second).Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void not_equal_operand()
|
|
||||||
{
|
|
||||||
var first = new QualityModel(Quality.Bluray1080p, true);
|
|
||||||
var second = new QualityModel(Quality.Bluray1080p, true);
|
|
||||||
|
|
||||||
(first != second).Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void not_equal_operand_false()
|
|
||||||
{
|
|
||||||
var first = new QualityModel(Quality.Bluray1080p, true);
|
|
||||||
var second = new QualityModel(Quality.Unknown, true);
|
|
||||||
|
|
||||||
(first != second).Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void not_equal_operand_false_proper()
|
|
||||||
{
|
|
||||||
var first = new QualityModel(Quality.Bluray1080p, true);
|
|
||||||
var second = new QualityModel(Quality.Bluray1080p, false);
|
|
||||||
|
|
||||||
(first != second).Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void greater_operand()
|
|
||||||
{
|
|
||||||
var first = new QualityModel(Quality.DVD, true);
|
|
||||||
var second = new QualityModel(Quality.Bluray1080p, true);
|
|
||||||
|
|
||||||
(first < second).Should().BeTrue();
|
|
||||||
(first <= second).Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void lesser_operand()
|
|
||||||
{
|
|
||||||
var first = new QualityModel(Quality.DVD, true);
|
|
||||||
var second = new QualityModel(Quality.Bluray1080p, true);
|
|
||||||
|
|
||||||
(second > first).Should().BeTrue();
|
|
||||||
(second >= first).Should().BeTrue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,12 +17,7 @@ namespace NzbDrone.Core.Test.TvTests.SeriesRepositoryTests
|
||||||
{
|
{
|
||||||
var profile = new QualityProfile
|
var profile = new QualityProfile
|
||||||
{
|
{
|
||||||
Allowed = new List<Quality>
|
Items = Qualities.QualityFixture.GetDefaultQualities(Quality.Bluray1080p, Quality.DVD, Quality.HDTV720p),
|
||||||
{
|
|
||||||
Quality.Bluray1080p,
|
|
||||||
Quality.DVD,
|
|
||||||
Quality.HDTV720p
|
|
||||||
},
|
|
||||||
|
|
||||||
Cutoff = Quality.Bluray1080p,
|
Cutoff = Quality.Bluray1080p,
|
||||||
Name = "TestProfile"
|
Name = "TestProfile"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Blacklisting
|
namespace NzbDrone.Core.Blacklisting
|
||||||
|
|
|
@ -1,12 +1,36 @@
|
||||||
using System;
|
using System;
|
||||||
using Marr.Data.Converters;
|
using Marr.Data.Converters;
|
||||||
using Marr.Data.Mapping;
|
using Marr.Data.Mapping;
|
||||||
using NzbDrone.Common.Serializer;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Serialization;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Datastore.Converters
|
namespace NzbDrone.Core.Datastore.Converters
|
||||||
{
|
{
|
||||||
public class EmbeddedDocumentConverter : IConverter
|
public class EmbeddedDocumentConverter : IConverter
|
||||||
{
|
{
|
||||||
|
private readonly JsonSerializerSettings SerializerSetting;
|
||||||
|
|
||||||
|
public EmbeddedDocumentConverter(params JsonConverter[] converters)
|
||||||
|
{
|
||||||
|
SerializerSetting = new JsonSerializerSettings
|
||||||
|
{
|
||||||
|
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
|
||||||
|
NullValueHandling = NullValueHandling.Ignore,
|
||||||
|
Formatting = Formatting.Indented,
|
||||||
|
DefaultValueHandling = DefaultValueHandling.Include,
|
||||||
|
ContractResolver = new CamelCasePropertyNamesContractResolver()
|
||||||
|
};
|
||||||
|
|
||||||
|
SerializerSetting.Converters.Add(new StringEnumConverter { CamelCaseText = true });
|
||||||
|
SerializerSetting.Converters.Add(new VersionConverter());
|
||||||
|
|
||||||
|
foreach (var converter in converters)
|
||||||
|
{
|
||||||
|
SerializerSetting.Converters.Add(converter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public virtual object FromDB(ConverterContext context)
|
public virtual object FromDB(ConverterContext context)
|
||||||
{
|
{
|
||||||
if (context.DbValue == DBNull.Value)
|
if (context.DbValue == DBNull.Value)
|
||||||
|
@ -20,8 +44,7 @@ namespace NzbDrone.Core.Datastore.Converters
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
return JsonConvert.DeserializeObject(stringValue, context.ColumnMap.FieldType, SerializerSetting);
|
||||||
return Json.Deserialize(stringValue, context.ColumnMap.FieldType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public object FromDB(ColumnMap map, object dbValue)
|
public object FromDB(ColumnMap map, object dbValue)
|
||||||
|
@ -33,7 +56,7 @@ namespace NzbDrone.Core.Datastore.Converters
|
||||||
{
|
{
|
||||||
if (clrValue == null) return null;
|
if (clrValue == null) return null;
|
||||||
|
|
||||||
return clrValue.ToJson();
|
return JsonConvert.SerializeObject(clrValue, SerializerSetting);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type DbType
|
public Type DbType
|
||||||
|
|
|
@ -2,10 +2,13 @@
|
||||||
using Marr.Data.Converters;
|
using Marr.Data.Converters;
|
||||||
using Marr.Data.Mapping;
|
using Marr.Data.Mapping;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Common.Serializer;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Datastore.Converters
|
namespace NzbDrone.Core.Datastore.Converters
|
||||||
{
|
{
|
||||||
public class QualityIntConverter : IConverter
|
public class QualityIntConverter : JsonConverter, IConverter
|
||||||
{
|
{
|
||||||
public object FromDB(ConverterContext context)
|
public object FromDB(ConverterContext context)
|
||||||
{
|
{
|
||||||
|
@ -26,7 +29,7 @@ namespace NzbDrone.Core.Datastore.Converters
|
||||||
|
|
||||||
public object ToDB(object clrValue)
|
public object ToDB(object clrValue)
|
||||||
{
|
{
|
||||||
if(clrValue == null) return 0;
|
if(clrValue == DBNull.Value) return 0;
|
||||||
|
|
||||||
if(clrValue as Quality == null)
|
if(clrValue as Quality == null)
|
||||||
{
|
{
|
||||||
|
@ -44,5 +47,21 @@ namespace NzbDrone.Core.Datastore.Converters
|
||||||
return typeof(int);
|
return typeof(int);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool CanConvert(Type objectType)
|
||||||
|
{
|
||||||
|
return objectType == typeof(Quality);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
var item = reader.Value;
|
||||||
|
return (Quality)Convert.ToInt32(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
writer.WriteValue(ToDB(value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using NzbDrone.Common.Serializer;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.Datastore.Converters;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(36)]
|
||||||
|
public class update_with_quality_converters : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
if (!Schema.Table("QualityProfiles").Column("Items").Exists())
|
||||||
|
{
|
||||||
|
Alter.Table("QualityProfiles").AddColumn("Items").AsString().Nullable();
|
||||||
|
}
|
||||||
|
|
||||||
|
Execute.WithConnection(ConvertQualityProfiles);
|
||||||
|
Execute.WithConnection(ConvertQualityModels);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConvertQualityProfiles(IDbConnection conn, IDbTransaction tran)
|
||||||
|
{
|
||||||
|
var qualityProfileItemConverter = new EmbeddedDocumentConverter(new QualityIntConverter());
|
||||||
|
|
||||||
|
// Convert 'Allowed' column in QualityProfiles from Json List<object> to Json List<int> (int = Quality)
|
||||||
|
using (IDbCommand qualityProfileCmd = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
qualityProfileCmd.Transaction = tran;
|
||||||
|
qualityProfileCmd.CommandText = @"SELECT Id, Allowed FROM QualityProfiles";
|
||||||
|
using (IDataReader qualityProfileReader = qualityProfileCmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (qualityProfileReader.Read())
|
||||||
|
{
|
||||||
|
var id = qualityProfileReader.GetInt32(0);
|
||||||
|
var allowedJson = qualityProfileReader.GetString(1);
|
||||||
|
|
||||||
|
var allowed = Json.Deserialize<List<Quality>>(allowedJson);
|
||||||
|
|
||||||
|
var items = Quality.DefaultQualityDefinitions.OrderBy(v => v.Weight).Select(v => new QualityProfileItem { Quality = v.Quality, Allowed = allowed.Contains(v.Quality) }).ToList();
|
||||||
|
|
||||||
|
var allowedNewJson = qualityProfileItemConverter.ToDB(items);
|
||||||
|
|
||||||
|
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
updateCmd.Transaction = tran;
|
||||||
|
updateCmd.CommandText = "UPDATE QualityProfiles SET Items = ? WHERE Id = ?";
|
||||||
|
updateCmd.AddParameter(allowedNewJson);
|
||||||
|
updateCmd.AddParameter(id);
|
||||||
|
|
||||||
|
updateCmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConvertQualityModels(IDbConnection conn, IDbTransaction tran)
|
||||||
|
{
|
||||||
|
// Converts the QualityModel JSON objects to their new format (only storing the QualityId instead of the entire object)
|
||||||
|
ConvertQualityModel(conn, tran, "Blacklist");
|
||||||
|
ConvertQualityModel(conn, tran, "EpisodeFiles");
|
||||||
|
ConvertQualityModel(conn, tran, "History");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConvertQualityModel(IDbConnection conn, IDbTransaction tran, string tableName)
|
||||||
|
{
|
||||||
|
var qualityModelConverter = new EmbeddedDocumentConverter(new QualityIntConverter());
|
||||||
|
|
||||||
|
using (IDbCommand qualityModelCmd = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
qualityModelCmd.Transaction = tran;
|
||||||
|
qualityModelCmd.CommandText = @"SELECT Distinct Quality FROM " + tableName;
|
||||||
|
using (IDataReader qualityModelReader = qualityModelCmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (qualityModelReader.Read())
|
||||||
|
{
|
||||||
|
var qualityJson = qualityModelReader.GetString(0);
|
||||||
|
|
||||||
|
QualityModel quality;
|
||||||
|
|
||||||
|
if (!Json.TryDeserialize<QualityModel>(qualityJson, out quality))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var qualityNewJson = qualityModelConverter.ToDB(quality);
|
||||||
|
|
||||||
|
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
updateCmd.Transaction = tran;
|
||||||
|
updateCmd.CommandText = "UPDATE " + tableName + " SET Quality = ? WHERE Quality = ?";
|
||||||
|
updateCmd.AddParameter(qualityNewJson);
|
||||||
|
updateCmd.AddParameter(qualityJson);
|
||||||
|
|
||||||
|
updateCmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(37)]
|
||||||
|
public class add_configurable_qualities : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
SqLiteAlter.DropColumns("QualityProfiles", new[] { "Allowed" });
|
||||||
|
Alter.Column("Items").OnTable("QualityProfiles").AsString().NotNullable();
|
||||||
|
|
||||||
|
Create.TableForModel("QualityDefinitions")
|
||||||
|
.WithColumn("Quality").AsInt32().Unique()
|
||||||
|
.WithColumn("Title").AsString().Unique()
|
||||||
|
.WithColumn("Weight").AsInt32().Unique()
|
||||||
|
.WithColumn("MinSize").AsInt32()
|
||||||
|
.WithColumn("MaxSize").AsInt32();
|
||||||
|
|
||||||
|
Execute.WithConnection(ConvertQualities);
|
||||||
|
|
||||||
|
Delete.Table("QualitySizes");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConvertQualities(IDbConnection conn, IDbTransaction tran)
|
||||||
|
{
|
||||||
|
// Convert QualitySizes to a more generic QualityDefinitions table.
|
||||||
|
using (IDbCommand qualitySizeCmd = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
qualitySizeCmd.Transaction = tran;
|
||||||
|
qualitySizeCmd.CommandText = @"SELECT QualityId, MinSize, MaxSize FROM QualitySizes";
|
||||||
|
using (IDataReader qualitySizeReader = qualitySizeCmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (qualitySizeReader.Read())
|
||||||
|
{
|
||||||
|
var qualityId = qualitySizeReader.GetInt32(0);
|
||||||
|
var minSize = qualitySizeReader.GetInt32(1);
|
||||||
|
var maxSize = qualitySizeReader.GetInt32(2);
|
||||||
|
|
||||||
|
var defaultConfig = Quality.DefaultQualityDefinitions.Single(p => (int)p.Quality == qualityId);
|
||||||
|
|
||||||
|
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
updateCmd.Transaction = tran;
|
||||||
|
updateCmd.CommandText = "INSERT INTO QualityDefinitions (Quality, Title, Weight, MinSize, MaxSize) VALUES (?, ?, ?, ?, ?)";
|
||||||
|
updateCmd.AddParameter(qualityId);
|
||||||
|
updateCmd.AddParameter(defaultConfig.Title);
|
||||||
|
updateCmd.AddParameter(defaultConfig.Weight);
|
||||||
|
updateCmd.AddParameter(minSize);
|
||||||
|
updateCmd.AddParameter(maxSize);
|
||||||
|
|
||||||
|
updateCmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(38)]
|
||||||
|
public class add_on_upgrade_to_notifications : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Alter.Table("Notifications").AddColumn("OnUpgrade").AsBoolean().Nullable();
|
||||||
|
|
||||||
|
Execute.Sql("UPDATE Notifications SET OnUpgrade = OnDownload");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,5 +10,11 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
|
||||||
return expressionRoot.Table(name).WithColumn("Id").AsInt32().PrimaryKey().Identity();
|
return expressionRoot.Table(name).WithColumn("Id").AsInt32().PrimaryKey().Identity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void AddParameter(this System.Data.IDbCommand command, object value)
|
||||||
|
{
|
||||||
|
var parameter = command.CreateParameter();
|
||||||
|
parameter.Value = value;
|
||||||
|
command.Parameters.Add(parameter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -29,7 +29,7 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
|
||||||
private static readonly Regex SchemaRegex = new Regex(@"['\""\[](?<name>\w+)['\""\]]\s(?<schema>[\w-\s]+)",
|
private static readonly Regex SchemaRegex = new Regex(@"['\""\[](?<name>\w+)['\""\]]\s(?<schema>[\w-\s]+)",
|
||||||
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
|
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
|
||||||
|
|
||||||
private static readonly Regex IndexRegex = new Regex(@"\(""(?<col>.*)""\s(?<direction>ASC|DESC)\)$",
|
private static readonly Regex IndexRegex = new Regex(@"\((?:""|')(?<col>.*)(?:""|')\s(?<direction>ASC|DESC)\)$",
|
||||||
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
|
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
|
||||||
|
|
||||||
public SqLiteMigrationHelper(IConnectionStringFactory connectionStringFactory, Logger logger)
|
public SqLiteMigrationHelper(IConnectionStringFactory connectionStringFactory, Logger logger)
|
||||||
|
@ -96,8 +96,6 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
|
||||||
|
|
||||||
var reader = command.ExecuteReader();
|
var reader = command.ExecuteReader();
|
||||||
var sqls = ReadArray<string>(reader).ToList();
|
var sqls = ReadArray<string>(reader).ToList();
|
||||||
|
|
||||||
|
|
||||||
var indexes = new List<SQLiteIndex>();
|
var indexes = new List<SQLiteIndex>();
|
||||||
|
|
||||||
foreach (var indexSql in sqls)
|
foreach (var indexSql in sqls)
|
||||||
|
@ -105,6 +103,8 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
|
||||||
var newIndex = new SQLiteIndex();
|
var newIndex = new SQLiteIndex();
|
||||||
var matches = IndexRegex.Match(indexSql);
|
var matches = IndexRegex.Match(indexSql);
|
||||||
|
|
||||||
|
if (!matches.Success) continue;;
|
||||||
|
|
||||||
newIndex.Column = matches.Groups["col"].Value;
|
newIndex.Column = matches.Groups["col"].Value;
|
||||||
newIndex.Unique = indexSql.Contains("UNIQUE");
|
newIndex.Unique = indexSql.Contains("UNIQUE");
|
||||||
newIndex.Table = tableName;
|
newIndex.Table = tableName;
|
||||||
|
|
|
@ -45,7 +45,6 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
|
||||||
|
|
||||||
var newIndexes = originalIndexes.Union(indexes);
|
var newIndexes = originalIndexes.Union(indexes);
|
||||||
|
|
||||||
|
|
||||||
CreateTable(tableName, columns, newIndexes);
|
CreateTable(tableName, columns, newIndexes);
|
||||||
|
|
||||||
transaction.Commit();
|
transaction.Commit();
|
||||||
|
@ -57,7 +56,7 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
|
||||||
using (var transaction = _sqLiteMigrationHelper.BeginTransaction())
|
using (var transaction = _sqLiteMigrationHelper.BeginTransaction())
|
||||||
{
|
{
|
||||||
var originalColumns = _sqLiteMigrationHelper.GetColumns(tableName);
|
var originalColumns = _sqLiteMigrationHelper.GetColumns(tableName);
|
||||||
var originalIndexes = _sqLiteMigrationHelper.GetIndexes(tableName);
|
var indexes = _sqLiteMigrationHelper.GetIndexes(tableName);
|
||||||
|
|
||||||
var newColumns = originalColumns.Select(c =>
|
var newColumns = originalColumns.Select(c =>
|
||||||
{
|
{
|
||||||
|
@ -82,9 +81,7 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
|
||||||
return c.Value;
|
return c.Value;
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
var newIndexes = originalIndexes;
|
CreateTable(tableName, newColumns, indexes);
|
||||||
|
|
||||||
CreateTable(tableName, newColumns, newIndexes);
|
|
||||||
|
|
||||||
transaction.Commit();
|
transaction.Commit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace NzbDrone.Core.Datastore
|
||||||
|
|
||||||
Mapper.Entity<QualityProfile>().RegisterModel("QualityProfiles");
|
Mapper.Entity<QualityProfile>().RegisterModel("QualityProfiles");
|
||||||
|
|
||||||
Mapper.Entity<QualitySize>().RegisterModel("QualitySizes");
|
Mapper.Entity<QualityDefinition>().RegisterModel("QualityDefinitions");
|
||||||
|
|
||||||
Mapper.Entity<Log>().RegisterModel("Logs");
|
Mapper.Entity<Log>().RegisterModel("Logs");
|
||||||
|
|
||||||
|
@ -81,6 +81,8 @@ namespace NzbDrone.Core.Datastore
|
||||||
MapRepository.Instance.RegisterTypeConverter(typeof(Boolean), new BooleanIntConverter());
|
MapRepository.Instance.RegisterTypeConverter(typeof(Boolean), new BooleanIntConverter());
|
||||||
MapRepository.Instance.RegisterTypeConverter(typeof(Enum), new EnumIntConverter());
|
MapRepository.Instance.RegisterTypeConverter(typeof(Enum), new EnumIntConverter());
|
||||||
MapRepository.Instance.RegisterTypeConverter(typeof(Quality), new QualityIntConverter());
|
MapRepository.Instance.RegisterTypeConverter(typeof(Quality), new QualityIntConverter());
|
||||||
|
MapRepository.Instance.RegisterTypeConverter(typeof(List<QualityProfileItem>), new EmbeddedDocumentConverter(new QualityIntConverter()));
|
||||||
|
MapRepository.Instance.RegisterTypeConverter(typeof(QualityModel), new EmbeddedDocumentConverter(new QualityIntConverter()));
|
||||||
MapRepository.Instance.RegisterTypeConverter(typeof(Dictionary<string, string>), new EmbeddedDocumentConverter());
|
MapRepository.Instance.RegisterTypeConverter(typeof(Dictionary<string, string>), new EmbeddedDocumentConverter());
|
||||||
MapRepository.Instance.RegisterTypeConverter(typeof(List<int>), new EmbeddedDocumentConverter());
|
MapRepository.Instance.RegisterTypeConverter(typeof(List<int>), new EmbeddedDocumentConverter());
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace NzbDrone.Core.DecisionEngine
|
||||||
{
|
{
|
||||||
public interface IQualityUpgradableSpecification
|
public interface IQualityUpgradableSpecification
|
||||||
{
|
{
|
||||||
bool IsUpgradable(QualityModel currentQuality, QualityModel newQuality = null);
|
bool IsUpgradable(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null);
|
||||||
bool CutoffNotMet(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null);
|
bool CutoffNotMet(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null);
|
||||||
bool IsProperUpgrade(QualityModel currentQuality, QualityModel newQuality);
|
bool IsProperUpgrade(QualityModel currentQuality, QualityModel newQuality);
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,12 @@ namespace NzbDrone.Core.DecisionEngine
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsUpgradable(QualityModel currentQuality, QualityModel newQuality = null)
|
public bool IsUpgradable(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null)
|
||||||
{
|
{
|
||||||
if (newQuality != null)
|
if (newQuality != null)
|
||||||
{
|
{
|
||||||
if (currentQuality >= newQuality)
|
int compare = new QualityModelComparer(profile).Compare(newQuality, currentQuality);
|
||||||
|
if (compare <= 0)
|
||||||
{
|
{
|
||||||
_logger.Trace("existing item has better or equal quality. skipping");
|
_logger.Trace("existing item has better or equal quality. skipping");
|
||||||
return false;
|
return false;
|
||||||
|
@ -41,7 +42,9 @@ namespace NzbDrone.Core.DecisionEngine
|
||||||
|
|
||||||
public bool CutoffNotMet(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null)
|
public bool CutoffNotMet(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null)
|
||||||
{
|
{
|
||||||
if (currentQuality.Quality >= profile.Cutoff)
|
int compare = new QualityModelComparer(profile).Compare(currentQuality.Quality, profile.Cutoff);
|
||||||
|
|
||||||
|
if (compare >= 0)
|
||||||
{
|
{
|
||||||
if (newQuality != null && IsProperUpgrade(currentQuality, newQuality))
|
if (newQuality != null && IsProperUpgrade(currentQuality, newQuality))
|
||||||
{
|
{
|
||||||
|
@ -57,7 +60,9 @@ namespace NzbDrone.Core.DecisionEngine
|
||||||
|
|
||||||
public bool IsProperUpgrade(QualityModel currentQuality, QualityModel newQuality)
|
public bool IsProperUpgrade(QualityModel currentQuality, QualityModel newQuality)
|
||||||
{
|
{
|
||||||
if (currentQuality.Quality == newQuality.Quality && newQuality > currentQuality)
|
int compare = newQuality.Proper.CompareTo(currentQuality.Proper);
|
||||||
|
|
||||||
|
if (currentQuality.Quality == newQuality.Quality && compare > 0)
|
||||||
{
|
{
|
||||||
_logger.Trace("New quality is a proper for existing quality");
|
_logger.Trace("New quality is a proper for existing quality");
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -9,13 +9,13 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
{
|
{
|
||||||
public class AcceptableSizeSpecification : IDecisionEngineSpecification
|
public class AcceptableSizeSpecification : IDecisionEngineSpecification
|
||||||
{
|
{
|
||||||
private readonly IQualitySizeService _qualityTypeProvider;
|
private readonly IQualityDefinitionService _qualityDefinitionService;
|
||||||
private readonly IEpisodeService _episodeService;
|
private readonly IEpisodeService _episodeService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public AcceptableSizeSpecification(IQualitySizeService qualityTypeProvider, IEpisodeService episodeService, Logger logger)
|
public AcceptableSizeSpecification(IQualityDefinitionService qualityDefinitionService, IEpisodeService episodeService, Logger logger)
|
||||||
{
|
{
|
||||||
_qualityTypeProvider = qualityTypeProvider;
|
_qualityDefinitionService = qualityDefinitionService;
|
||||||
_episodeService = episodeService;
|
_episodeService = episodeService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
@ -44,15 +44,15 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var qualityType = _qualityTypeProvider.Get(quality.Id);
|
var qualityDefinition = _qualityDefinitionService.Get(quality);
|
||||||
|
|
||||||
if (qualityType.MaxSize == 0)
|
if (qualityDefinition.MaxSize == 0)
|
||||||
{
|
{
|
||||||
_logger.Trace("Max size is 0 (unlimited) - skipping check.");
|
_logger.Trace("Max size is 0 (unlimited) - skipping check.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var maxSize = qualityType.MaxSize.Megabytes();
|
var maxSize = qualityDefinition.MaxSize.Megabytes();
|
||||||
|
|
||||||
//Multiply maxSize by Series.Runtime
|
//Multiply maxSize by Series.Runtime
|
||||||
maxSize = maxSize * subject.Series.Runtime * subject.Episodes.Count;
|
maxSize = maxSize * subject.Series.Runtime * subject.Episodes.Count;
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
|
|
||||||
if (_blacklistService.Blacklisted(subject.Release.Title))
|
if (_blacklistService.Blacklisted(subject.Release.Title))
|
||||||
{
|
{
|
||||||
_logger.Trace("{0} is blacklisted", subject.Release.Title);
|
_logger.Trace("{0} is blacklisted, rejecting.", subject.Release.Title);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
|
|
||||||
if (!_qualityUpgradableSpecification.CutoffNotMet(subject.Series.QualityProfile, file.Quality, subject.ParsedEpisodeInfo.Quality))
|
if (!_qualityUpgradableSpecification.CutoffNotMet(subject.Series.QualityProfile, file.Quality, subject.ParsedEpisodeInfo.Quality))
|
||||||
{
|
{
|
||||||
|
_logger.Trace("Cutoff already met, rejecting.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ using NLog;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
{
|
{
|
||||||
|
@ -38,13 +40,19 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
|
|
||||||
var queue = downloadClient.GetQueue().Select(q => q.RemoteEpisode);
|
var queue = downloadClient.GetQueue().Select(q => q.RemoteEpisode);
|
||||||
|
|
||||||
return !IsInQueue(subject, queue);
|
if (IsInQueue(subject, queue))
|
||||||
|
{
|
||||||
|
_logger.Trace("Already in queue, rejecting.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsInQueue(RemoteEpisode newEpisode, IEnumerable<RemoteEpisode> queue)
|
private bool IsInQueue(RemoteEpisode newEpisode, IEnumerable<RemoteEpisode> queue)
|
||||||
{
|
{
|
||||||
var matchingSeries = queue.Where(q => q.Series.Id == newEpisode.Series.Id);
|
var matchingSeries = queue.Where(q => q.Series.Id == newEpisode.Series.Id);
|
||||||
var matchingSeriesAndQuality = matchingSeries.Where(q => q.ParsedEpisodeInfo.Quality >= newEpisode.ParsedEpisodeInfo.Quality);
|
var matchingSeriesAndQuality = matchingSeries.Where(q => new QualityModelComparer(q.Series.QualityProfile).Compare(q.ParsedEpisodeInfo.Quality, newEpisode.ParsedEpisodeInfo.Quality) >= 0);
|
||||||
|
|
||||||
return matchingSeriesAndQuality.Any(q => q.Episodes.Select(e => e.Id).Intersect(newEpisode.Episodes.Select(e => e.Id)).Any());
|
return matchingSeriesAndQuality.Any(q => q.Episodes.Select(e => e.Id).Intersect(newEpisode.Episodes.Select(e => e.Id)).Any());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,24 @@
|
||||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
using NLog;
|
||||||
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
{
|
{
|
||||||
public class NotSampleSpecification : IDecisionEngineSpecification
|
public class NotSampleSpecification : IDecisionEngineSpecification
|
||||||
{
|
{
|
||||||
|
private readonly Logger _logger;
|
||||||
public string RejectionReason { get { return "Sample"; } }
|
public string RejectionReason { get { return "Sample"; } }
|
||||||
|
|
||||||
|
public NotSampleSpecification(Logger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
public bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
||||||
{
|
{
|
||||||
if (subject.Release.Title.ToLower().Contains("sample") && subject.Release.Size < 70.Megabytes())
|
if (subject.Release.Title.ToLower().Contains("sample") && subject.Release.Size < 70.Megabytes())
|
||||||
{
|
{
|
||||||
|
_logger.Trace("Sample release, rejecting.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
||||||
{
|
{
|
||||||
_logger.Trace("Checking if report meets quality requirements. {0}", subject.ParsedEpisodeInfo.Quality);
|
_logger.Trace("Checking if report meets quality requirements. {0}", subject.ParsedEpisodeInfo.Quality);
|
||||||
if (!subject.Series.QualityProfile.Value.Allowed.Contains(subject.ParsedEpisodeInfo.Quality.Quality))
|
if (!subject.Series.QualityProfile.Value.Items.Exists(v => v.Allowed && v.Quality == subject.ParsedEpisodeInfo.Quality.Quality))
|
||||||
{
|
{
|
||||||
_logger.Trace("Quality {0} rejected by Series' quality profile", subject.ParsedEpisodeInfo.Quality);
|
_logger.Trace("Quality {0} rejected by Series' quality profile", subject.ParsedEpisodeInfo.Quality);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -51,6 +51,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
|
||||||
|
|
||||||
if (mostRecent != null && mostRecent.EventType == HistoryEventType.Grabbed)
|
if (mostRecent != null && mostRecent.EventType == HistoryEventType.Grabbed)
|
||||||
{
|
{
|
||||||
|
_logger.Trace("Latest history item is downloading, rejecting.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,11 +60,11 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
|
||||||
|
|
||||||
foreach (var episode in subject.Episodes)
|
foreach (var episode in subject.Episodes)
|
||||||
{
|
{
|
||||||
var bestQualityInHistory = _historyService.GetBestQualityInHistory(episode.Id);
|
var bestQualityInHistory = _historyService.GetBestQualityInHistory(subject.Series.QualityProfile, episode.Id);
|
||||||
if (bestQualityInHistory != null)
|
if (bestQualityInHistory != null)
|
||||||
{
|
{
|
||||||
_logger.Trace("Comparing history quality with report. History is {0}", bestQualityInHistory);
|
_logger.Trace("Comparing history quality with report. History is {0}", bestQualityInHistory);
|
||||||
if (!_qualityUpgradableSpecification.IsUpgradable(bestQualityInHistory, subject.ParsedEpisodeInfo.Quality))
|
if (!_qualityUpgradableSpecification.IsUpgradable(subject.Series.QualityProfile, bestQualityInHistory, subject.ParsedEpisodeInfo.Quality))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
|
||||||
{
|
{
|
||||||
if (file.DateAdded < DateTime.Today.AddDays(-7))
|
if (file.DateAdded < DateTime.Today.AddDays(-7))
|
||||||
{
|
{
|
||||||
_logger.Trace("Proper for old file, skipping: {0}", subject);
|
_logger.Trace("Proper for old file, rejecting: {0}", subject);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
{
|
{
|
||||||
_logger.Trace("Comparing file quality with report. Existing file is {0}", file.Quality);
|
_logger.Trace("Comparing file quality with report. Existing file is {0}", file.Quality);
|
||||||
|
|
||||||
if (!_qualityUpgradableSpecification.IsUpgradable(file.Quality, subject.ParsedEpisodeInfo.Quality))
|
if (!_qualityUpgradableSpecification.IsUpgradable(subject.Series.QualityProfile, file.Quality, subject.ParsedEpisodeInfo.Quality))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,10 +31,10 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
var action = String.Format("mode=addfile&cat={0}&priority={1}", category, priority);
|
var action = String.Format("mode=addfile&cat={0}&priority={1}", category, priority);
|
||||||
|
|
||||||
request.AddFile("name", ReadFully(nzb), title, "application/x-nzb");
|
request.AddFile("name", ReadFully(nzb), title, "application/x-nzb");
|
||||||
|
|
||||||
var response = Json.TryDeserialize<SabAddResponse>(ProcessRequest(request, action));
|
|
||||||
|
|
||||||
if (response == null)
|
SabAddResponse response;
|
||||||
|
|
||||||
|
if (!Json.TryDeserialize<SabAddResponse>(ProcessRequest(request, action), out response))
|
||||||
{
|
{
|
||||||
response = new SabAddResponse();
|
response = new SabAddResponse();
|
||||||
response.Status = true;
|
response.Status = true;
|
||||||
|
@ -87,9 +87,9 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
throw new ApplicationException("Unable to connect to SABnzbd, please check your settings");
|
throw new ApplicationException("Unable to connect to SABnzbd, please check your settings");
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = Json.TryDeserialize<SabJsonError>(response.Content);
|
SabJsonError result;
|
||||||
|
|
||||||
if (result == null)
|
if (!Json.TryDeserialize<SabJsonError>(response.Content, out result))
|
||||||
{
|
{
|
||||||
//Handle plain text responses from SAB
|
//Handle plain text responses from SAB
|
||||||
result = new SabJsonError();
|
result = new SabJsonError();
|
||||||
|
|
|
@ -3,6 +3,8 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download
|
namespace NzbDrone.Core.Download
|
||||||
{
|
{
|
||||||
|
@ -16,7 +18,7 @@ namespace NzbDrone.Core.Download
|
||||||
private readonly IDownloadService _downloadService;
|
private readonly IDownloadService _downloadService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public DownloadApprovedReports(IDownloadService downloadService, Logger logger)
|
public DownloadApprovedReports(IDownloadService downloadService, Logger logger)
|
||||||
{
|
{
|
||||||
_downloadService = downloadService;
|
_downloadService = downloadService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
@ -57,11 +59,13 @@ namespace NzbDrone.Core.Download
|
||||||
public List<DownloadDecision> GetQualifiedReports(IEnumerable<DownloadDecision> decisions)
|
public List<DownloadDecision> GetQualifiedReports(IEnumerable<DownloadDecision> decisions)
|
||||||
{
|
{
|
||||||
return decisions.Where(c => c.Approved && c.RemoteEpisode.Episodes.Any())
|
return decisions.Where(c => c.Approved && c.RemoteEpisode.Episodes.Any())
|
||||||
.OrderByDescending(c => c.RemoteEpisode.ParsedEpisodeInfo.Quality)
|
.GroupBy(c => c.RemoteEpisode.Series.Id, (i,s) => s
|
||||||
.ThenBy(c => c.RemoteEpisode.Episodes.Select(e => e.EpisodeNumber).MinOrDefault())
|
.OrderByDescending(c => c.RemoteEpisode.ParsedEpisodeInfo.Quality, new QualityModelComparer(s.First().RemoteEpisode.Series.QualityProfile))
|
||||||
.ThenBy(c => c.RemoteEpisode.Release.Size.Round(200.Megabytes()) / c.RemoteEpisode.Episodes.Count)
|
.ThenBy(c => c.RemoteEpisode.Episodes.Select(e => e.EpisodeNumber).MinOrDefault())
|
||||||
.ThenBy(c => c.RemoteEpisode.Release.Age)
|
.ThenBy(c => c.RemoteEpisode.Release.Size.Round(200.Megabytes()) / c.RemoteEpisode.Episodes.Count)
|
||||||
.ToList();
|
.ThenBy(c => c.RemoteEpisode.Release.Age))
|
||||||
|
.SelectMany(c => c)
|
||||||
|
.ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Common.Messaging;
|
using NzbDrone.Common.Messaging;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download
|
namespace NzbDrone.Core.Download
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.History
|
namespace NzbDrone.Core.History
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||||
using Marr.Data.QGen;
|
using Marr.Data.QGen;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.History
|
namespace NzbDrone.Core.History
|
||||||
|
|
|
@ -6,6 +6,7 @@ using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.History
|
namespace NzbDrone.Core.History
|
||||||
|
@ -15,7 +16,7 @@ namespace NzbDrone.Core.History
|
||||||
List<History> All();
|
List<History> All();
|
||||||
void Purge();
|
void Purge();
|
||||||
void Trim();
|
void Trim();
|
||||||
QualityModel GetBestQualityInHistory(int episodeId);
|
QualityModel GetBestQualityInHistory(QualityProfile qualityProfile, int episodeId);
|
||||||
PagingSpec<History> Paged(PagingSpec<History> pagingSpec);
|
PagingSpec<History> Paged(PagingSpec<History> pagingSpec);
|
||||||
List<History> BetweenDates(DateTime startDate, DateTime endDate, HistoryEventType eventType);
|
List<History> BetweenDates(DateTime startDate, DateTime endDate, HistoryEventType eventType);
|
||||||
List<History> Failed();
|
List<History> Failed();
|
||||||
|
@ -80,9 +81,12 @@ namespace NzbDrone.Core.History
|
||||||
_historyRepository.Trim();
|
_historyRepository.Trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
public QualityModel GetBestQualityInHistory(int episodeId)
|
public QualityModel GetBestQualityInHistory(QualityProfile qualityProfile, int episodeId)
|
||||||
{
|
{
|
||||||
return _historyRepository.GetBestQualityInHistory(episodeId).OrderByDescending(q => q).FirstOrDefault();
|
var comparer = new QualityModelComparer(qualityProfile);
|
||||||
|
return _historyRepository.GetBestQualityInHistory(episodeId)
|
||||||
|
.OrderByDescending(q => q, comparer)
|
||||||
|
.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(EpisodeGrabbedEvent message)
|
public void Handle(EpisodeGrabbedEvent message)
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IParseFeed Parser { get; private set; }
|
public virtual IParseFeed Parser { get; private set; }
|
||||||
|
|
||||||
public abstract IEnumerable<string> RecentFeed { get; }
|
public abstract IEnumerable<string> RecentFeed { get; }
|
||||||
public abstract IEnumerable<string> GetEpisodeSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int episodeNumber);
|
public abstract IEnumerable<string> GetEpisodeSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int episodeNumber);
|
||||||
public abstract IEnumerable<string> GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date);
|
public abstract IEnumerable<string> GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date);
|
||||||
|
@ -53,7 +53,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return GetType().Name;
|
return Definition.Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,16 +27,6 @@ namespace NzbDrone.Core.Jobs
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(ApplicationStartedEvent message)
|
|
||||||
{
|
|
||||||
_cancellationTokenSource = new CancellationTokenSource();
|
|
||||||
Timer.Interval = 1000 * 30;
|
|
||||||
Timer.Elapsed += (o, args) => Task.Factory.StartNew(ExecuteCommands, _cancellationTokenSource.Token)
|
|
||||||
.LogExceptions();
|
|
||||||
|
|
||||||
Timer.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ExecuteCommands()
|
private void ExecuteCommands()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -70,8 +60,19 @@ namespace NzbDrone.Core.Jobs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Handle(ApplicationStartedEvent message)
|
||||||
|
{
|
||||||
|
_cancellationTokenSource = new CancellationTokenSource();
|
||||||
|
Timer.Interval = 1000 * 30;
|
||||||
|
Timer.Elapsed += (o, args) => Task.Factory.StartNew(ExecuteCommands, _cancellationTokenSource.Token)
|
||||||
|
.LogExceptions();
|
||||||
|
|
||||||
|
Timer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
public void Handle(ApplicationShutdownRequested message)
|
public void Handle(ApplicationShutdownRequested message)
|
||||||
{
|
{
|
||||||
|
_logger.Info("Shutting down scheduler");
|
||||||
_cancellationTokenSource.Cancel(true);
|
_cancellationTokenSource.Cancel(true);
|
||||||
Timer.Stop();
|
Timer.Stop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace NzbDrone.Core.Jobs
|
||||||
new ScheduledTask{ Interval = 24*60, TypeName = typeof(HousekeepingCommand).FullName},
|
new ScheduledTask{ Interval = 24*60, TypeName = typeof(HousekeepingCommand).FullName},
|
||||||
};
|
};
|
||||||
|
|
||||||
var currentTasks = _scheduledTaskRepository.All();
|
var currentTasks = _scheduledTaskRepository.All().ToList();
|
||||||
|
|
||||||
_logger.Debug("Initializing jobs. Available: {0} Existing:{1}", defaultTasks.Count(), currentTasks.Count());
|
_logger.Debug("Initializing jobs. Available: {0} Existing:{1}", defaultTasks.Count(), currentTasks.Count());
|
||||||
|
|
||||||
|
@ -76,6 +76,11 @@ namespace NzbDrone.Core.Jobs
|
||||||
|
|
||||||
currentDefinition.Interval = defaultTask.Interval;
|
currentDefinition.Interval = defaultTask.Interval;
|
||||||
|
|
||||||
|
if (currentDefinition.Id == 0)
|
||||||
|
{
|
||||||
|
currentDefinition.LastExecution = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
_scheduledTaskRepository.Upsert(currentDefinition);
|
_scheduledTaskRepository.Upsert(currentDefinition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,15 @@ namespace NzbDrone.Core.Lifecycle
|
||||||
{
|
{
|
||||||
public class ApplicationShutdownRequested : IEvent
|
public class ApplicationShutdownRequested : IEvent
|
||||||
{
|
{
|
||||||
|
public bool Restarting { get; set; }
|
||||||
|
|
||||||
|
public ApplicationShutdownRequested()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApplicationShutdownRequested(bool restarting)
|
||||||
|
{
|
||||||
|
Restarting = restarting;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Lifecycle.Commands
|
||||||
|
{
|
||||||
|
public class RestartCommand : Command
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Lifecycle.Commands
|
||||||
|
{
|
||||||
|
public class ShutdownCommand : Command
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
using System;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
using NzbDrone.Common.Processes;
|
||||||
|
using NzbDrone.Core.Instrumentation;
|
||||||
|
using NzbDrone.Core.Lifecycle.Commands;
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using IServiceProvider = NzbDrone.Common.IServiceProvider;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Lifecycle
|
||||||
|
{
|
||||||
|
public class LifecycleService: IExecute<ShutdownCommand>, IExecute<RestartCommand>
|
||||||
|
{
|
||||||
|
private readonly IEventAggregator _eventAggregator;
|
||||||
|
private readonly IRuntimeInfo _runtimeInfo;
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
private readonly IProcessProvider _processProvider;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
|
||||||
|
public LifecycleService(IEventAggregator eventAggregator,
|
||||||
|
IRuntimeInfo runtimeInfo,
|
||||||
|
IServiceProvider serviceProvider,
|
||||||
|
IProcessProvider processProvider,
|
||||||
|
Logger logger)
|
||||||
|
{
|
||||||
|
_eventAggregator = eventAggregator;
|
||||||
|
_runtimeInfo = runtimeInfo;
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
|
_processProvider = processProvider;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute(ShutdownCommand message)
|
||||||
|
{
|
||||||
|
_logger.Info("Shutdown requested.");
|
||||||
|
_eventAggregator.PublishEvent(new ApplicationShutdownRequested());
|
||||||
|
|
||||||
|
if (_runtimeInfo.IsWindowsService)
|
||||||
|
{
|
||||||
|
_serviceProvider.Stop(ServiceProvider.NZBDRONE_SERVICE_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute(RestartCommand message)
|
||||||
|
{
|
||||||
|
_logger.Info("Restart requested.");
|
||||||
|
|
||||||
|
if (OsInfo.IsLinux)
|
||||||
|
{
|
||||||
|
_processProvider.SpawnNewProcess(_runtimeInfo.ExecutingApplication, "--terminateexisting --nobrowser");
|
||||||
|
}
|
||||||
|
|
||||||
|
_eventAggregator.PublishEvent(new ApplicationShutdownRequested(true));
|
||||||
|
|
||||||
|
if (_runtimeInfo.IsWindowsService)
|
||||||
|
{
|
||||||
|
_serviceProvider.Restart(ServiceProvider.NZBDRONE_SERVICE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_processProvider.SpawnNewProcess(_runtimeInfo.ExecutingApplication, "--terminateexisting --nobrowser");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaFiles.Commands
|
||||||
|
{
|
||||||
|
public class RescanSeriesCommand : Command
|
||||||
|
{
|
||||||
|
public int SeriesId { get; set; }
|
||||||
|
|
||||||
|
public override bool SendUpdatesToClient
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using System.IO;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
|
@ -21,13 +22,15 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
|
|
||||||
public class DiskScanService :
|
public class DiskScanService :
|
||||||
IDiskScanService,
|
IDiskScanService,
|
||||||
IHandle<SeriesUpdatedEvent>
|
IHandle<SeriesUpdatedEvent>,
|
||||||
|
IExecute<RescanSeriesCommand>
|
||||||
{
|
{
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
private readonly IMakeImportDecision _importDecisionMaker;
|
private readonly IMakeImportDecision _importDecisionMaker;
|
||||||
private readonly IImportApprovedEpisodes _importApprovedEpisodes;
|
private readonly IImportApprovedEpisodes _importApprovedEpisodes;
|
||||||
private readonly ICommandExecutor _commandExecutor;
|
private readonly ICommandExecutor _commandExecutor;
|
||||||
private readonly IConfigService _configService;
|
private readonly IConfigService _configService;
|
||||||
|
private readonly ISeriesService _seriesService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public DiskScanService(IDiskProvider diskProvider,
|
public DiskScanService(IDiskProvider diskProvider,
|
||||||
|
@ -35,6 +38,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
IImportApprovedEpisodes importApprovedEpisodes,
|
IImportApprovedEpisodes importApprovedEpisodes,
|
||||||
ICommandExecutor commandExecutor,
|
ICommandExecutor commandExecutor,
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
|
ISeriesService seriesService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
|
@ -42,6 +46,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
_importApprovedEpisodes = importApprovedEpisodes;
|
_importApprovedEpisodes = importApprovedEpisodes;
|
||||||
_commandExecutor = commandExecutor;
|
_commandExecutor = commandExecutor;
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
|
_seriesService = seriesService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,5 +95,12 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
{
|
{
|
||||||
Scan(message.Series);
|
Scan(message.Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Execute(RescanSeriesCommand message)
|
||||||
|
{
|
||||||
|
var series = _seriesService.GetSeries(message.SeriesId);
|
||||||
|
|
||||||
|
Scan(series);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue