Merge branch 'develop'
This commit is contained in:
commit
e7c2eda995
BIN
Logo/64.png
BIN
Logo/64.png
Binary file not shown.
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 3.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 79 KiB |
Binary file not shown.
Before Width: | Height: | Size: 65 KiB |
Binary file not shown.
Before Width: | Height: | Size: 92 KiB |
|
@ -0,0 +1,21 @@
|
||||||
|
using System;
|
||||||
|
using FluentValidation;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Config
|
||||||
|
{
|
||||||
|
public class DownloadClientConfigModule : NzbDroneConfigModule<DownloadClientConfigResource>
|
||||||
|
{
|
||||||
|
public DownloadClientConfigModule(IConfigService configService, RootFolderValidator rootFolderValidator, PathExistsValidator pathExistsValidator)
|
||||||
|
: base(configService)
|
||||||
|
{
|
||||||
|
SharedValidator.RuleFor(c => c.DownloadedEpisodesFolder)
|
||||||
|
.Cascade(CascadeMode.StopOnFirstFailure)
|
||||||
|
.IsValidPath()
|
||||||
|
.SetValidator(rootFolderValidator)
|
||||||
|
.SetValidator(pathExistsValidator)
|
||||||
|
.When(c => !String.IsNullOrWhiteSpace(c.DownloadedEpisodesFolder));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
using NzbDrone.Api.REST;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Config
|
||||||
|
{
|
||||||
|
public class DownloadClientConfigResource : RestResource
|
||||||
|
{
|
||||||
|
public String DownloadedEpisodesFolder { get; set; }
|
||||||
|
public String DownloadClientWorkingFolders { get; set; }
|
||||||
|
|
||||||
|
public Boolean AutoRedownloadFailed { get; set; }
|
||||||
|
public Boolean RemoveFailedDownloads { get; set; }
|
||||||
|
public Boolean EnableFailedDownloadHandling { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using FluentValidation;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
using Omu.ValueInjecter;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Config
|
||||||
|
{
|
||||||
|
public class HostConfigModule : NzbDroneRestModule<HostConfigResource>
|
||||||
|
{
|
||||||
|
private readonly IConfigFileProvider _configFileProvider;
|
||||||
|
|
||||||
|
public HostConfigModule(ConfigFileProvider configFileProvider)
|
||||||
|
: base("/config/host")
|
||||||
|
{
|
||||||
|
_configFileProvider = configFileProvider;
|
||||||
|
|
||||||
|
GetResourceSingle = GetHostConfig;
|
||||||
|
GetResourceById = GetHostConfig;
|
||||||
|
UpdateResource = SaveHostConfig;
|
||||||
|
|
||||||
|
SharedValidator.RuleFor(c => c.Branch).NotEmpty().WithMessage("Branch name is required, 'master' is the default");
|
||||||
|
SharedValidator.RuleFor(c => c.Port).InclusiveBetween(1, 65535);
|
||||||
|
|
||||||
|
SharedValidator.RuleFor(c => c.Username).NotEmpty().When(c => c.AuthenticationEnabled);
|
||||||
|
SharedValidator.RuleFor(c => c.Password).NotEmpty().When(c => c.AuthenticationEnabled);
|
||||||
|
|
||||||
|
SharedValidator.RuleFor(c => c.SslPort).InclusiveBetween(1, 65535).When(c => c.EnableSsl);
|
||||||
|
SharedValidator.RuleFor(c => c.SslCertHash).NotEmpty().When(c => c.EnableSsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private HostConfigResource GetHostConfig()
|
||||||
|
{
|
||||||
|
var resource = new HostConfigResource();
|
||||||
|
resource.InjectFrom(_configFileProvider);
|
||||||
|
resource.Id = 1;
|
||||||
|
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HostConfigResource GetHostConfig(int id)
|
||||||
|
{
|
||||||
|
return GetHostConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveHostConfig(HostConfigResource resource)
|
||||||
|
{
|
||||||
|
var dictionary = resource.GetType()
|
||||||
|
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
|
||||||
|
.ToDictionary(prop => prop.Name, prop => prop.GetValue(resource, null));
|
||||||
|
|
||||||
|
_configFileProvider.SaveConfigDictionary(dictionary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
using System;
|
||||||
|
using NzbDrone.Api.REST;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Config
|
||||||
|
{
|
||||||
|
public class HostConfigResource : RestResource
|
||||||
|
{
|
||||||
|
public Int32 Port { get; set; }
|
||||||
|
public Int32 SslPort { get; set; }
|
||||||
|
public Boolean EnableSsl { get; set; }
|
||||||
|
public Boolean LaunchBrowser { get; set; }
|
||||||
|
public Boolean AuthenticationEnabled { get; set; }
|
||||||
|
public String Username { get; set; }
|
||||||
|
public String Password { get; set; }
|
||||||
|
public String LogLevel { get; set; }
|
||||||
|
public String Branch { get; set; }
|
||||||
|
public String ApiKey { get; set; }
|
||||||
|
public Boolean Torrent { get; set; }
|
||||||
|
public String SslCertHash { get; set; }
|
||||||
|
public String UrlBase { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
using FluentValidation;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Config
|
||||||
|
{
|
||||||
|
public class IndexerConfigModule : NzbDroneConfigModule<IndexerConfigResource>
|
||||||
|
{
|
||||||
|
|
||||||
|
public IndexerConfigModule(IConfigService configService)
|
||||||
|
: base(configService)
|
||||||
|
{
|
||||||
|
SharedValidator.RuleFor(c => c.RssSyncInterval).InclusiveBetween(10, 120);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
using NzbDrone.Api.REST;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Config
|
||||||
|
{
|
||||||
|
public class IndexerConfigResource : RestResource
|
||||||
|
{
|
||||||
|
public Int32 Retention { get; set; }
|
||||||
|
public Int32 RssSyncInterval { get; set; }
|
||||||
|
public String ReleaseRestrictions { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
using FluentValidation;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Config
|
||||||
|
{
|
||||||
|
public class MediaManagementConfigModule : NzbDroneConfigModule<MediaManagementConfigResource>
|
||||||
|
{
|
||||||
|
public MediaManagementConfigModule(IConfigService configService, PathExistsValidator pathExistsValidator)
|
||||||
|
: base(configService)
|
||||||
|
{
|
||||||
|
SharedValidator.RuleFor(c => c.FileChmod).NotEmpty();
|
||||||
|
SharedValidator.RuleFor(c => c.FolderChmod).NotEmpty();
|
||||||
|
SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath().SetValidator(pathExistsValidator).When(c => !String.IsNullOrWhiteSpace(c.RecycleBin));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
using NzbDrone.Api.REST;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Config
|
||||||
|
{
|
||||||
|
public class MediaManagementConfigResource : RestResource
|
||||||
|
{
|
||||||
|
public Boolean AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
|
||||||
|
public String RecycleBin { get; set; }
|
||||||
|
public Boolean AutoDownloadPropers { get; set; }
|
||||||
|
public Boolean CreateEmptySeriesFolders { get; set; }
|
||||||
|
|
||||||
|
public Boolean SetPermissionsLinux { get; set; }
|
||||||
|
public String FileChmod { get; set; }
|
||||||
|
public String FolderChmod { get; set; }
|
||||||
|
public String ChownUser { get; set; }
|
||||||
|
public String ChownGroup { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,14 +12,14 @@ using Omu.ValueInjecter;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Config
|
namespace NzbDrone.Api.Config
|
||||||
{
|
{
|
||||||
public class NamingModule : NzbDroneRestModule<NamingConfigResource>
|
public class NamingConfigModule : NzbDroneRestModule<NamingConfigResource>
|
||||||
{
|
{
|
||||||
private readonly INamingConfigService _namingConfigService;
|
private readonly INamingConfigService _namingConfigService;
|
||||||
private readonly IFilenameSampleService _filenameSampleService;
|
private readonly IFilenameSampleService _filenameSampleService;
|
||||||
private readonly IFilenameValidationService _filenameValidationService;
|
private readonly IFilenameValidationService _filenameValidationService;
|
||||||
private readonly IBuildFileNames _filenameBuilder;
|
private readonly IBuildFileNames _filenameBuilder;
|
||||||
|
|
||||||
public NamingModule(INamingConfigService namingConfigService,
|
public NamingConfigModule(INamingConfigService namingConfigService,
|
||||||
IFilenameSampleService filenameSampleService,
|
IFilenameSampleService filenameSampleService,
|
||||||
IFilenameValidationService filenameValidationService,
|
IFilenameValidationService filenameValidationService,
|
||||||
IBuildFileNames filenameBuilder)
|
IBuildFileNames filenameBuilder)
|
|
@ -0,0 +1,51 @@
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using NzbDrone.Api.REST;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
using Omu.ValueInjecter;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Config
|
||||||
|
{
|
||||||
|
public abstract class NzbDroneConfigModule<TResource> : NzbDroneRestModule<TResource> where TResource : RestResource, new()
|
||||||
|
{
|
||||||
|
private readonly IConfigService _configService;
|
||||||
|
|
||||||
|
protected NzbDroneConfigModule(IConfigService configService)
|
||||||
|
: this(new TResource().ResourceName.Replace("config", ""), configService)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected NzbDroneConfigModule(string resource, IConfigService configService) :
|
||||||
|
base("config/" + resource.Trim('/'))
|
||||||
|
{
|
||||||
|
_configService = configService;
|
||||||
|
|
||||||
|
GetResourceSingle = GetConfig;
|
||||||
|
GetResourceById = GetConfig;
|
||||||
|
UpdateResource = SaveConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TResource GetConfig()
|
||||||
|
{
|
||||||
|
var resource = new TResource();
|
||||||
|
resource.InjectFrom(_configService);
|
||||||
|
resource.Id = 1;
|
||||||
|
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TResource GetConfig(int id)
|
||||||
|
{
|
||||||
|
return GetConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveConfig(TResource resource)
|
||||||
|
{
|
||||||
|
var dictionary = resource.GetType()
|
||||||
|
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
|
||||||
|
.ToDictionary(prop => prop.Name, prop => prop.GetValue(resource, null));
|
||||||
|
|
||||||
|
_configService.SaveConfigDictionary(dictionary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,71 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Nancy;
|
|
||||||
using NzbDrone.Api.Extensions;
|
|
||||||
using NzbDrone.Core.Configuration;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Config
|
|
||||||
{
|
|
||||||
public class SettingsModule : NzbDroneApiModule
|
|
||||||
{
|
|
||||||
private readonly IConfigService _configService;
|
|
||||||
private readonly IConfigFileProvider _configFileProvider;
|
|
||||||
|
|
||||||
public SettingsModule(IConfigService configService, IConfigFileProvider configFileProvider)
|
|
||||||
: base("/settings")
|
|
||||||
{
|
|
||||||
_configService = configService;
|
|
||||||
_configFileProvider = configFileProvider;
|
|
||||||
Get["/"] = x => GetGeneralSettings();
|
|
||||||
Post["/"] = x => SaveGeneralSettings();
|
|
||||||
|
|
||||||
Get["/host"] = x => GetHostSettings();
|
|
||||||
Post["/host"] = x => SaveHostSettings();
|
|
||||||
|
|
||||||
Get["/log"] = x => GetLogSettings();
|
|
||||||
Post["/log"] = x => SaveLogSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Response SaveLogSettings()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Response GetLogSettings()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Response SaveHostSettings()
|
|
||||||
{
|
|
||||||
var request = Request.Body.FromJson<Dictionary<string, object>>();
|
|
||||||
_configFileProvider.SaveConfigDictionary(request);
|
|
||||||
|
|
||||||
return GetHostSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Response GetHostSettings()
|
|
||||||
{
|
|
||||||
return _configFileProvider.GetConfigDictionary().AsResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Response GetGeneralSettings()
|
|
||||||
{
|
|
||||||
var collection = Request.Query.Collection;
|
|
||||||
|
|
||||||
if (collection.HasValue && Boolean.Parse(collection.Value))
|
|
||||||
return _configService.All().AsResponse();
|
|
||||||
|
|
||||||
return _configService.AllWithDefaults().AsResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Response SaveGeneralSettings()
|
|
||||||
{
|
|
||||||
var request = Request.Body.FromJson<Dictionary<string, object>>();
|
|
||||||
_configService.SaveValues(request);
|
|
||||||
|
|
||||||
|
|
||||||
return request.AsResponse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.DownloadClient
|
||||||
|
{
|
||||||
|
public class DownloadClientModule : ProviderModuleBase<DownloadClientResource, IDownloadClient, DownloadClientDefinition>
|
||||||
|
{
|
||||||
|
public DownloadClientModule(IDownloadClientFactory downloadClientFactory)
|
||||||
|
: base(downloadClientFactory, "downloadclient")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Validate(DownloadClientDefinition definition)
|
||||||
|
{
|
||||||
|
if (!definition.Enable) return;
|
||||||
|
base.Validate(definition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.DownloadClient
|
||||||
|
{
|
||||||
|
public class DownloadClientResource : ProviderResource
|
||||||
|
{
|
||||||
|
public Boolean Enable { get; set; }
|
||||||
|
public Int32 Protocol { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Api.ClientSchema;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
|
using Omu.ValueInjecter;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.DownloadClient
|
||||||
|
{
|
||||||
|
public class DownloadClientSchemaModule : NzbDroneRestModule<DownloadClientResource>
|
||||||
|
{
|
||||||
|
private readonly IDownloadClientFactory _notificationFactory;
|
||||||
|
|
||||||
|
public DownloadClientSchemaModule(IDownloadClientFactory notificationFactory)
|
||||||
|
: base("downloadclient/schema")
|
||||||
|
{
|
||||||
|
_notificationFactory = notificationFactory;
|
||||||
|
GetResourceAll = GetSchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<DownloadClientResource> GetSchema()
|
||||||
|
{
|
||||||
|
var notifications = _notificationFactory.Templates();
|
||||||
|
|
||||||
|
var result = new List<DownloadClientResource>(notifications.Count);
|
||||||
|
|
||||||
|
foreach (var notification in notifications)
|
||||||
|
{
|
||||||
|
var notificationResource = new DownloadClientResource();
|
||||||
|
notificationResource.InjectFrom(notification);
|
||||||
|
notificationResource.Fields = SchemaBuilder.ToSchema(notification.Settings);
|
||||||
|
|
||||||
|
result.Add(notificationResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -92,8 +92,19 @@
|
||||||
<Compile Include="ClientSchema\SelectOption.cs" />
|
<Compile Include="ClientSchema\SelectOption.cs" />
|
||||||
<Compile Include="Commands\CommandModule.cs" />
|
<Compile Include="Commands\CommandModule.cs" />
|
||||||
<Compile Include="Commands\CommandResource.cs" />
|
<Compile Include="Commands\CommandResource.cs" />
|
||||||
|
<Compile Include="Config\IndexerConfigModule.cs" />
|
||||||
|
<Compile Include="Config\MediaManagementConfigModule.cs" />
|
||||||
|
<Compile Include="Config\MediaManagementConfigResource.cs" />
|
||||||
|
<Compile Include="Config\NzbDroneConfigModule.cs" />
|
||||||
|
<Compile Include="Config\DownloadClientConfigModule.cs" />
|
||||||
|
<Compile Include="Config\DownloadClientConfigResource.cs" />
|
||||||
|
<Compile Include="Config\HostConfigModule.cs" />
|
||||||
|
<Compile Include="Config\HostConfigResource.cs" />
|
||||||
<Compile Include="Config\NamingConfigResource.cs" />
|
<Compile Include="Config\NamingConfigResource.cs" />
|
||||||
<Compile Include="Config\NamingModule.cs" />
|
<Compile Include="Config\NamingConfigModule.cs" />
|
||||||
|
<Compile Include="Config\IndexerConfigResource.cs" />
|
||||||
|
<Compile Include="DownloadClient\DownloadClientModule.cs" />
|
||||||
|
<Compile Include="DownloadClient\DownloadClientResource.cs" />
|
||||||
<Compile Include="DiskSpace\DiskSpaceModule.cs" />
|
<Compile Include="DiskSpace\DiskSpaceModule.cs" />
|
||||||
<Compile Include="DiskSpace\DiskSpaceResource.cs" />
|
<Compile Include="DiskSpace\DiskSpaceResource.cs" />
|
||||||
<Compile Include="EpisodeFiles\EpisodeFileModule.cs" />
|
<Compile Include="EpisodeFiles\EpisodeFileModule.cs" />
|
||||||
|
@ -122,6 +133,7 @@
|
||||||
<Compile Include="History\HistoryModule.cs" />
|
<Compile Include="History\HistoryModule.cs" />
|
||||||
<Compile Include="Metadata\MetadataResource.cs" />
|
<Compile Include="Metadata\MetadataResource.cs" />
|
||||||
<Compile Include="Metadata\MetadataModule.cs" />
|
<Compile Include="Metadata\MetadataModule.cs" />
|
||||||
|
<Compile Include="Notifications\NotificationSchemaModule.cs" />
|
||||||
<Compile Include="ProviderResource.cs" />
|
<Compile Include="ProviderResource.cs" />
|
||||||
<Compile Include="ProviderModuleBase.cs" />
|
<Compile Include="ProviderModuleBase.cs" />
|
||||||
<Compile Include="Indexers\IndexerSchemaModule.cs" />
|
<Compile Include="Indexers\IndexerSchemaModule.cs" />
|
||||||
|
@ -145,7 +157,7 @@
|
||||||
<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" />
|
||||||
<Compile Include="Notifications\NotificationSchemaModule.cs" />
|
<Compile Include="DownloadClient\DownloadClientSchemaModule.cs" />
|
||||||
<Compile Include="Notifications\NotificationModule.cs" />
|
<Compile Include="Notifications\NotificationModule.cs" />
|
||||||
<Compile Include="Notifications\NotificationResource.cs" />
|
<Compile Include="Notifications\NotificationResource.cs" />
|
||||||
<Compile Include="NzbDroneRestModule.cs" />
|
<Compile Include="NzbDroneRestModule.cs" />
|
||||||
|
@ -174,11 +186,9 @@
|
||||||
<Compile Include="Qualities\QualityDefinitionResource.cs" />
|
<Compile Include="Qualities\QualityDefinitionResource.cs" />
|
||||||
<Compile Include="Qualities\QualityDefinitionModule.cs" />
|
<Compile Include="Qualities\QualityDefinitionModule.cs" />
|
||||||
<Compile Include="Extensions\ReqResExtensions.cs" />
|
<Compile Include="Extensions\ReqResExtensions.cs" />
|
||||||
<Compile Include="Config\SettingsModule.cs" />
|
|
||||||
<Compile Include="System\SystemModule.cs" />
|
<Compile Include="System\SystemModule.cs" />
|
||||||
<Compile Include="TinyIoCNancyBootstrapper.cs" />
|
<Compile Include="TinyIoCNancyBootstrapper.cs" />
|
||||||
<Compile Include="Update\UpdateModule.cs" />
|
<Compile Include="Update\UpdateModule.cs" />
|
||||||
<Compile Include="Validation\PathValidator.cs" />
|
|
||||||
<Compile Include="Validation\RuleBuilderExtensions.cs" />
|
<Compile Include="Validation\RuleBuilderExtensions.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -5,7 +5,7 @@ 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;
|
||||||
using NzbDrone.Api.Validation;
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
|
||||||
namespace NzbDrone.Api.RootFolders
|
namespace NzbDrone.Api.RootFolders
|
||||||
{
|
{
|
||||||
|
@ -13,7 +13,11 @@ namespace NzbDrone.Api.RootFolders
|
||||||
{
|
{
|
||||||
private readonly IRootFolderService _rootFolderService;
|
private readonly IRootFolderService _rootFolderService;
|
||||||
|
|
||||||
public RootFolderModule(IRootFolderService rootFolderService, ICommandExecutor commandExecutor)
|
public RootFolderModule(IRootFolderService rootFolderService,
|
||||||
|
ICommandExecutor commandExecutor,
|
||||||
|
RootFolderValidator rootFolderValidator,
|
||||||
|
PathExistsValidator pathExistsValidator,
|
||||||
|
DroneFactoryValidator droneFactoryValidator)
|
||||||
: base(commandExecutor)
|
: base(commandExecutor)
|
||||||
{
|
{
|
||||||
_rootFolderService = rootFolderService;
|
_rootFolderService = rootFolderService;
|
||||||
|
@ -23,7 +27,12 @@ namespace NzbDrone.Api.RootFolders
|
||||||
CreateResource = CreateRootFolder;
|
CreateResource = CreateRootFolder;
|
||||||
DeleteResource = DeleteFolder;
|
DeleteResource = DeleteFolder;
|
||||||
|
|
||||||
SharedValidator.RuleFor(c => c.Path).IsValidPath();
|
SharedValidator.RuleFor(c => c.Path)
|
||||||
|
.Cascade(CascadeMode.StopOnFirstFailure)
|
||||||
|
.IsValidPath()
|
||||||
|
.SetValidator(rootFolderValidator)
|
||||||
|
.SetValidator(pathExistsValidator)
|
||||||
|
.SetValidator(droneFactoryValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RootFolderResource GetRootFolder(int id)
|
private RootFolderResource GetRootFolder(int id)
|
||||||
|
@ -33,15 +42,7 @@ namespace NzbDrone.Api.RootFolders
|
||||||
|
|
||||||
private int CreateRootFolder(RootFolderResource rootFolderResource)
|
private int CreateRootFolder(RootFolderResource rootFolderResource)
|
||||||
{
|
{
|
||||||
try
|
return GetNewId<RootFolder>(_rootFolderService.Add, rootFolderResource);
|
||||||
{
|
|
||||||
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()
|
||||||
|
|
|
@ -12,6 +12,7 @@ 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;
|
using NzbDrone.Core.Tv.Events;
|
||||||
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Series
|
namespace NzbDrone.Api.Series
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using FluentValidation.Validators;
|
using FluentValidation.Validators;
|
||||||
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Validation
|
namespace NzbDrone.Api.Validation
|
||||||
{
|
{
|
||||||
|
@ -21,11 +22,6 @@ namespace NzbDrone.Api.Validation
|
||||||
return ruleBuilder.SetValidator(new RegularExpressionValidator("^http(s)?://", RegexOptions.IgnoreCase)).WithMessage("must start with http:// or https://");
|
return ruleBuilder.SetValidator(new RegularExpressionValidator("^http(s)?://", RegexOptions.IgnoreCase)).WithMessage("must start with http:// or https://");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IRuleBuilderOptions<T, string> IsValidPath<T>(this IRuleBuilder<T, string> ruleBuilder)
|
|
||||||
{
|
|
||||||
return ruleBuilder.SetValidator(new PathValidator());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IRuleBuilderOptions<T, string> NotBlank<T>(this IRuleBuilder<T, string> ruleBuilder)
|
public static IRuleBuilderOptions<T, string> NotBlank<T>(this IRuleBuilder<T, string> ruleBuilder)
|
||||||
{
|
{
|
||||||
return ruleBuilder.SetValidator(new NotNullValidator()).SetValidator(new NotEmptyValidator(""));
|
return ruleBuilder.SetValidator(new NotNullValidator()).SetValidator(new NotEmptyValidator(""));
|
||||||
|
|
|
@ -71,7 +71,6 @@ namespace NzbDrone.Common
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static bool ContainsInvalidPathChars(this string text)
|
public static bool ContainsInvalidPathChars(this string text)
|
||||||
{
|
{
|
||||||
return text.IndexOfAny(Path.GetInvalidPathChars()) >= 0;
|
return text.IndexOfAny(Path.GetInvalidPathChars()) >= 0;
|
||||||
|
|
|
@ -179,9 +179,7 @@ namespace NzbDrone.Common.Processes
|
||||||
public ProcessOutput StartAndCapture(string path, string args = null)
|
public ProcessOutput StartAndCapture(string path, string args = null)
|
||||||
{
|
{
|
||||||
var output = new ProcessOutput();
|
var output = new ProcessOutput();
|
||||||
var process = Start(path, args, s => output.Standard.Add(s), error => output.Error.Add(error));
|
Start(path, args, s => output.Standard.Add(s), error => output.Error.Add(error)).WaitForExit();
|
||||||
|
|
||||||
WaitForExit(process);
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@ -190,10 +188,7 @@ namespace NzbDrone.Common.Processes
|
||||||
{
|
{
|
||||||
Logger.Trace("Waiting for process {0} to exit.", process.ProcessName);
|
Logger.Trace("Waiting for process {0} to exit.", process.ProcessName);
|
||||||
|
|
||||||
if (!process.HasExited)
|
process.WaitForExit();
|
||||||
{
|
|
||||||
process.WaitForExit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPriority(int processId, ProcessPriorityClass priority)
|
public void SetPriority(int processId, ProcessPriorityClass priority)
|
||||||
|
|
|
@ -105,16 +105,6 @@ namespace NzbDrone.Core.Test.Configuration
|
||||||
Subject.GetValue(key, value2).Should().Be(value2);
|
Subject.GetValue(key, value2).Should().Be(value2);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void updating_a_vakye_should_update_its_value()
|
|
||||||
{
|
|
||||||
Subject.SabHost = "Test";
|
|
||||||
Subject.SabHost.Should().Be("Test");
|
|
||||||
|
|
||||||
Subject.SabHost = "Test2";
|
|
||||||
Subject.SabHost.Should().Be("Test2");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
[Description("This test will use reflection to ensure each config property read/writes to a unique key")]
|
[Description("This test will use reflection to ensure each config property read/writes to a unique key")]
|
||||||
public void config_properties_should_write_and_read_using_same_key()
|
public void config_properties_should_write_and_read_using_same_key()
|
||||||
|
|
|
@ -15,340 +15,166 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
|
|
||||||
public class AcceptableSizeSpecificationFixture : CoreTest<AcceptableSizeSpecification>
|
public class AcceptableSizeSpecificationFixture : CoreTest<AcceptableSizeSpecification>
|
||||||
{
|
{
|
||||||
|
private RemoteEpisode parseResultMultiSet;
|
||||||
private RemoteEpisode parseResultMulti;
|
private RemoteEpisode parseResultMulti;
|
||||||
private RemoteEpisode parseResultSingle;
|
private RemoteEpisode parseResultSingle;
|
||||||
private Series series30minutes;
|
private Series series;
|
||||||
private Series series60minutes;
|
|
||||||
private QualityDefinition qualityType;
|
private QualityDefinition qualityType;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
|
series = Builder<Series>.CreateNew()
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
parseResultMultiSet = new RemoteEpisode
|
||||||
|
{
|
||||||
|
Series = series,
|
||||||
|
Release = new ReleaseInfo(),
|
||||||
|
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.SDTV, true) },
|
||||||
|
Episodes = new List<Episode> { new Episode(), new Episode(), new Episode(), new Episode(), new Episode(), new Episode() }
|
||||||
|
};
|
||||||
|
|
||||||
parseResultMulti = new RemoteEpisode
|
parseResultMulti = new RemoteEpisode
|
||||||
{
|
{
|
||||||
Release = new ReleaseInfo(),
|
Series = series,
|
||||||
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.SDTV, true) },
|
Release = new ReleaseInfo(),
|
||||||
Episodes = new List<Episode> { new Episode(), new Episode() }
|
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.SDTV, true) },
|
||||||
};
|
Episodes = new List<Episode> { new Episode(), new Episode() }
|
||||||
|
};
|
||||||
|
|
||||||
parseResultSingle = new RemoteEpisode
|
parseResultSingle = new RemoteEpisode
|
||||||
{
|
{
|
||||||
|
Series = series,
|
||||||
Release = new ReleaseInfo(),
|
Release = new ReleaseInfo(),
|
||||||
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.SDTV, true) },
|
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.SDTV, true) },
|
||||||
Episodes = new List<Episode> { new Episode() }
|
Episodes = new List<Episode> { new Episode() }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
series30minutes = Builder<Series>.CreateNew()
|
|
||||||
.With(c => c.Runtime = 30)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
series60minutes = Builder<Series>.CreateNew()
|
|
||||||
.With(c => c.Runtime = 60)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
qualityType = Builder<QualityDefinition>.CreateNew()
|
qualityType = Builder<QualityDefinition>.CreateNew()
|
||||||
.With(q => q.MinSize = 0)
|
.With(q => q.MinSize = 2)
|
||||||
.With(q => q.MaxSize = 10)
|
.With(q => q.MaxSize = 10)
|
||||||
.With(q => q.Quality = Quality.SDTV)
|
.With(q => q.Quality = Quality.SDTV)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
private void GivenLastEpisode()
|
||||||
public void IsAcceptableSize_true_single_episode_not_first_or_last_30_minute()
|
|
||||||
{
|
{
|
||||||
parseResultSingle.Series = series30minutes;
|
|
||||||
parseResultSingle.Release.Size = 184572800;
|
|
||||||
|
|
||||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
|
||||||
.Returns(false);
|
|
||||||
|
|
||||||
|
|
||||||
bool result = Subject.IsSatisfiedBy(parseResultSingle, null);
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void IsAcceptableSize_true_single_episode_not_first_or_last_60_minute()
|
|
||||||
{
|
|
||||||
parseResultSingle.Series = series60minutes;
|
|
||||||
parseResultSingle.Release.Size = 368572800;
|
|
||||||
|
|
||||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
|
||||||
.Returns(false);
|
|
||||||
|
|
||||||
|
|
||||||
bool result = Subject.IsSatisfiedBy(parseResultSingle, null);
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void IsAcceptableSize_false_single_episode_not_first_or_last_30_minute()
|
|
||||||
{
|
|
||||||
parseResultSingle.Series = series30minutes;
|
|
||||||
parseResultSingle.Release.Size = 1.Gigabytes();
|
|
||||||
|
|
||||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
|
||||||
.Returns(false);
|
|
||||||
|
|
||||||
|
|
||||||
bool result = Subject.IsSatisfiedBy(parseResultSingle, null);
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void IsAcceptableSize_false_single_episode_not_first_or_last_60_minute()
|
|
||||||
{
|
|
||||||
parseResultSingle.Series = series60minutes;
|
|
||||||
parseResultSingle.Release.Size = 1.Gigabytes();
|
|
||||||
|
|
||||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
|
||||||
.Returns(false);
|
|
||||||
|
|
||||||
bool result = Subject.IsSatisfiedBy(parseResultSingle, null);
|
|
||||||
|
|
||||||
result.Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void IsAcceptableSize_true_multi_episode_not_first_or_last_30_minute()
|
|
||||||
{
|
|
||||||
parseResultMulti.Series = series30minutes;
|
|
||||||
parseResultMulti.Release.Size = 184572800;
|
|
||||||
|
|
||||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
|
||||||
.Returns(false);
|
|
||||||
|
|
||||||
|
|
||||||
bool result = Subject.IsSatisfiedBy(parseResultMulti, null);
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void IsAcceptableSize_true_multi_episode_not_first_or_last_60_minute()
|
|
||||||
{
|
|
||||||
parseResultMulti.Series = series60minutes;
|
|
||||||
parseResultMulti.Release.Size = 368572800;
|
|
||||||
|
|
||||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
|
||||||
.Returns(false);
|
|
||||||
|
|
||||||
|
|
||||||
bool result = Subject.IsSatisfiedBy(parseResultMulti, null);
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void IsAcceptableSize_false_multi_episode_not_first_or_last_30_minute()
|
|
||||||
{
|
|
||||||
parseResultMulti.Series = series30minutes;
|
|
||||||
parseResultMulti.Release.Size = 1.Gigabytes();
|
|
||||||
|
|
||||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
|
||||||
.Returns(false);
|
|
||||||
|
|
||||||
|
|
||||||
bool result = Subject.IsSatisfiedBy(parseResultMulti, null);
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void IsAcceptableSize_false_multi_episode_not_first_or_last_60_minute()
|
|
||||||
{
|
|
||||||
parseResultMulti.Series = series60minutes;
|
|
||||||
parseResultMulti.Release.Size = 10.Gigabytes();
|
|
||||||
|
|
||||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
|
||||||
.Returns(false);
|
|
||||||
|
|
||||||
|
|
||||||
bool result = Subject.IsSatisfiedBy(parseResultMulti, null);
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void IsAcceptableSize_true_single_episode_first_30_minute()
|
|
||||||
{
|
|
||||||
parseResultSingle.Series = series30minutes;
|
|
||||||
parseResultSingle.Release.Size = 184572800;
|
|
||||||
|
|
||||||
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>()))
|
||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
|
|
||||||
bool result = Subject.IsSatisfiedBy(parseResultSingle, null);
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().BeTrue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[TestCase(30, 50, false)]
|
||||||
public void IsAcceptableSize_true_single_episode_first_60_minute()
|
[TestCase(30, 250, true)]
|
||||||
{
|
[TestCase(30, 500, false)]
|
||||||
parseResultSingle.Series = series60minutes;
|
[TestCase(60, 100, false)]
|
||||||
parseResultSingle.Release.Size = 368572800;
|
[TestCase(60, 500, true)]
|
||||||
|
[TestCase(60, 1000, false)]
|
||||||
|
public void single_episode(int runtime, int sizeInMegaBytes, bool expectedResult)
|
||||||
|
{
|
||||||
|
series.Runtime = runtime;
|
||||||
|
parseResultSingle.Series = series;
|
||||||
|
parseResultSingle.Release.Size = sizeInMegaBytes.Megabytes();
|
||||||
|
|
||||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
Subject.IsSatisfiedBy(parseResultSingle, null).Should().Be(expectedResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(30, 500, true)]
|
||||||
|
[TestCase(30, 1000, false)]
|
||||||
|
[TestCase(60, 1000, true)]
|
||||||
|
[TestCase(60, 2000, false)]
|
||||||
|
public void single_episode_first_or_last(int runtime, int sizeInMegaBytes, bool expectedResult)
|
||||||
|
{
|
||||||
|
GivenLastEpisode();
|
||||||
|
|
||||||
|
series.Runtime = runtime;
|
||||||
|
parseResultSingle.Series = series;
|
||||||
|
parseResultSingle.Release.Size = sizeInMegaBytes.Megabytes();
|
||||||
|
|
||||||
|
Subject.IsSatisfiedBy(parseResultSingle, null).Should().Be(expectedResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(30, 50 * 2, false)]
|
||||||
|
[TestCase(30, 250 * 2, true)]
|
||||||
|
[TestCase(30, 500 * 2, false)]
|
||||||
|
[TestCase(60, 100 * 2, false)]
|
||||||
|
[TestCase(60, 500 * 2, true)]
|
||||||
|
[TestCase(60, 1000 * 2, false)]
|
||||||
|
public void multi_episode(int runtime, int sizeInMegaBytes, bool expectedResult)
|
||||||
|
{
|
||||||
|
series.Runtime = runtime;
|
||||||
|
parseResultMulti.Series = series;
|
||||||
|
parseResultMulti.Release.Size = sizeInMegaBytes.Megabytes();
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
Mocker.GetMock<IEpisodeService>().Setup(
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||||
.Returns(true);
|
.Returns(false);
|
||||||
|
|
||||||
|
Subject.IsSatisfiedBy(parseResultMulti, null).Should().Be(expectedResult);
|
||||||
bool result = Subject.IsSatisfiedBy(parseResultSingle, null);
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().BeTrue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[TestCase(30, 50 * 6, false)]
|
||||||
public void IsAcceptableSize_false_single_episode_first_30_minute()
|
[TestCase(30, 250 * 6, true)]
|
||||||
|
[TestCase(30, 500 * 6, false)]
|
||||||
|
[TestCase(60, 100 * 6, false)]
|
||||||
|
[TestCase(60, 500 * 6, true)]
|
||||||
|
[TestCase(60, 1000 * 6, false)]
|
||||||
|
public void multiset_episode(int runtime, int sizeInMegaBytes, bool expectedResult)
|
||||||
{
|
{
|
||||||
parseResultSingle.Series = series30minutes;
|
series.Runtime = runtime;
|
||||||
parseResultSingle.Release.Size = 1.Gigabytes();
|
parseResultMultiSet.Series = series;
|
||||||
|
parseResultMultiSet.Release.Size = sizeInMegaBytes.Megabytes();
|
||||||
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>()))
|
||||||
.Returns(true);
|
.Returns(false);
|
||||||
|
|
||||||
|
Subject.IsSatisfiedBy(parseResultMultiSet, null).Should().Be(expectedResult);
|
||||||
bool result = Subject.IsSatisfiedBy(parseResultSingle, null);
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().BeFalse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void IsAcceptableSize_false_single_episode_first_60_minute()
|
public void should_return_true_if_unlimited_30_minute()
|
||||||
{
|
{
|
||||||
|
GivenLastEpisode();
|
||||||
|
|
||||||
|
series.Runtime = 30;
|
||||||
parseResultSingle.Series = series60minutes;
|
parseResultSingle.Series = series;
|
||||||
parseResultSingle.Release.Size = 10.Gigabytes();
|
|
||||||
|
|
||||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
|
||||||
.Returns(true);
|
|
||||||
|
|
||||||
|
|
||||||
bool result = Subject.IsSatisfiedBy(parseResultSingle, null);
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void IsAcceptableSize_true_unlimited_30_minute()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
parseResultSingle.Series = series30minutes;
|
|
||||||
parseResultSingle.Release.Size = 18457280000;
|
parseResultSingle.Release.Size = 18457280000;
|
||||||
qualityType.MaxSize = 0;
|
qualityType.MaxSize = 0;
|
||||||
|
|
||||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
Subject.IsSatisfiedBy(parseResultSingle, null).Should().BeTrue();
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
|
||||||
.Returns(true);
|
|
||||||
|
|
||||||
|
|
||||||
bool result = Subject.IsSatisfiedBy(parseResultSingle, null);
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().BeTrue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void IsAcceptableSize_true_unlimited_60_minute()
|
public void should_return_true_if_unlimited_60_minute()
|
||||||
{
|
{
|
||||||
|
GivenLastEpisode();
|
||||||
|
|
||||||
|
series.Runtime = 60;
|
||||||
parseResultSingle.Series = series60minutes;
|
parseResultSingle.Series = series;
|
||||||
parseResultSingle.Release.Size = 36857280000;
|
parseResultSingle.Release.Size = 36857280000;
|
||||||
qualityType.MaxSize = 0;
|
qualityType.MaxSize = 0;
|
||||||
|
|
||||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
Subject.IsSatisfiedBy(parseResultSingle, null).Should().BeTrue();;
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
|
||||||
.Returns(true);
|
|
||||||
|
|
||||||
|
|
||||||
bool result = Subject.IsSatisfiedBy(parseResultSingle, null);
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().BeTrue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void IsAcceptableSize_should_treat_daily_series_as_single_episode()
|
public void should_treat_daily_series_as_single_episode()
|
||||||
{
|
{
|
||||||
|
GivenLastEpisode();
|
||||||
|
|
||||||
parseResultSingle.Series = series60minutes;
|
series.Runtime = 60;
|
||||||
|
parseResultSingle.Series = series;
|
||||||
parseResultSingle.Series.SeriesType = SeriesTypes.Daily;
|
parseResultSingle.Series.SeriesType = SeriesTypes.Daily;
|
||||||
|
|
||||||
parseResultSingle.Release.Size = 300.Megabytes();
|
parseResultSingle.Release.Size = 300.Megabytes();
|
||||||
|
|
||||||
qualityType.MaxSize = (int)600.Megabytes();
|
qualityType.MaxSize = 10;
|
||||||
|
|
||||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
Subject.IsSatisfiedBy(parseResultSingle, null).Should().BeTrue();
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(
|
|
||||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
|
||||||
.Returns(true);
|
|
||||||
|
|
||||||
|
|
||||||
bool result = Subject.IsSatisfiedBy(parseResultSingle, null);
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().BeTrue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -362,9 +188,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
Subject.IsSatisfiedBy(parseResult, null).Should().BeTrue();
|
Subject.IsSatisfiedBy(parseResult, null).Should().BeTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_always_return_false_if_unknow()
|
public void should_always_return_false_if_unknown()
|
||||||
{
|
{
|
||||||
var parseResult = new RemoteEpisode
|
var parseResult = new RemoteEpisode
|
||||||
{
|
{
|
||||||
|
@ -373,7 +198,6 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
|
|
||||||
Subject.IsSatisfiedBy(parseResult, null).Should().BeFalse();
|
Subject.IsSatisfiedBy(parseResult, null).Should().BeFalse();
|
||||||
|
|
||||||
|
|
||||||
Mocker.GetMock<IQualityDefinitionService>().Verify(c => c.Get(It.IsAny<Quality>()), Times.Never());
|
Mocker.GetMock<IQualityDefinitionService>().Verify(c => c.Get(It.IsAny<Quality>()), Times.Never());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
|
|
||||||
private void GivenSpecifications(params Mock<IDecisionEngineSpecification>[] mocks)
|
private void GivenSpecifications(params Mock<IDecisionEngineSpecification>[] mocks)
|
||||||
{
|
{
|
||||||
Mocker.SetConstant<IEnumerable<IRejectWithReason>>(mocks.Select(c => c.Object));
|
Mocker.SetConstant<IEnumerable<IDecisionEngineSpecification>>(mocks.Select(c => c.Object));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
|
@ -83,7 +83,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
private void GivenSabnzbdDownloadClient()
|
private void GivenSabnzbdDownloadClient()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IProvideDownloadClient>()
|
Mocker.GetMock<IProvideDownloadClient>()
|
||||||
.Setup(c => c.GetDownloadClient()).Returns(Mocker.Resolve<SabnzbdClient>());
|
.Setup(c => c.GetDownloadClient()).Returns(Mocker.Resolve<Sabnzbd>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenMostRecentForEpisode(HistoryEventType eventType)
|
private void GivenMostRecentForEpisode(HistoryEventType eventType)
|
||||||
|
|
|
@ -56,9 +56,6 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
Mocker.GetMock<IProvideDownloadClient>()
|
Mocker.GetMock<IProvideDownloadClient>()
|
||||||
.Setup(s => s.GetDownloadClient())
|
.Setup(s => s.GetDownloadClient())
|
||||||
.Returns(_downloadClient.Object);
|
.Returns(_downloadClient.Object);
|
||||||
|
|
||||||
_downloadClient.SetupGet(s => s.IsConfigured)
|
|
||||||
.Returns(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenEmptyQueue()
|
private void GivenEmptyQueue()
|
||||||
|
|
|
@ -20,65 +20,62 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
{
|
{
|
||||||
parseResult = new RemoteEpisode
|
parseResult = new RemoteEpisode
|
||||||
{
|
{
|
||||||
Release = new ReleaseInfo
|
Release = new ReleaseInfo()
|
||||||
{
|
|
||||||
PublishDate = DateTime.Now.AddDays(-100)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WithUnlimitedRetention()
|
private void WithRetention(int days)
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IConfigService>().SetupGet(c => c.Retention).Returns(0);
|
Mocker.GetMock<IConfigService>().SetupGet(c => c.Retention).Returns(days);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WithLongRetention()
|
private void WithAge(int days)
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IConfigService>().SetupGet(c => c.Retention).Returns(1000);
|
parseResult.Release.PublishDate = DateTime.Now.AddDays(-days);
|
||||||
}
|
|
||||||
|
|
||||||
private void WithShortRetention()
|
|
||||||
{
|
|
||||||
Mocker.GetMock<IConfigService>().SetupGet(c => c.Retention).Returns(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WithEqualRetention()
|
|
||||||
{
|
|
||||||
Mocker.GetMock<IConfigService>().SetupGet(c => c.Retention).Returns(100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void unlimited_retention_should_return_true()
|
public void should_return_true_when_retention_is_set_to_zero()
|
||||||
{
|
{
|
||||||
WithUnlimitedRetention();
|
WithRetention(0);
|
||||||
|
WithAge(100);
|
||||||
|
|
||||||
Subject.IsSatisfiedBy(parseResult, null).Should().BeTrue();
|
Subject.IsSatisfiedBy(parseResult, null).Should().BeTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void longer_retention_should_return_true()
|
public void should_return_true_when_release_if_younger_than_retention()
|
||||||
{
|
{
|
||||||
WithLongRetention();
|
WithRetention(1000);
|
||||||
|
WithAge(100);
|
||||||
|
|
||||||
Subject.IsSatisfiedBy(parseResult, null).Should().BeTrue();
|
Subject.IsSatisfiedBy(parseResult, null).Should().BeTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void equal_retention_should_return_true()
|
public void should_return_true_when_release_and_retention_are_the_same()
|
||||||
{
|
{
|
||||||
WithEqualRetention();
|
WithRetention(100);
|
||||||
|
WithAge(100);
|
||||||
|
|
||||||
Subject.IsSatisfiedBy(parseResult, null).Should().BeTrue();
|
Subject.IsSatisfiedBy(parseResult, null).Should().BeTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void shorter_retention_should_return_false()
|
public void should_return_false_when_old_than_retention()
|
||||||
{
|
{
|
||||||
WithShortRetention();
|
WithRetention(10);
|
||||||
|
WithAge(100);
|
||||||
|
|
||||||
Subject.IsSatisfiedBy(parseResult, null).Should().BeFalse();
|
Subject.IsSatisfiedBy(parseResult, null).Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void zeroDay_report_should_return_true()
|
public void should_return_true_if_release_came_out_today_and_retention_is_zero()
|
||||||
{
|
{
|
||||||
WithUnlimitedRetention();
|
WithRetention(0);
|
||||||
|
WithAge(100);
|
||||||
|
|
||||||
Subject.IsSatisfiedBy(parseResult, null).Should().BeTrue();
|
Subject.IsSatisfiedBy(parseResult, null).Should().BeTrue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,9 @@ using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Download.Clients;
|
using NzbDrone.Core.Download.Clients;
|
||||||
|
using NzbDrone.Core.Download.Clients.Blackhole;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
|
@ -13,7 +14,7 @@ using NzbDrone.Test.Common;
|
||||||
namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class BlackholeProviderFixture : CoreTest<BlackholeProvider>
|
public class BlackholeProviderFixture : CoreTest<Blackhole>
|
||||||
{
|
{
|
||||||
private const string _nzbUrl = "http://www.nzbs.com/url";
|
private const string _nzbUrl = "http://www.nzbs.com/url";
|
||||||
private const string _title = "some_nzb_title";
|
private const string _title = "some_nzb_title";
|
||||||
|
@ -27,13 +28,16 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||||
_blackHoleFolder = @"c:\nzb\blackhole\".AsOsAgnostic();
|
_blackHoleFolder = @"c:\nzb\blackhole\".AsOsAgnostic();
|
||||||
_nzbPath = @"c:\nzb\blackhole\some_nzb_title.nzb".AsOsAgnostic();
|
_nzbPath = @"c:\nzb\blackhole\some_nzb_title.nzb".AsOsAgnostic();
|
||||||
|
|
||||||
|
|
||||||
Mocker.GetMock<IConfigService>().SetupGet(c => c.BlackholeFolder).Returns(_blackHoleFolder);
|
|
||||||
|
|
||||||
_remoteEpisode = new RemoteEpisode();
|
_remoteEpisode = new RemoteEpisode();
|
||||||
_remoteEpisode.Release = new ReleaseInfo();
|
_remoteEpisode.Release = new ReleaseInfo();
|
||||||
_remoteEpisode.Release.Title = _title;
|
_remoteEpisode.Release.Title = _title;
|
||||||
_remoteEpisode.Release.DownloadUrl = _nzbUrl;
|
_remoteEpisode.Release.DownloadUrl = _nzbUrl;
|
||||||
|
|
||||||
|
Subject.Definition = new DownloadClientDefinition();
|
||||||
|
Subject.Definition.Settings = new FolderSettings
|
||||||
|
{
|
||||||
|
Folder = _blackHoleFolder
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WithExistingFile()
|
private void WithExistingFile()
|
||||||
|
|
|
@ -3,17 +3,15 @@ using System.Linq;
|
||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Common.Serializer;
|
|
||||||
using NzbDrone.Core.Configuration;
|
|
||||||
using NzbDrone.Core.Download.Clients.Nzbget;
|
using NzbDrone.Core.Download.Clients.Nzbget;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
|
namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests
|
||||||
{
|
{
|
||||||
public class DownloadNzbFixture : CoreTest
|
public class DownloadNzbFixture : CoreTest<Nzbget>
|
||||||
{
|
{
|
||||||
private const string _url = "http://www.nzbdrone.com";
|
private const string _url = "http://www.nzbdrone.com";
|
||||||
private const string _title = "30.Rock.S01E01.Pilot.720p.hdtv";
|
private const string _title = "30.Rock.S01E01.Pilot.720p.hdtv";
|
||||||
|
@ -32,6 +30,17 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
|
||||||
.With(e => e.AirDate = DateTime.Today.ToString(Episode.AIR_DATE_FORMAT))
|
.With(e => e.AirDate = DateTime.Today.ToString(Episode.AIR_DATE_FORMAT))
|
||||||
.Build()
|
.Build()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
Subject.Definition = new DownloadClientDefinition();
|
||||||
|
Subject.Definition.Settings = new NzbgetSettings
|
||||||
|
{
|
||||||
|
Host = "localhost",
|
||||||
|
Port = 6789,
|
||||||
|
Username = "nzbget",
|
||||||
|
Password = "pass",
|
||||||
|
TvCategory = "tv",
|
||||||
|
RecentTvPriority = (int)NzbgetPriority.High
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -39,14 +48,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
|
||||||
{
|
{
|
||||||
var p = new object[] {"30.Rock.S01E01.Pilot.720p.hdtv.nzb", "TV", 50, false, "http://www.nzbdrone.com"};
|
var p = new object[] {"30.Rock.S01E01.Pilot.720p.hdtv.nzb", "TV", 50, false, "http://www.nzbdrone.com"};
|
||||||
|
|
||||||
Mocker.GetMock<INzbGetCommunicationProxy>()
|
Mocker.GetMock<INzbgetProxy>()
|
||||||
.Setup(s => s.AddNzb(p))
|
.Setup(s => s.AddNzb(It.IsAny<NzbgetSettings>(), p))
|
||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
Mocker.Resolve<NzbgetClient>().DownloadNzb(_remoteEpisode);
|
Subject.DownloadNzb(_remoteEpisode);
|
||||||
|
|
||||||
Mocker.GetMock<INzbGetCommunicationProxy>()
|
Mocker.GetMock<INzbgetProxy>()
|
||||||
.Verify(v => v.AddNzb(It.IsAny<object []>()), Times.Once());
|
.Verify(v => v.AddNzb(It.IsAny<NzbgetSettings>(), It.IsAny<object []>()), Times.Once());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,40 +5,52 @@ using FizzWare.NBuilder;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Download.Clients.Nzbget;
|
using NzbDrone.Core.Download.Clients.Nzbget;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
|
namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests
|
||||||
{
|
{
|
||||||
public class QueueFixture : CoreTest<NzbgetClient>
|
public class QueueFixture : CoreTest<Nzbget>
|
||||||
{
|
{
|
||||||
private List<NzbGetQueueItem> _queue;
|
private List<NzbgetQueueItem> _queue;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_queue = Builder<NzbGetQueueItem>.CreateListOfSize(5)
|
_queue = Builder<NzbgetQueueItem>.CreateListOfSize(5)
|
||||||
.All()
|
.All()
|
||||||
.With(q => q.NzbName = "30.Rock.S01E01.Pilot.720p.hdtv.nzb")
|
.With(q => q.NzbName = "30.Rock.S01E01.Pilot.720p.hdtv.nzb")
|
||||||
.Build()
|
.Build()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
Subject.Definition = new DownloadClientDefinition();
|
||||||
|
Subject.Definition.Settings = new NzbgetSettings
|
||||||
|
{
|
||||||
|
Host = "localhost",
|
||||||
|
Port = 6789,
|
||||||
|
Username = "nzbget",
|
||||||
|
Password = "pass",
|
||||||
|
TvCategory = "tv",
|
||||||
|
RecentTvPriority = (int)NzbgetPriority.High
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WithFullQueue()
|
private void WithFullQueue()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<INzbGetCommunicationProxy>()
|
Mocker.GetMock<INzbgetProxy>()
|
||||||
.Setup(s => s.GetQueue())
|
.Setup(s => s.GetQueue(It.IsAny<NzbgetSettings>()))
|
||||||
.Returns(_queue);
|
.Returns(_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WithEmptyQueue()
|
private void WithEmptyQueue()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<INzbGetCommunicationProxy>()
|
Mocker.GetMock<INzbgetProxy>()
|
||||||
.Setup(s => s.GetQueue())
|
.Setup(s => s.GetQueue(It.IsAny<NzbgetSettings>()))
|
||||||
.Returns(new List<NzbGetQueueItem>());
|
.Returns(new List<NzbgetQueueItem>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
|
@ -6,7 +6,9 @@ using NUnit.Framework;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Download.Clients;
|
using NzbDrone.Core.Download.Clients;
|
||||||
|
using NzbDrone.Core.Download.Clients.Pneumatic;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
|
@ -14,7 +16,7 @@ using NzbDrone.Test.Common;
|
||||||
namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class PneumaticProviderFixture : CoreTest<PneumaticClient>
|
public class PneumaticProviderFixture : CoreTest<Pneumatic>
|
||||||
{
|
{
|
||||||
private const string _nzbUrl = "http://www.nzbs.com/url";
|
private const string _nzbUrl = "http://www.nzbs.com/url";
|
||||||
private const string _title = "30.Rock.S01E05.hdtv.xvid-LoL";
|
private const string _title = "30.Rock.S01E05.hdtv.xvid-LoL";
|
||||||
|
@ -31,7 +33,6 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||||
_nzbPath = Path.Combine(_pneumaticFolder, _title + ".nzb").AsOsAgnostic();
|
_nzbPath = Path.Combine(_pneumaticFolder, _title + ".nzb").AsOsAgnostic();
|
||||||
_sabDrop = @"d:\unsorted tv\".AsOsAgnostic();
|
_sabDrop = @"d:\unsorted tv\".AsOsAgnostic();
|
||||||
|
|
||||||
Mocker.GetMock<IConfigService>().SetupGet(c => c.PneumaticFolder).Returns(_pneumaticFolder);
|
|
||||||
Mocker.GetMock<IConfigService>().SetupGet(c => c.DownloadedEpisodesFolder).Returns(_sabDrop);
|
Mocker.GetMock<IConfigService>().SetupGet(c => c.DownloadedEpisodesFolder).Returns(_sabDrop);
|
||||||
|
|
||||||
_remoteEpisode = new RemoteEpisode();
|
_remoteEpisode = new RemoteEpisode();
|
||||||
|
@ -41,6 +42,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||||
|
|
||||||
_remoteEpisode.ParsedEpisodeInfo = new ParsedEpisodeInfo();
|
_remoteEpisode.ParsedEpisodeInfo = new ParsedEpisodeInfo();
|
||||||
_remoteEpisode.ParsedEpisodeInfo.FullSeason = false;
|
_remoteEpisode.ParsedEpisodeInfo.FullSeason = false;
|
||||||
|
|
||||||
|
Subject.Definition = new DownloadClientDefinition();
|
||||||
|
Subject.Definition.Settings = new FolderSettings
|
||||||
|
{
|
||||||
|
Folder = _pneumaticFolder
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WithExistingFile()
|
private void WithExistingFile()
|
||||||
|
|
|
@ -1,191 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using FizzWare.NBuilder;
|
|
||||||
using FluentAssertions;
|
|
||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Common;
|
|
||||||
using NzbDrone.Core.Configuration;
|
|
||||||
using NzbDrone.Core.Download.Clients.Sabnzbd;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
using NzbDrone.Core.Test.Framework;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
|
|
||||||
public class SabProviderFixture : CoreTest<SabnzbdClient>
|
|
||||||
{
|
|
||||||
private const string URL = "http://www.nzbclub.com/nzb_download.aspx?mid=1950232";
|
|
||||||
private const string TITLE = "My Series Name - 5x2-5x3 - My title [Bluray720p] [Proper]";
|
|
||||||
private RemoteEpisode _remoteEpisode;
|
|
||||||
|
|
||||||
[SetUp]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
var fakeConfig = Mocker.GetMock<IConfigService>();
|
|
||||||
|
|
||||||
fakeConfig.SetupGet(c => c.SabHost).Returns("192.168.5.55");
|
|
||||||
fakeConfig.SetupGet(c => c.SabPort).Returns(2222);
|
|
||||||
fakeConfig.SetupGet(c => c.SabApiKey).Returns("5c770e3197e4fe763423ee7c392c25d1");
|
|
||||||
fakeConfig.SetupGet(c => c.SabUsername).Returns("admin");
|
|
||||||
fakeConfig.SetupGet(c => c.SabPassword).Returns("pass");
|
|
||||||
fakeConfig.SetupGet(c => c.SabTvCategory).Returns("tv");
|
|
||||||
|
|
||||||
_remoteEpisode = new RemoteEpisode();
|
|
||||||
_remoteEpisode.Release = new ReleaseInfo();
|
|
||||||
_remoteEpisode.Release.Title = TITLE;
|
|
||||||
_remoteEpisode.Release.DownloadUrl = URL;
|
|
||||||
|
|
||||||
_remoteEpisode.Episodes = Builder<Episode>.CreateListOfSize(1)
|
|
||||||
.All()
|
|
||||||
.With(e => e.AirDate = DateTime.Today.ToString(Episode.AIR_DATE_FORMAT))
|
|
||||||
.Build()
|
|
||||||
.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_be_able_to_get_categories_when_config_is_passed_in()
|
|
||||||
{
|
|
||||||
|
|
||||||
const string host = "192.168.5.22";
|
|
||||||
const int port = 1111;
|
|
||||||
const string apikey = "5c770e3197e4fe763423ee7c392c25d2";
|
|
||||||
const string username = "admin2";
|
|
||||||
const string password = "pass2";
|
|
||||||
|
|
||||||
Mocker.GetMock<IHttpProvider>(MockBehavior.Strict)
|
|
||||||
.Setup(s => s.DownloadString("http://192.168.5.22:1111/api?mode=get_cats&output=json&apikey=5c770e3197e4fe763423ee7c392c25d2&ma_username=admin2&ma_password=pass2"))
|
|
||||||
.Returns(ReadAllText("Files", "Categories_json.txt"));
|
|
||||||
|
|
||||||
var result = Subject.GetCategories(host, port, apikey, username, password);
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().NotBeNull();
|
|
||||||
result.categories.Should().NotBeEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_be_able_to_get_categories_using_config()
|
|
||||||
{
|
|
||||||
Mocker.GetMock<IHttpProvider>(MockBehavior.Strict)
|
|
||||||
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=get_cats&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
|
|
||||||
.Returns(ReadAllText("Files", "Categories_json.txt"));
|
|
||||||
|
|
||||||
|
|
||||||
var result = Subject.GetCategories();
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().NotBeNull();
|
|
||||||
result.categories.Should().NotBeEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void GetHistory_should_return_a_list_with_items_when_the_history_has_items()
|
|
||||||
{
|
|
||||||
Mocker.GetMock<IHttpProvider>()
|
|
||||||
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=history&output=json&start=0&limit=0&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
|
|
||||||
.Returns(ReadAllText("Files", "History.txt"));
|
|
||||||
|
|
||||||
|
|
||||||
var result = Subject.GetHistory();
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().HaveCount(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void GetHistory_should_return_an_empty_list_when_the_queue_is_empty()
|
|
||||||
{
|
|
||||||
Mocker.GetMock<IHttpProvider>()
|
|
||||||
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=history&output=json&start=0&limit=0&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
|
|
||||||
.Returns(ReadAllText("Files", "HistoryEmpty.txt"));
|
|
||||||
|
|
||||||
|
|
||||||
var result = Subject.GetHistory();
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().BeEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void GetHistory_should_return_an_empty_list_when_there_is_an_error_getting_the_queue()
|
|
||||||
{
|
|
||||||
Mocker.GetMock<IHttpProvider>()
|
|
||||||
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=history&output=json&start=0&limit=0&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
|
|
||||||
.Returns(ReadAllText("Files", "JsonError.txt"));
|
|
||||||
|
|
||||||
|
|
||||||
Assert.Throws<ApplicationException>(() => Subject.GetHistory(), "API Key Incorrect");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void GetVersion_should_return_the_version_using_passed_in_values()
|
|
||||||
{
|
|
||||||
var response = "{ \"version\": \"0.6.9\" }";
|
|
||||||
|
|
||||||
Mocker.GetMock<IHttpProvider>()
|
|
||||||
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=version&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
|
|
||||||
.Returns(response);
|
|
||||||
|
|
||||||
|
|
||||||
var result = Subject.GetVersion("192.168.5.55", 2222, "5c770e3197e4fe763423ee7c392c25d1", "admin", "pass");
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().NotBeNull();
|
|
||||||
result.Version.Should().Be("0.6.9");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void GetVersion_should_return_the_version_using_saved_values()
|
|
||||||
{
|
|
||||||
var response = "{ \"version\": \"0.6.9\" }";
|
|
||||||
|
|
||||||
Mocker.GetMock<IHttpProvider>()
|
|
||||||
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=version&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
|
|
||||||
.Returns(response);
|
|
||||||
|
|
||||||
|
|
||||||
var result = Subject.GetVersion();
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().NotBeNull();
|
|
||||||
result.Version.Should().Be("0.6.9");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Test_should_return_version_as_a_string()
|
|
||||||
{
|
|
||||||
const string response = "{ \"version\": \"0.6.9\" }";
|
|
||||||
|
|
||||||
Mocker.GetMock<IHttpProvider>()
|
|
||||||
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=version&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
|
|
||||||
.Returns(response);
|
|
||||||
|
|
||||||
|
|
||||||
var result = Subject.Test("192.168.5.55", 2222, "5c770e3197e4fe763423ee7c392c25d1", "admin", "pass");
|
|
||||||
|
|
||||||
|
|
||||||
result.Should().Be("0.6.9");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void downloadNzb_should_use_sabRecentTvPriority_when_recentEpisode_is_true()
|
|
||||||
{
|
|
||||||
Mocker.GetMock<IConfigService>()
|
|
||||||
.SetupGet(s => s.SabRecentTvPriority)
|
|
||||||
.Returns(SabPriorityType.High);
|
|
||||||
|
|
||||||
Mocker.GetMock<ISabCommunicationProxy>()
|
|
||||||
.Setup(s => s.DownloadNzb(It.IsAny<Stream>(), It.IsAny<String>(), It.IsAny<String>(), (int)SabPriorityType.High))
|
|
||||||
.Returns(new SabAddResponse());
|
|
||||||
|
|
||||||
Subject.DownloadNzb(_remoteEpisode);
|
|
||||||
|
|
||||||
Mocker.GetMock<ISabCommunicationProxy>()
|
|
||||||
.Verify(v => v.DownloadNzb(It.IsAny<Stream>(), It.IsAny<String>(), It.IsAny<String>(), (int)SabPriorityType.High), Times.Once());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
|
using NzbDrone.Core.Download.Clients.Sabnzbd;
|
||||||
|
using NzbDrone.Core.Download.Clients.Sabnzbd.Responses;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class SabnzbdFixture : CoreTest<Sabnzbd>
|
||||||
|
{
|
||||||
|
private const string URL = "http://www.nzbclub.com/nzb_download.aspx?mid=1950232";
|
||||||
|
private const string TITLE = "My Series Name - 5x2-5x3 - My title [Bluray720p] [Proper]";
|
||||||
|
private RemoteEpisode _remoteEpisode;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_remoteEpisode = new RemoteEpisode();
|
||||||
|
_remoteEpisode.Release = new ReleaseInfo();
|
||||||
|
_remoteEpisode.Release.Title = TITLE;
|
||||||
|
_remoteEpisode.Release.DownloadUrl = URL;
|
||||||
|
|
||||||
|
_remoteEpisode.Episodes = Builder<Episode>.CreateListOfSize(1)
|
||||||
|
.All()
|
||||||
|
.With(e => e.AirDate = DateTime.Today.ToString(Episode.AIR_DATE_FORMAT))
|
||||||
|
.Build()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
Subject.Definition = new DownloadClientDefinition();
|
||||||
|
Subject.Definition.Settings = new SabnzbdSettings
|
||||||
|
{
|
||||||
|
Host = "192.168.5.55",
|
||||||
|
Port = 2222,
|
||||||
|
ApiKey = "5c770e3197e4fe763423ee7c392c25d1",
|
||||||
|
Username = "admin",
|
||||||
|
Password = "pass",
|
||||||
|
TvCategory = "tv",
|
||||||
|
RecentTvPriority = (int)SabnzbdPriority.High
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void downloadNzb_should_use_sabRecentTvPriority_when_recentEpisode_is_true()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<ISabnzbdProxy>()
|
||||||
|
.Setup(s => s.DownloadNzb(It.IsAny<Stream>(), It.IsAny<String>(), It.IsAny<String>(), (int)SabnzbdPriority.High, It.IsAny<SabnzbdSettings>()))
|
||||||
|
.Returns(new SabnzbdAddResponse());
|
||||||
|
|
||||||
|
Subject.DownloadNzb(_remoteEpisode);
|
||||||
|
|
||||||
|
Mocker.GetMock<ISabnzbdProxy>()
|
||||||
|
.Verify(v => v.DownloadNzb(It.IsAny<Stream>(), It.IsAny<String>(), It.IsAny<String>(), (int)SabnzbdPriority.High, It.IsAny<SabnzbdSettings>()), Times.Once());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
|
@ -33,9 +34,6 @@ namespace NzbDrone.Core.Test.Download
|
||||||
.With(c => c.Release = Builder<ReleaseInfo>.CreateNew().Build())
|
.With(c => c.Release = Builder<ReleaseInfo>.CreateNew().Build())
|
||||||
.With(c => c.Episodes = episodes)
|
.With(c => c.Episodes = episodes)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
|
||||||
Mocker.GetMock<IDownloadClient>().Setup(c => c.IsConfigured).Returns(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WithSuccessfulAdd()
|
private void WithSuccessfulAdd()
|
||||||
|
@ -85,7 +83,8 @@ namespace NzbDrone.Core.Test.Download
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_attempt_download_if_client_isnt_configure()
|
public void should_not_attempt_download_if_client_isnt_configure()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IDownloadClient>().Setup(c => c.IsConfigured).Returns(false);
|
Mocker.GetMock<IProvideDownloadClient>()
|
||||||
|
.Setup(c => c.GetDownloadClient()).Returns((IDownloadClient)null);
|
||||||
|
|
||||||
Subject.DownloadReport(_parseResult);
|
Subject.DownloadReport(_parseResult);
|
||||||
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
{
|
|
||||||
"categories":[
|
|
||||||
"*",
|
|
||||||
"anime",
|
|
||||||
"apps",
|
|
||||||
"books",
|
|
||||||
"consoles",
|
|
||||||
"ds-games",
|
|
||||||
"emulation",
|
|
||||||
"games",
|
|
||||||
"misc",
|
|
||||||
"movies",
|
|
||||||
"music",
|
|
||||||
"pda",
|
|
||||||
"resources",
|
|
||||||
"test",
|
|
||||||
"tv",
|
|
||||||
"tv-dvd",
|
|
||||||
"unknown",
|
|
||||||
"wii-games",
|
|
||||||
"xbox-dlc",
|
|
||||||
"xbox-xbla",
|
|
||||||
"xxx"
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,99 +0,0 @@
|
||||||
{
|
|
||||||
"history":{
|
|
||||||
"active_lang":"en",
|
|
||||||
"paused":false,
|
|
||||||
"session":"5c770e3197e4fe763423ee7c392c25d1",
|
|
||||||
"restart_req":false,
|
|
||||||
"power_options":true,
|
|
||||||
"slots":[
|
|
||||||
{
|
|
||||||
"action_line":"",
|
|
||||||
"show_details":"True",
|
|
||||||
"script_log":"",
|
|
||||||
"meta":null,
|
|
||||||
"fail_message":"",
|
|
||||||
"loaded":false,
|
|
||||||
"id":9858,
|
|
||||||
"size":"970 MB",
|
|
||||||
"category":"tv",
|
|
||||||
"pp":"D",
|
|
||||||
"retry":0,
|
|
||||||
"completeness":0,
|
|
||||||
"script":"None",
|
|
||||||
"nzb_name":"The.Mentalist.S04E12.720p.HDTV.x264-IMMERSE.nzb",
|
|
||||||
"download_time":524,
|
|
||||||
"storage":"C:\\ServerPool\\ServerFolders\\Unsorted TV\\The Mentalist - 4x12 - My Bloody Valentine [HDTV-720p]",
|
|
||||||
"status":"Completed",
|
|
||||||
"script_line":"",
|
|
||||||
"completed":1327033479,
|
|
||||||
"nzo_id":"SABnzbd_nzo_0crgis",
|
|
||||||
"downloaded":1016942445,
|
|
||||||
"report":"",
|
|
||||||
"path":"D:\\SABnzbd\\downloading\\The Mentalist - 4x12 - My Bloody Valentine [HDTV-720p]",
|
|
||||||
"postproc_time":24,
|
|
||||||
"name":"The Mentalist - 4x12 - My Bloody Valentine [HDTV-720p]",
|
|
||||||
"url":"",
|
|
||||||
"bytes":1016942445,
|
|
||||||
"url_info":"",
|
|
||||||
"stage_log":[
|
|
||||||
{
|
|
||||||
"name":"Download",
|
|
||||||
"actions":[
|
|
||||||
"Downloaded in 8 minutes 44 seconds at an average of 1.8 MB/s"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"Repair",
|
|
||||||
"actions":[
|
|
||||||
"[the.mentalist.s04e12.720p.hdtv.x264-immerse] Quick Check OK"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"Unpack",
|
|
||||||
"actions":[
|
|
||||||
"[the.mentalist.s04e12.720p.hdtv.x264-immerse] Unpacked 1 files/folders in 23 seconds"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"speed":"0 ",
|
|
||||||
"helpuri":"http://wiki.sabnzbd.org/",
|
|
||||||
"size":"0 B",
|
|
||||||
"uptime":"1d",
|
|
||||||
"total_size":"10.2 T",
|
|
||||||
"month_size":"445.7 G",
|
|
||||||
"week_size":"46.6 G",
|
|
||||||
"version":"0.6.9",
|
|
||||||
"new_rel_url":"http://sourceforge.net/projects/sabnzbdplus/files/sabnzbdplus/sabnzbd-0.6.14",
|
|
||||||
"diskspacetotal2":"9314.57",
|
|
||||||
"color_scheme":"gold",
|
|
||||||
"diskspacetotal1":"871.41",
|
|
||||||
"nt":true,
|
|
||||||
"status":"Idle",
|
|
||||||
"last_warning":"2012-01-19 23:58:01,736\nWARNING:\nAPI Key incorrect, Use the api key from Config->General in your 3rd party program:",
|
|
||||||
"have_warnings":"3",
|
|
||||||
"cache_art":"0",
|
|
||||||
"sizeleft":"0 B",
|
|
||||||
"finishaction":null,
|
|
||||||
"paused_all":false,
|
|
||||||
"cache_size":"0 B",
|
|
||||||
"new_release":"0.6.14",
|
|
||||||
"pause_int":"0",
|
|
||||||
"mbleft":"0.00",
|
|
||||||
"diskspace1":"869.82",
|
|
||||||
"darwin":false,
|
|
||||||
"timeleft":"0:00:00",
|
|
||||||
"mb":"0.00",
|
|
||||||
"noofslots":9724,
|
|
||||||
"day_size":"0 ",
|
|
||||||
"eta":"unknown",
|
|
||||||
"nzb_quota":"",
|
|
||||||
"loadavg":"",
|
|
||||||
"cache_max":"-1",
|
|
||||||
"kbpersec":"0.00",
|
|
||||||
"speedlimit":"",
|
|
||||||
"webdir":"D:\\SABnzbd\\SABnzbd\\interfaces\\Plush\\templates",
|
|
||||||
"diskspace2":"1084.96"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
{
|
|
||||||
"history":{
|
|
||||||
"active_lang":"en",
|
|
||||||
"paused":false,
|
|
||||||
"session":"5c770e3197e4fe763423ee7c392c25d1",
|
|
||||||
"restart_req":false,
|
|
||||||
"power_options":true,
|
|
||||||
"slots":[
|
|
||||||
|
|
||||||
],
|
|
||||||
"speed":"0 ",
|
|
||||||
"helpuri":"http://wiki.sabnzbd.org/",
|
|
||||||
"size":"0 B",
|
|
||||||
"uptime":"1d",
|
|
||||||
"total_size":"10.2 T",
|
|
||||||
"month_size":"445.7 G",
|
|
||||||
"week_size":"46.6 G",
|
|
||||||
"version":"0.6.9",
|
|
||||||
"new_rel_url":"http://sourceforge.net/projects/sabnzbdplus/files/sabnzbdplus/sabnzbd-0.6.14",
|
|
||||||
"diskspacetotal2":"9314.57",
|
|
||||||
"color_scheme":"gold",
|
|
||||||
"diskspacetotal1":"871.41",
|
|
||||||
"nt":true,
|
|
||||||
"status":"Idle",
|
|
||||||
"last_warning":"2012-01-19 23:58:01,736\nWARNING:\nAPI Key incorrect, Use the api key from Config->General in your 3rd party program:",
|
|
||||||
"have_warnings":"3",
|
|
||||||
"cache_art":"0",
|
|
||||||
"sizeleft":"0 B",
|
|
||||||
"finishaction":null,
|
|
||||||
"paused_all":false,
|
|
||||||
"cache_size":"0 B",
|
|
||||||
"new_release":"0.6.14",
|
|
||||||
"pause_int":"0",
|
|
||||||
"mbleft":"0.00",
|
|
||||||
"diskspace1":"869.82",
|
|
||||||
"darwin":false,
|
|
||||||
"timeleft":"0:00:00",
|
|
||||||
"mb":"0.00",
|
|
||||||
"noofslots":9724,
|
|
||||||
"day_size":"0 ",
|
|
||||||
"eta":"unknown",
|
|
||||||
"nzb_quota":"",
|
|
||||||
"loadavg":"",
|
|
||||||
"cache_max":"-1",
|
|
||||||
"kbpersec":"0.00",
|
|
||||||
"speedlimit":"",
|
|
||||||
"webdir":"D:\\SABnzbd\\SABnzbd\\interfaces\\Plush\\templates",
|
|
||||||
"diskspace2":"1084.96"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"status": false,
|
|
||||||
"error": "API Key Incorrect"
|
|
||||||
}
|
|
|
@ -77,7 +77,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IParsingService>()
|
Mocker.GetMock<IParsingService>()
|
||||||
.Setup(c => c.GetEpisodes(It.IsAny<String>(), It.IsAny<Series>(), It.IsAny<Boolean>()))
|
.Setup(c => c.GetLocalEpisode(It.IsAny<String>(), It.IsAny<Series>(), It.IsAny<Boolean>()))
|
||||||
.Returns(_localEpisode);
|
.Returns(_localEpisode);
|
||||||
|
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
{
|
{
|
||||||
GivenSpecifications(_pass1);
|
GivenSpecifications(_pass1);
|
||||||
|
|
||||||
Mocker.GetMock<IParsingService>().Setup(c => c.GetEpisodes(It.IsAny<String>(), It.IsAny<Series>(), It.IsAny<Boolean>()))
|
Mocker.GetMock<IParsingService>().Setup(c => c.GetLocalEpisode(It.IsAny<String>(), It.IsAny<Series>(), It.IsAny<Boolean>()))
|
||||||
.Throws<TestException>();
|
.Throws<TestException>();
|
||||||
|
|
||||||
_videoFiles = new List<String>
|
_videoFiles = new List<String>
|
||||||
|
@ -168,7 +168,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
Subject.GetImportDecisions(_videoFiles, _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.GetLocalEpisode(It.IsAny<String>(), It.IsAny<Series>(), It.IsAny<Boolean>()), Times.Exactly(_videoFiles.Count));
|
||||||
|
|
||||||
ExceptionVerification.ExpectedErrors(3);
|
ExceptionVerification.ExpectedErrors(3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace NzbDrone.Core.Test.MetadataSourceTests
|
||||||
[TestCase("Franklin & Bash", "Franklin & Bash")]
|
[TestCase("Franklin & Bash", "Franklin & Bash")]
|
||||||
[TestCase("Mr. D", "Mr. D")]
|
[TestCase("Mr. D", "Mr. D")]
|
||||||
[TestCase("Rob & Big", "Rob and Big")]
|
[TestCase("Rob & Big", "Rob and Big")]
|
||||||
|
[TestCase("M*A*S*H", "M*A*S*H")]
|
||||||
public void successful_search(string title, string expected)
|
public void successful_search(string title, string expected)
|
||||||
{
|
{
|
||||||
var result = Subject.SearchForNewSeries(title);
|
var result = Subject.SearchForNewSeries(title);
|
||||||
|
@ -38,7 +39,7 @@ namespace NzbDrone.Core.Test.MetadataSourceTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(75978)]
|
[TestCase(75978)]
|
||||||
[TestCase(79349)]
|
[TestCase(83462)]
|
||||||
public void should_be_able_to_get_series_detail(int tvdbId)
|
public void should_be_able_to_get_series_detail(int tvdbId)
|
||||||
{
|
{
|
||||||
var details = Subject.GetSeriesInfo(tvdbId);
|
var details = Subject.GetSeriesInfo(tvdbId);
|
||||||
|
|
|
@ -122,10 +122,10 @@
|
||||||
<Compile Include="Download\DownloadApprovedReportsTests\DownloadApprovedFixture.cs" />
|
<Compile Include="Download\DownloadApprovedReportsTests\DownloadApprovedFixture.cs" />
|
||||||
<Compile Include="Download\DownloadApprovedReportsTests\GetQualifiedReportsFixture.cs" />
|
<Compile Include="Download\DownloadApprovedReportsTests\GetQualifiedReportsFixture.cs" />
|
||||||
<Compile Include="Download\DownloadClientTests\BlackholeProviderFixture.cs" />
|
<Compile Include="Download\DownloadClientTests\BlackholeProviderFixture.cs" />
|
||||||
<Compile Include="Download\DownloadClientTests\NzbgetProviderTests\DownloadNzbFixture.cs" />
|
<Compile Include="Download\DownloadClientTests\NzbgetTests\DownloadNzbFixture.cs" />
|
||||||
<Compile Include="Download\DownloadClientTests\NzbgetProviderTests\QueueFixture.cs" />
|
<Compile Include="Download\DownloadClientTests\NzbgetTests\QueueFixture.cs" />
|
||||||
<Compile Include="Download\DownloadClientTests\PneumaticProviderFixture.cs" />
|
<Compile Include="Download\DownloadClientTests\PneumaticProviderFixture.cs" />
|
||||||
<Compile Include="Download\DownloadClientTests\SabProviderTests\SabProviderFixture.cs" />
|
<Compile Include="Download\DownloadClientTests\SabnzbdTests\SabnzbdFixture.cs" />
|
||||||
<Compile Include="Download\DownloadServiceFixture.cs" />
|
<Compile Include="Download\DownloadServiceFixture.cs" />
|
||||||
<Compile Include="Download\FailedDownloadServiceFixture.cs" />
|
<Compile Include="Download\FailedDownloadServiceFixture.cs" />
|
||||||
<Compile Include="Framework\CoreTest.cs" />
|
<Compile Include="Framework\CoreTest.cs" />
|
||||||
|
@ -180,6 +180,17 @@
|
||||||
<Compile Include="NotificationTests\Xbmc\OnDownloadFixture.cs" />
|
<Compile Include="NotificationTests\Xbmc\OnDownloadFixture.cs" />
|
||||||
<Compile Include="OrganizerTests\BuildFilePathFixture.cs" />
|
<Compile Include="OrganizerTests\BuildFilePathFixture.cs" />
|
||||||
<Compile Include="OrganizerTests\GetSeriesFolderFixture.cs" />
|
<Compile Include="OrganizerTests\GetSeriesFolderFixture.cs" />
|
||||||
|
<Compile Include="ParserTests\AbsoluteEpisodeNumberParserFixture.cs" />
|
||||||
|
<Compile Include="ParserTests\IsPossibleSpecialEpisodeFixture.cs" />
|
||||||
|
<Compile Include="ParserTests\ReleaseGroupParserFixture.cs" />
|
||||||
|
<Compile Include="ParserTests\LanguageParserFixture.cs" />
|
||||||
|
<Compile Include="ParserTests\SeasonParserFixture.cs" />
|
||||||
|
<Compile Include="ParserTests\NormalizeTitleFixture.cs" />
|
||||||
|
<Compile Include="ParserTests\CrapParserFixture.cs" />
|
||||||
|
<Compile Include="ParserTests\DailyEpisodeParserFixture.cs" />
|
||||||
|
<Compile Include="ParserTests\SingleEpisodeParserFixture.cs" />
|
||||||
|
<Compile Include="ParserTests\PathParserFixture.cs" />
|
||||||
|
<Compile Include="ParserTests\MultiEpisodeParserFixture.cs" />
|
||||||
<Compile Include="ParserTests\ParsingServiceTests\GetEpisodesFixture.cs" />
|
<Compile Include="ParserTests\ParsingServiceTests\GetEpisodesFixture.cs" />
|
||||||
<Compile Include="ParserTests\ParsingServiceTests\GetSeriesFixture.cs" />
|
<Compile Include="ParserTests\ParsingServiceTests\GetSeriesFixture.cs" />
|
||||||
<Compile Include="ParserTests\ParsingServiceTests\MapFixture.cs" />
|
<Compile Include="ParserTests\ParsingServiceTests\MapFixture.cs" />
|
||||||
|
@ -287,18 +298,9 @@
|
||||||
<Content Include="Files\LongOverview.txt">
|
<Content Include="Files\LongOverview.txt">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="Files\HistoryEmpty.txt">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Files\Queue.txt">
|
<Content Include="Files\Queue.txt">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="Files\History.txt">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Files\JsonError.txt">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<None Include="..\NzbDrone.Test.Common\App.config">
|
<None Include="..\NzbDrone.Test.Common\App.config">
|
||||||
<Link>App.config</Link>
|
<Link>App.config</Link>
|
||||||
</None>
|
</None>
|
||||||
|
@ -330,9 +332,6 @@
|
||||||
<Content Include="Files\RSS\newznab.xml">
|
<Content Include="Files\RSS\newznab.xml">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="Files\Categories_json.txt">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Files\RSS\SizeParsing\newznab.xml">
|
<Content Include="Files\RSS\SizeParsing\newznab.xml">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ParserTests
|
||||||
|
{
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class AbsoluteEpisodeNumberParserFixture : CoreTest
|
||||||
|
{
|
||||||
|
[TestCase("[SubDESU]_High_School_DxD_07_(1280x720_x264-AAC)_[6B7FD717]", "High School DxD", 7, 0, 0)]
|
||||||
|
[TestCase("[Chihiro]_Working!!_-_06_[848x480_H.264_AAC][859EEAFA]", "Working!!", 6, 0, 0)]
|
||||||
|
[TestCase("[Commie]_Senki_Zesshou_Symphogear_-_11_[65F220B4]", "Senki_Zesshou_Symphogear", 11, 0, 0)]
|
||||||
|
[TestCase("[Underwater]_Rinne_no_Lagrange_-_12_(720p)_[5C7BC4F9]", "Rinne_no_Lagrange", 12, 0, 0)]
|
||||||
|
[TestCase("[Commie]_Rinne_no_Lagrange_-_15_[E76552EA]", "Rinne_no_Lagrange", 15, 0, 0)]
|
||||||
|
[TestCase("[HorribleSubs]_Hunter_X_Hunter_-_33_[720p]", "Hunter_X_Hunter", 33, 0, 0)]
|
||||||
|
[TestCase("[HorribleSubs]_Fairy_Tail_-_145_[720p]", "Fairy_Tail", 145, 0, 0)]
|
||||||
|
[TestCase("[HorribleSubs] Tonari no Kaibutsu-kun - 13 [1080p].mkv", "Tonari no Kaibutsu-kun", 13, 0, 0)]
|
||||||
|
[TestCase("[Doremi].Yes.Pretty.Cure.5.Go.Go!.31.[1280x720].[C65D4B1F].mkv", "Yes.Pretty.Cure.5.Go.Go!", 31, 0, 0)]
|
||||||
|
[TestCase("[K-F] One Piece 214", "One Piece", 214, 0, 0)]
|
||||||
|
[TestCase("[K-F] One Piece S10E14 214", "One Piece", 214, 10, 14)]
|
||||||
|
[TestCase("[K-F] One Piece 10x14 214", "One Piece", 214, 10, 14)]
|
||||||
|
[TestCase("[K-F] One Piece 214 10x14", "One Piece", 214, 10, 14)]
|
||||||
|
// [TestCase("One Piece S10E14 214", "One Piece", 214, 10, 14)]
|
||||||
|
// [TestCase("One Piece 10x14 214", "One Piece", 214, 10, 14)]
|
||||||
|
// [TestCase("One Piece 214 10x14", "One Piece", 214, 10, 14)]
|
||||||
|
// [TestCase("214 One Piece 10x14", "One Piece", 214, 10, 14)]
|
||||||
|
[TestCase("Bleach - 031 - The Resolution to Kill [Lunar].avi", "Bleach", 31, 0, 0)]
|
||||||
|
[TestCase("Bleach - 031 - The Resolution to Kill [Lunar]", "Bleach", 31, 0, 0)]
|
||||||
|
[TestCase("[ACX]Hack Sign 01 Role Play [Kosaka] [9C57891E].mkv", "Hack Sign", 1, 0, 0)]
|
||||||
|
[TestCase("[SFW-sage] Bakuman S3 - 12 [720p][D07C91FC]", "Bakuman S3", 12, 0, 0)]
|
||||||
|
[TestCase("ducktales_e66_time_is_money_part_one_marking_time", "DuckTales", 66, 0, 0)]
|
||||||
|
public void should_parse_absolute_numbers(string postTitle, string title, int absoluteEpisodeNumber, int seasonNumber, int episodeNumber)
|
||||||
|
{
|
||||||
|
var result = Parser.Parser.ParseTitle(postTitle);
|
||||||
|
result.Should().NotBeNull();
|
||||||
|
result.AbsoluteEpisodeNumbers.First().Should().Be(absoluteEpisodeNumber);
|
||||||
|
result.SeasonNumber.Should().Be(seasonNumber);
|
||||||
|
result.EpisodeNumbers.FirstOrDefault().Should().Be(episodeNumber);
|
||||||
|
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
|
||||||
|
result.FullSeason.Should().BeFalse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Expansive;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ParserTests
|
||||||
|
{
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class CrapParserFixture : CoreTest
|
||||||
|
{
|
||||||
|
[TestCase("76El6LcgLzqb426WoVFg1vVVVGx4uCYopQkfjmLe")]
|
||||||
|
[TestCase("Vrq6e1Aba3U amCjuEgV5R2QvdsLEGYF3YQAQkw8")]
|
||||||
|
[TestCase("TDAsqTea7k4o6iofVx3MQGuDK116FSjPobMuh8oB")]
|
||||||
|
[TestCase("yp4nFodAAzoeoRc467HRh1mzuT17qeekmuJ3zFnL")]
|
||||||
|
[TestCase("oxXo8S2272KE1 lfppvxo3iwEJBrBmhlQVK1gqGc")]
|
||||||
|
[TestCase("dPBAtu681Ycy3A4NpJDH6kNVQooLxqtnsW1Umfiv")]
|
||||||
|
[TestCase("password - \"bdc435cb-93c4-4902-97ea-ca00568c3887.337\" yEnc")]
|
||||||
|
[TestCase("185d86a343e39f3341e35c4dad3f9959")]
|
||||||
|
[TestCase("ba27283b17c00d01193eacc02a8ba98eeb523a76")]
|
||||||
|
[TestCase("45a55debe3856da318cc35882ad07e43cd32fd15")]
|
||||||
|
[TestCase("86420f8ee425340d8894bf3bc636b66404b95f18")]
|
||||||
|
[TestCase("ce39afb7da6cf7c04eba3090f0a309f609883862")]
|
||||||
|
[TestCase("THIS SHOULD NEVER PARSE")]
|
||||||
|
public void should_not_parse_crap(string title)
|
||||||
|
{
|
||||||
|
Parser.Parser.ParseTitle(title).Should().BeNull();
|
||||||
|
ExceptionVerification.IgnoreWarns();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Expansive;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ParserTests
|
||||||
|
{
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class DailyEpisodeParserFixture : CoreTest
|
||||||
|
{
|
||||||
|
[TestCase("Conan 2011 04 18 Emma Roberts HDTV XviD BFF", "Conan", 2011, 04, 18)]
|
||||||
|
[TestCase("The Tonight Show With Jay Leno 2011 04 15 1080i HDTV DD5 1 MPEG2 TrollHD", "The Tonight Show With Jay Leno", 2011, 04, 15)]
|
||||||
|
[TestCase("The.Daily.Show.2010.10.11.Johnny.Knoxville.iTouch-MW", "The.Daily.Show", 2010, 10, 11)]
|
||||||
|
[TestCase("The Daily Show - 2011-04-12 - Gov. Deval Patrick", "The.Daily.Show", 2011, 04, 12)]
|
||||||
|
[TestCase("2011.01.10 - Denis Leary - HD TV.mkv", "", 2011, 1, 10)]
|
||||||
|
[TestCase("2011.03.13 - Denis Leary - HD TV.mkv", "", 2011, 3, 13)]
|
||||||
|
[TestCase("The Tonight Show with Jay Leno - 2011-06-16 - Larry David, \"Bachelorette\" Ashley Hebert, Pitbull with Ne-Yo", "The Tonight Show with Jay Leno", 2011, 6, 16)]
|
||||||
|
[TestCase("2020.NZ.2012.16.02.PDTV.XviD-C4TV", "2020nz", 2012, 2, 16)]
|
||||||
|
[TestCase("2020.NZ.2012.13.02.PDTV.XviD-C4TV", "2020nz", 2012, 2, 13)]
|
||||||
|
[TestCase("2020.NZ.2011.12.02.PDTV.XviD-C4TV", "2020nz", 2011, 12, 2)]
|
||||||
|
public void should_parse_daily_episode(string postTitle, string title, int year, int month, int day)
|
||||||
|
{
|
||||||
|
var result = Parser.Parser.ParseTitle(postTitle);
|
||||||
|
var airDate = new DateTime(year, month, day);
|
||||||
|
result.Should().NotBeNull();
|
||||||
|
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
|
||||||
|
result.AirDate.Should().Be(airDate.ToString(Episode.AIR_DATE_FORMAT));
|
||||||
|
result.EpisodeNumbers.Should().BeEmpty();
|
||||||
|
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
|
||||||
|
result.FullSeason.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("Conan {year} {month} {day} Emma Roberts HDTV XviD BFF")]
|
||||||
|
[TestCase("The Tonight Show With Jay Leno {year} {month} {day} 1080i HDTV DD5 1 MPEG2 TrollHD")]
|
||||||
|
[TestCase("The.Daily.Show.{year}.{month}.{day}.Johnny.Knoxville.iTouch-MW")]
|
||||||
|
[TestCase("The Daily Show - {year}-{month}-{day} - Gov. Deval Patrick")]
|
||||||
|
[TestCase("{year}.{month}.{day} - Denis Leary - HD TV.mkv")]
|
||||||
|
[TestCase("The Tonight Show with Jay Leno - {year}-{month}-{day} - Larry David, \"Bachelorette\" Ashley Hebert, Pitbull with Ne-Yo")]
|
||||||
|
[TestCase("2020.NZ.{year}.{month}.{day}.PDTV.XviD-C4TV")]
|
||||||
|
public void should_not_accept_ancient_daily_series(string title)
|
||||||
|
{
|
||||||
|
var yearTooLow = title.Expand(new { year = 1950, month = 10, day = 14 });
|
||||||
|
Parser.Parser.ParseTitle(yearTooLow).Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("Conan {year} {month} {day} Emma Roberts HDTV XviD BFF")]
|
||||||
|
[TestCase("The Tonight Show With Jay Leno {year} {month} {day} 1080i HDTV DD5 1 MPEG2 TrollHD")]
|
||||||
|
[TestCase("The.Daily.Show.{year}.{month}.{day}.Johnny.Knoxville.iTouch-MW")]
|
||||||
|
[TestCase("The Daily Show - {year}-{month}-{day} - Gov. Deval Patrick")]
|
||||||
|
[TestCase("{year}.{month}.{day} - Denis Leary - HD TV.mkv")]
|
||||||
|
[TestCase("The Tonight Show with Jay Leno - {year}-{month}-{day} - Larry David, \"Bachelorette\" Ashley Hebert, Pitbull with Ne-Yo")]
|
||||||
|
[TestCase("2020.NZ.{year}.{month}.{day}.PDTV.XviD-C4TV")]
|
||||||
|
public void should_not_accept_future_dates(string title)
|
||||||
|
{
|
||||||
|
var twoDaysFromNow = DateTime.Now.AddDays(2);
|
||||||
|
|
||||||
|
var validDate = title.Expand(new { year = twoDaysFromNow.Year, month = twoDaysFromNow.Month.ToString("00"), day = twoDaysFromNow.Day.ToString("00") });
|
||||||
|
|
||||||
|
Parser.Parser.ParseTitle(validDate).Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_fail_if_episode_is_far_in_future()
|
||||||
|
{
|
||||||
|
var title = string.Format("{0:yyyy.MM.dd} - Denis Leary - HD TV.mkv", DateTime.Now.AddDays(2));
|
||||||
|
|
||||||
|
Parser.Parser.ParseTitle(title).Should().BeNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ParserTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class IsPossibleSpecialEpisodeFixture
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void should_not_treat_files_without_a_series_title_as_a_special()
|
||||||
|
{
|
||||||
|
var parsedEpisodeInfo = new ParsedEpisodeInfo
|
||||||
|
{
|
||||||
|
EpisodeNumbers = new[]{ 7 },
|
||||||
|
SeasonNumber = 1,
|
||||||
|
SeriesTitle = ""
|
||||||
|
};
|
||||||
|
|
||||||
|
parsedEpisodeInfo.IsPossibleSpecialEpisode().Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_when_episode_numbers_is_empty()
|
||||||
|
{
|
||||||
|
var parsedEpisodeInfo = new ParsedEpisodeInfo
|
||||||
|
{
|
||||||
|
SeasonNumber = 1,
|
||||||
|
SeriesTitle = ""
|
||||||
|
};
|
||||||
|
|
||||||
|
parsedEpisodeInfo.IsPossibleSpecialEpisode().Should().BeTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ParserTests
|
||||||
|
{
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class LanguageParserFixture : CoreTest
|
||||||
|
{
|
||||||
|
[TestCase("Castle.2009.S01E14.English.HDTV.XviD-LOL", Language.English)]
|
||||||
|
[TestCase("Castle.2009.S01E14.French.HDTV.XviD-LOL", Language.French)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Spanish.HDTV.XviD-LOL", Language.Spanish)]
|
||||||
|
[TestCase("Castle.2009.S01E14.German.HDTV.XviD-LOL", Language.German)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Germany.HDTV.XviD-LOL", Language.English)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Italian.HDTV.XviD-LOL", Language.Italian)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Danish.HDTV.XviD-LOL", Language.Danish)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Dutch.HDTV.XviD-LOL", Language.Dutch)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Japanese.HDTV.XviD-LOL", Language.Japanese)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Cantonese.HDTV.XviD-LOL", Language.Cantonese)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Mandarin.HDTV.XviD-LOL", Language.Mandarin)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Korean.HDTV.XviD-LOL", Language.Korean)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Russian.HDTV.XviD-LOL", Language.Russian)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Polish.HDTV.XviD-LOL", Language.Polish)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Vietnamese.HDTV.XviD-LOL", Language.Vietnamese)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Swedish.HDTV.XviD-LOL", Language.Swedish)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Norwegian.HDTV.XviD-LOL", Language.Norwegian)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Finnish.HDTV.XviD-LOL", Language.Finnish)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Turkish.HDTV.XviD-LOL", Language.Turkish)]
|
||||||
|
[TestCase("Castle.2009.S01E14.Portuguese.HDTV.XviD-LOL", Language.Portuguese)]
|
||||||
|
[TestCase("Castle.2009.S01E14.HDTV.XviD-LOL", Language.English)]
|
||||||
|
[TestCase("person.of.interest.1x19.ita.720p.bdmux.x264-novarip", Language.Italian)]
|
||||||
|
[TestCase("Salamander.S01E01.FLEMISH.HDTV.x264-BRiGAND", Language.Flemish)]
|
||||||
|
[TestCase("H.Polukatoikia.S03E13.Greek.PDTV.XviD-Ouzo", Language.Greek)]
|
||||||
|
[TestCase("Burn.Notice.S04E15.Brotherly.Love.GERMAN.DUBBED.WS.WEBRiP.XviD.REPACK-TVP", Language.German)]
|
||||||
|
[TestCase("Ray Donovan - S01E01.720p.HDtv.x264-Evolve (NLsub)", Language.Norwegian)]
|
||||||
|
[TestCase("Shield,.The.1x13.Tueurs.De.Flics.FR.DVDRip.XviD", Language.French)]
|
||||||
|
[TestCase("True.Detective.S01E01.1080p.WEB-DL.Rus.Eng.TVKlondike", Language.Russian)]
|
||||||
|
public void should_parse_language(string postTitle, Language language)
|
||||||
|
{
|
||||||
|
var result = Parser.Parser.ParseTitle(postTitle);
|
||||||
|
result.Language.Should().Be(language);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Expansive;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ParserTests
|
||||||
|
{
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class MultiEpisodeParserFixture : CoreTest
|
||||||
|
{
|
||||||
|
[TestCase("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", "WEEDS", 3, new[] { 1, 2, 3, 4, 5, 6 })]
|
||||||
|
[TestCase("Two.and.a.Half.Men.103.104.720p.HDTV.X264-DIMENSION", "Two.and.a.Half.Men", 1, new[] { 3, 4 })]
|
||||||
|
[TestCase("Weeds.S03E01.S03E02.720p.HDTV.X264-DIMENSION", "Weeds", 3, new[] { 1, 2 })]
|
||||||
|
[TestCase("The Borgias S01e01 e02 ShoHD On Demand 1080i DD5 1 ALANiS", "The Borgias", 1, new[] { 1, 2 })]
|
||||||
|
[TestCase("White.Collar.2x04.2x05.720p.BluRay-FUTV", "White.Collar", 2, new[] { 4, 5 })]
|
||||||
|
[TestCase("Desperate.Housewives.S07E22E23.720p.HDTV.X264-DIMENSION", "Desperate.Housewives", 7, new[] { 22, 23 })]
|
||||||
|
[TestCase("Desparate Housewives - S07E22 - S07E23 - And Lots of Security.. [HDTV-720p].mkv", "Desparate Housewives", 7, new[] { 22, 23 })]
|
||||||
|
[TestCase("S03E01.S03E02.720p.HDTV.X264-DIMENSION", "", 3, new[] { 1, 2 })]
|
||||||
|
[TestCase("Desparate Housewives - S07E22 - 7x23 - And Lots of Security.. [HDTV-720p].mkv", "Desparate Housewives", 7, new[] { 22, 23 })]
|
||||||
|
[TestCase("S07E22 - 7x23 - And Lots of Security.. [HDTV-720p].mkv", "", 7, new[] { 22, 23 })]
|
||||||
|
[TestCase("2x04x05.720p.BluRay-FUTV", "", 2, new[] { 4, 5 })]
|
||||||
|
[TestCase("S02E04E05.720p.BluRay-FUTV", "", 2, new[] { 4, 5 })]
|
||||||
|
[TestCase("S02E03-04-05.720p.BluRay-FUTV", "", 2, new[] { 3, 4, 5 })]
|
||||||
|
[TestCase("Breakout.Kings.S02E09-E10.HDTV.x264-ASAP", "Breakout Kings", 2, new[] { 9, 10 })]
|
||||||
|
[TestCase("Breakout Kings - 2x9-2x10 - Served Cold [SDTV] ", "Breakout Kings", 2, new[] { 9, 10 })]
|
||||||
|
[TestCase("Breakout Kings - 2x09-2x10 - Served Cold [SDTV] ", "Breakout Kings", 2, new[] { 9, 10 })]
|
||||||
|
[TestCase("Hell on Wheels S02E09 E10 HDTV x264 EVOLVE", "Hell on Wheels", 2, new[] { 9, 10 })]
|
||||||
|
[TestCase("Hell.on.Wheels.S02E09-E10.720p.HDTV.x264-EVOLVE", "Hell on Wheels", 2, new[] { 9, 10 })]
|
||||||
|
[TestCase("Grey's Anatomy - 8x01_02 - Free Falling", "Grey's Anatomy", 8, new [] { 1,2 })]
|
||||||
|
[TestCase("8x01_02 - Free Falling", "", 8, new[] { 1, 2 })]
|
||||||
|
[TestCase("Kaamelott.S01E91-E100", "Kaamelott", 1, new[] { 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 })]
|
||||||
|
[TestCase("Neighbours.S29E161-E165.PDTV.x264-FQM", "Neighbours", 29, new[] { 161, 162, 163, 164, 165 })]
|
||||||
|
[TestCase("Shortland.Street.S22E5363-E5366.HDTV.x264-FiHTV", "Shortland Street", 22, new[] { 5363, 5364, 5365, 5366 })]
|
||||||
|
public void should_parse_multiple_episodes(string postTitle, string title, int season, int[] episodes)
|
||||||
|
{
|
||||||
|
var result = Parser.Parser.ParseTitle(postTitle);
|
||||||
|
result.SeasonNumber.Should().Be(season);
|
||||||
|
result.EpisodeNumbers.Should().BeEquivalentTo(episodes);
|
||||||
|
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
|
||||||
|
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
|
||||||
|
result.FullSeason.Should().BeFalse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Expansive;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ParserTests
|
||||||
|
{
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class NormalizeTitleFixture : CoreTest
|
||||||
|
{
|
||||||
|
[TestCase("Conan", "conan")]
|
||||||
|
[TestCase("The Tonight Show With Jay Leno", "tonightshowwithjayleno")]
|
||||||
|
[TestCase("The.Daily.Show", "dailyshow")]
|
||||||
|
[TestCase("Castle (2009)", "castle2009")]
|
||||||
|
[TestCase("Parenthood.2010", "parenthood2010")]
|
||||||
|
[TestCase("Law_and_Order_SVU", "lawordersvu")]
|
||||||
|
public void should_normalize_series_title(string parsedSeriesName, string seriesName)
|
||||||
|
{
|
||||||
|
var result = parsedSeriesName.CleanSeriesTitle();
|
||||||
|
result.Should().Be(seriesName);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("CaPitAl", "capital")]
|
||||||
|
[TestCase("peri.od", "period")]
|
||||||
|
[TestCase("this.^&%^**$%@#$!That", "thisthat")]
|
||||||
|
[TestCase("test/test", "testtest")]
|
||||||
|
[TestCase("90210", "90210")]
|
||||||
|
[TestCase("24", "24")]
|
||||||
|
public void should_remove_special_characters_and_casing(string dirty, string clean)
|
||||||
|
{
|
||||||
|
var result = dirty.CleanSeriesTitle();
|
||||||
|
result.Should().Be(clean);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("the")]
|
||||||
|
[TestCase("and")]
|
||||||
|
[TestCase("or")]
|
||||||
|
[TestCase("a")]
|
||||||
|
[TestCase("an")]
|
||||||
|
[TestCase("of")]
|
||||||
|
public void should_remove_common_words(string word)
|
||||||
|
{
|
||||||
|
var dirtyFormat = new[]
|
||||||
|
{
|
||||||
|
"word.{0}.word",
|
||||||
|
"word {0} word",
|
||||||
|
"word-{0}-word",
|
||||||
|
"{0}.word.word",
|
||||||
|
"{0}-word-word",
|
||||||
|
"{0} word word",
|
||||||
|
"word.word.{0}",
|
||||||
|
"word-word-{0}",
|
||||||
|
"word-word {0}",
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var s in dirtyFormat)
|
||||||
|
{
|
||||||
|
var dirty = String.Format(s, word);
|
||||||
|
dirty.CleanSeriesTitle().Should().Be("wordword");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("the")]
|
||||||
|
[TestCase("and")]
|
||||||
|
[TestCase("or")]
|
||||||
|
[TestCase("a")]
|
||||||
|
[TestCase("an")]
|
||||||
|
[TestCase("of")]
|
||||||
|
public void should_not_remove_common_words_in_the_middle_of_word(string word)
|
||||||
|
{
|
||||||
|
var dirtyFormat = new[]
|
||||||
|
{
|
||||||
|
"word.{0}word",
|
||||||
|
"word {0}word",
|
||||||
|
"word-{0}word",
|
||||||
|
"word{0}.word",
|
||||||
|
"word{0}-word",
|
||||||
|
"word{0}-word",
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var s in dirtyFormat)
|
||||||
|
{
|
||||||
|
var dirty = String.Format(s, word);
|
||||||
|
dirty.CleanSeriesTitle().Should().Be(("word" + word.ToLower() + "word"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,11 +2,8 @@ using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.Expansive;
|
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
using NzbDrone.Test.Common;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.ParserTests
|
namespace NzbDrone.Core.Test.ParserTests
|
||||||
{
|
{
|
||||||
|
@ -26,179 +23,6 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||||
* Superman.-.The.Man.of.Steel.1994-05.33.hybrid.DreamGirl-Novus-HD
|
* Superman.-.The.Man.of.Steel.1994-05.33.hybrid.DreamGirl-Novus-HD
|
||||||
*/
|
*/
|
||||||
|
|
||||||
[TestCase("Sonny.With.a.Chance.S02E15", "Sonny.With.a.Chance", 2, 15)]
|
|
||||||
[TestCase("Two.and.a.Half.Me.103.720p.HDTV.X264-DIMENSION", "Two.and.a.Half.Me", 1, 3)]
|
|
||||||
[TestCase("Two.and.a.Half.Me.113.720p.HDTV.X264-DIMENSION", "Two.and.a.Half.Me", 1, 13)]
|
|
||||||
[TestCase("Two.and.a.Half.Me.1013.720p.HDTV.X264-DIMENSION", "Two.and.a.Half.Me", 10, 13)]
|
|
||||||
[TestCase("Chuck.4x05.HDTV.XviD-LOL", "Chuck", 4, 5)]
|
|
||||||
[TestCase("The.Girls.Next.Door.S03E06.DVDRip.XviD-WiDE", "The.Girls.Next.Door", 3, 6)]
|
|
||||||
[TestCase("Degrassi.S10E27.WS.DSR.XviD-2HD", "Degrassi", 10, 27)]
|
|
||||||
[TestCase("Parenthood.2010.S02E14.HDTV.XviD-LOL", "Parenthood 2010", 2, 14)]
|
|
||||||
[TestCase("Hawaii Five 0 S01E19 720p WEB DL DD5 1 H 264 NT", "Hawaii Five 0", 1, 19)]
|
|
||||||
[TestCase("The Event S01E14 A Message Back 720p WEB DL DD5 1 H264 SURFER", "The Event", 1, 14)]
|
|
||||||
[TestCase("Adam Hills In Gordon St Tonight S01E07 WS PDTV XviD FUtV", "Adam Hills In Gordon St Tonight", 1, 7)]
|
|
||||||
[TestCase("Adam Hills In Gordon St Tonight S01E07 WS PDTV XviD FUtV", "Adam Hills In Gordon St Tonight", 1, 7)]
|
|
||||||
[TestCase("Adventure.Inc.S03E19.DVDRip.XviD-OSiTV", "Adventure.Inc", 3, 19)]
|
|
||||||
[TestCase("S03E09 WS PDTV XviD FUtV", "", 3, 9)]
|
|
||||||
[TestCase("5x10 WS PDTV XviD FUtV", "", 5, 10)]
|
|
||||||
[TestCase("Castle.2009.S01E14.HDTV.XviD-LOL", "Castle 2009", 1, 14)]
|
|
||||||
[TestCase("Pride.and.Prejudice.1995.S03E20.HDTV.XviD-LOL", "Pride and Prejudice 1995", 3, 20)]
|
|
||||||
[TestCase("The.Office.S03E115.DVDRip.XviD-OSiTV", "The.Office", 3, 115)]
|
|
||||||
[TestCase(@"Parks and Recreation - S02E21 - 94 Meetings - 720p TV.mkv", "Parks and Recreation", 2, 21)]
|
|
||||||
[TestCase(@"24-7 Penguins-Capitals- Road to the NHL Winter Classic - S01E03 - Episode 3.mkv", "24-7 Penguins-Capitals- Road to the NHL Winter Classic", 1, 3)]
|
|
||||||
[TestCase("Adventure.Inc.S03E19.DVDRip.\"XviD\"-OSiTV", "Adventure.Inc", 3, 19)]
|
|
||||||
[TestCase("Hawaii Five-0 (2010) - 1x05 - Nalowale (Forgotten/Missing)", "Hawaii Five-0 (2010)", 1, 5)]
|
|
||||||
[TestCase("Hawaii Five-0 (2010) - 1x05 - Title", "Hawaii Five-0 (2010)", 1, 5)]
|
|
||||||
[TestCase("House - S06E13 - 5 to 9 [DVD]", "House", 6, 13)]
|
|
||||||
[TestCase("The Mentalist - S02E21 - 18-5-4", "The Mentalist", 2, 21)]
|
|
||||||
[TestCase("Breaking.In.S01E07.21.0.Jump.Street.720p.WEB-DL.DD5.1.h.264-KiNGS", "Breaking In", 1, 7)]
|
|
||||||
[TestCase("CSI.525", "CSI", 5, 25)]
|
|
||||||
[TestCase("King of the Hill - 10x12 - 24 Hour Propane People [SDTV]", "King of the Hill", 10, 12)]
|
|
||||||
[TestCase("Brew Masters S01E06 3 Beers For Batali DVDRip XviD SPRiNTER", "Brew Masters", 1, 6)]
|
|
||||||
[TestCase("24 7 Flyers Rangers Road to the NHL Winter Classic Part01 720p HDTV x264 ORENJI", "24 7 Flyers Rangers Road to the NHL Winter Classic", 1, 1)]
|
|
||||||
[TestCase("24 7 Flyers Rangers Road to the NHL Winter Classic Part 02 720p HDTV x264 ORENJI", "24 7 Flyers Rangers Road to the NHL Winter Classic", 1, 2)]
|
|
||||||
[TestCase("24-7 Flyers-Rangers- Road to the NHL Winter Classic - S01E01 - Part 1", "24 7 Flyers Rangers Road to the NHL Winter Classic", 1, 1)]
|
|
||||||
[TestCase("The.Kennedys.Part.2.DSR.XviD-SYS", "The Kennedys", 1, 2)]
|
|
||||||
[TestCase("the-pacific-e07-720p", "The Pacific", 1, 7)]
|
|
||||||
[TestCase("S6E02-Unwrapped-(Playing With Food) - [DarkData]", "", 6, 2)]
|
|
||||||
[TestCase("S06E03-Unwrapped-(Number Ones Unwrapped) - [DarkData]", "", 6, 3)]
|
|
||||||
[TestCase("The Mentalist S02E21 18 5 4 720p WEB DL DD5 1 h 264 EbP", "The Mentalist", 2, 21)]
|
|
||||||
[TestCase("01x04 - Halloween, Part 1 - 720p WEB-DL", "", 1, 4)]
|
|
||||||
[TestCase("extras.s03.e05.ws.dvdrip.xvid-m00tv", "Extras", 3, 5)]
|
|
||||||
[TestCase("castle.2009.416.hdtv-lol", "Castle 2009", 4, 16)]
|
|
||||||
[TestCase("hawaii.five-0.2010.217.hdtv-lol", "Hawaii Five-0 (2010)", 2, 17)]
|
|
||||||
[TestCase("Looney Tunes - S1936E18 - I Love to Singa", "Looney Tunes", 1936, 18)]
|
|
||||||
[TestCase("American_Dad!_-_7x6_-_The_Scarlett_Getter_[SDTV]", "American Dad!", 7, 6)]
|
|
||||||
[TestCase("Falling_Skies_-_1x1_-_Live_and_Learn_[HDTV-720p]", "Falling Skies", 1, 1)]
|
|
||||||
[TestCase("Top Gear - 07x03 - 2005.11.70", "Top Gear", 7, 3)]
|
|
||||||
[TestCase("Hatfields and McCoys 2012 Part 1 REPACK 720p HDTV x264 2HD", "Hatfields and McCoys 2012", 1, 1)]
|
|
||||||
[TestCase("Glee.S04E09.Swan.Song.1080p.WEB-DL.DD5.1.H.264-ECI", "Glee", 4, 9)]
|
|
||||||
[TestCase("S08E20 50-50 Carla [DVD]", "", 8, 20)]
|
|
||||||
[TestCase("Cheers S08E20 50-50 Carla [DVD]", "Cheers", 8, 20)]
|
|
||||||
[TestCase("S02E10 6-50 to SLC [SDTV]", "", 2, 10)]
|
|
||||||
[TestCase("Franklin & Bash S02E10 6-50 to SLC [SDTV]", "Franklin & Bash", 2, 10)]
|
|
||||||
[TestCase("The_Big_Bang_Theory_-_6x12_-_The_Egg_Salad_Equivalency_[HDTV-720p]", "The Big Bang Theory", 6, 12)]
|
|
||||||
[TestCase("Top_Gear.19x06.720p_HDTV_x264-FoV", "Top Gear", 19, 6)]
|
|
||||||
[TestCase("Portlandia.S03E10.Alexandra.720p.WEB-DL.AAC2.0.H.264-CROM.mkv", "Portlandia", 3, 10)]
|
|
||||||
[TestCase("(Game of Thrones s03 e - \"Game of Thrones Season 3 Episode 10\"", "Game of Thrones", 3, 10)]
|
|
||||||
[TestCase("House.Hunters.International.S05E607.720p.hdtv.x264", "House.Hunters.International", 5, 607)]
|
|
||||||
[TestCase("Adventure.Time.With.Finn.And.Jake.S01E20.720p.BluRay.x264-DEiMOS", "Adventure.Time.With.Finn.And.Jake", 1, 20)]
|
|
||||||
[TestCase("Hostages.S01E04.2-45.PM.[HDTV-720p].mkv", "Hostages", 1, 4)]
|
|
||||||
[TestCase("S01E04", "", 1, 4)]
|
|
||||||
[TestCase("1x04", "", 1, 4)]
|
|
||||||
[TestCase("10.Things.You.Dont.Know.About.S02E04.Prohibition.HDTV.XviD-AFG", "10 Things You Dont Know About", 2, 4)]
|
|
||||||
[TestCase("30 Rock - S01E01 - Pilot.avi", "30 Rock", 1, 1)]
|
|
||||||
[TestCase("666 Park Avenue - S01E01", "666 Park Avenue", 1, 1)]
|
|
||||||
[TestCase("Warehouse 13 - S01E01", "Warehouse 13", 1, 1)]
|
|
||||||
[TestCase("Don't Trust The B---- in Apartment 23.S01E01", "Don't Trust The B---- in Apartment 23", 1, 1)]
|
|
||||||
[TestCase("Warehouse.13.S01E01", "Warehouse.13", 1, 1)]
|
|
||||||
[TestCase("Dont.Trust.The.B----.in.Apartment.23.S01E01", "Dont.Trust.The.B----.in.Apartment.23", 1, 1)]
|
|
||||||
[TestCase("24 S01E01", "24", 1, 1)]
|
|
||||||
[TestCase("24.S01E01", "24", 1, 1)]
|
|
||||||
[TestCase("Homeland - 2x12 - The Choice [HDTV-1080p].mkv", "Homeland", 2, 12)]
|
|
||||||
[TestCase("Homeland - 2x4 - New Car Smell [HDTV-1080p].mkv", "Homeland", 2, 4)]
|
|
||||||
public void ParseTitle_single(string postTitle, string title, int seasonNumber, int episodeNumber)
|
|
||||||
{
|
|
||||||
var result = Parser.Parser.ParseTitle(postTitle);
|
|
||||||
result.Should().NotBeNull();
|
|
||||||
result.EpisodeNumbers.Should().HaveCount(1);
|
|
||||||
result.SeasonNumber.Should().Be(seasonNumber);
|
|
||||||
result.EpisodeNumbers.First().Should().Be(episodeNumber);
|
|
||||||
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
|
|
||||||
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
|
|
||||||
result.FullSeason.Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase(@"z:\tv shows\battlestar galactica (2003)\Season 3\S03E05 - Collaborators.mkv", 3, 5)]
|
|
||||||
[TestCase(@"z:\tv shows\modern marvels\Season 16\S16E03 - The Potato.mkv", 16, 3)]
|
|
||||||
[TestCase(@"z:\tv shows\robot chicken\Specials\S00E16 - Dear Consumer - SD TV.avi", 0, 16)]
|
|
||||||
[TestCase(@"D:\shares\TV Shows\Parks And Recreation\Season 2\S02E21 - 94 Meetings - 720p TV.mkv", 2, 21)]
|
|
||||||
[TestCase(@"D:\shares\TV Shows\Battlestar Galactica (2003)\Season 2\S02E21.avi", 2, 21)]
|
|
||||||
[TestCase("C:/Test/TV/Chuck.4x05.HDTV.XviD-LOL", 4, 5)]
|
|
||||||
[TestCase(@"P:\TV Shows\House\Season 6\S06E13 - 5 to 9 - 720p BluRay.mkv", 6, 13)]
|
|
||||||
[TestCase(@"S:\TV Drop\House - 10x11 - Title [SDTV]\1011 - Title.avi", 10, 11)]
|
|
||||||
[TestCase(@"/TV Drop/House - 10x11 - Title [SDTV]/1011 - Title.avi", 10, 11)]
|
|
||||||
[TestCase(@"S:\TV Drop\King of the Hill - 10x12 - 24 Hour Propane People [SDTV]\1012 - 24 Hour Propane People.avi", 10, 12)]
|
|
||||||
[TestCase(@"/TV Drop/King of the Hill - 10x12 - 24 Hour Propane People [SDTV]/1012 - 24 Hour Propane People.avi", 10, 12)]
|
|
||||||
[TestCase(@"S:\TV Drop\King of the Hill - 10x12 - 24 Hour Propane People [SDTV]\Hour Propane People.avi", 10, 12)]
|
|
||||||
[TestCase(@"/TV Drop/King of the Hill - 10x12 - 24 Hour Propane People [SDTV]/Hour Propane People.avi", 10, 12)]
|
|
||||||
[TestCase(@"E:\Downloads\tv\The.Big.Bang.Theory.S01E01.720p.HDTV\ajifajjjeaeaeqwer_eppj.avi", 1, 1)]
|
|
||||||
[TestCase(@"C:\Test\Unsorted\The.Big.Bang.Theory.S01E01.720p.HDTV\tbbt101.avi", 1, 1)]
|
|
||||||
public void PathParse_tests(string path, int season, int episode)
|
|
||||||
{
|
|
||||||
var result = Parser.Parser.ParsePath(path);
|
|
||||||
result.EpisodeNumbers.Should().HaveCount(1);
|
|
||||||
result.SeasonNumber.Should().Be(season);
|
|
||||||
result.EpisodeNumbers[0].Should().Be(episode);
|
|
||||||
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
|
|
||||||
result.FullSeason.Should().BeFalse();
|
|
||||||
|
|
||||||
ExceptionVerification.IgnoreWarns();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase("THIS SHOULD NEVER PARSE")]
|
|
||||||
public void unparsable_title_should_log_warn_and_return_null(string title)
|
|
||||||
{
|
|
||||||
Parser.Parser.ParseTitle(title).Should().BeNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
//[Timeout(1000)]
|
|
||||||
[TestCase("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", "WEEDS", 3, new[] { 1, 2, 3, 4, 5, 6 })]
|
|
||||||
[TestCase("Two.and.a.Half.Men.103.104.720p.HDTV.X264-DIMENSION", "Two.and.a.Half.Men", 1, new[] { 3, 4 })]
|
|
||||||
[TestCase("Weeds.S03E01.S03E02.720p.HDTV.X264-DIMENSION", "Weeds", 3, new[] { 1, 2 })]
|
|
||||||
[TestCase("The Borgias S01e01 e02 ShoHD On Demand 1080i DD5 1 ALANiS", "The Borgias", 1, new[] { 1, 2 })]
|
|
||||||
[TestCase("White.Collar.2x04.2x05.720p.BluRay-FUTV", "White.Collar", 2, new[] { 4, 5 })]
|
|
||||||
[TestCase("Desperate.Housewives.S07E22E23.720p.HDTV.X264-DIMENSION", "Desperate.Housewives", 7, new[] { 22, 23 })]
|
|
||||||
[TestCase("Desparate Housewives - S07E22 - S07E23 - And Lots of Security.. [HDTV-720p].mkv", "Desparate Housewives", 7, new[] { 22, 23 })]
|
|
||||||
[TestCase("S03E01.S03E02.720p.HDTV.X264-DIMENSION", "", 3, new[] { 1, 2 })]
|
|
||||||
[TestCase("Desparate Housewives - S07E22 - 7x23 - And Lots of Security.. [HDTV-720p].mkv", "Desparate Housewives", 7, new[] { 22, 23 })]
|
|
||||||
[TestCase("S07E22 - 7x23 - And Lots of Security.. [HDTV-720p].mkv", "", 7, new[] { 22, 23 })]
|
|
||||||
[TestCase("2x04x05.720p.BluRay-FUTV", "", 2, new[] { 4, 5 })]
|
|
||||||
[TestCase("S02E04E05.720p.BluRay-FUTV", "", 2, new[] { 4, 5 })]
|
|
||||||
[TestCase("S02E03-04-05.720p.BluRay-FUTV", "", 2, new[] { 3, 4, 5 })]
|
|
||||||
[TestCase("Breakout.Kings.S02E09-E10.HDTV.x264-ASAP", "Breakout Kings", 2, new[] { 9, 10 })]
|
|
||||||
[TestCase("Breakout Kings - 2x9-2x10 - Served Cold [SDTV] ", "Breakout Kings", 2, new[] { 9, 10 })]
|
|
||||||
[TestCase("Breakout Kings - 2x09-2x10 - Served Cold [SDTV] ", "Breakout Kings", 2, new[] { 9, 10 })]
|
|
||||||
[TestCase("Hell on Wheels S02E09 E10 HDTV x264 EVOLVE", "Hell on Wheels", 2, new[] { 9, 10 })]
|
|
||||||
[TestCase("Hell.on.Wheels.S02E09-E10.720p.HDTV.x264-EVOLVE", "Hell on Wheels", 2, new[] { 9, 10 })]
|
|
||||||
[TestCase("Grey's Anatomy - 8x01_02 - Free Falling", "Grey's Anatomy", 8, new [] { 1,2 })]
|
|
||||||
[TestCase("8x01_02 - Free Falling", "", 8, new[] { 1, 2 })]
|
|
||||||
[TestCase("Kaamelott.S01E91-E100", "Kaamelott", 1, new[] { 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 })]
|
|
||||||
[TestCase("Neighbours.S29E161-E165.PDTV.x264-FQM", "Neighbours", 29, new[] { 161, 162, 163, 164, 165 })]
|
|
||||||
[TestCase("Shortland.Street.S22E5363-E5366.HDTV.x264-FiHTV", "Shortland Street", 22, new[] { 5363, 5364, 5365, 5366 })]
|
|
||||||
public void TitleParse_multi(string postTitle, string title, int season, int[] episodes)
|
|
||||||
{
|
|
||||||
var result = Parser.Parser.ParseTitle(postTitle);
|
|
||||||
result.SeasonNumber.Should().Be(season);
|
|
||||||
result.EpisodeNumbers.Should().BeEquivalentTo(episodes);
|
|
||||||
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
|
|
||||||
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
|
|
||||||
result.FullSeason.Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[TestCase("Conan 2011 04 18 Emma Roberts HDTV XviD BFF", "Conan", 2011, 04, 18)]
|
|
||||||
[TestCase("The Tonight Show With Jay Leno 2011 04 15 1080i HDTV DD5 1 MPEG2 TrollHD", "The Tonight Show With Jay Leno", 2011, 04, 15)]
|
|
||||||
[TestCase("The.Daily.Show.2010.10.11.Johnny.Knoxville.iTouch-MW", "The.Daily.Show", 2010, 10, 11)]
|
|
||||||
[TestCase("The Daily Show - 2011-04-12 - Gov. Deval Patrick", "The.Daily.Show", 2011, 04, 12)]
|
|
||||||
[TestCase("2011.01.10 - Denis Leary - HD TV.mkv", "", 2011, 1, 10)]
|
|
||||||
[TestCase("2011.03.13 - Denis Leary - HD TV.mkv", "", 2011, 3, 13)]
|
|
||||||
[TestCase("The Tonight Show with Jay Leno - 2011-06-16 - Larry David, \"Bachelorette\" Ashley Hebert, Pitbull with Ne-Yo", "The Tonight Show with Jay Leno", 2011, 6, 16)]
|
|
||||||
[TestCase("2020.NZ.2012.16.02.PDTV.XviD-C4TV", "2020nz", 2012, 2, 16)]
|
|
||||||
[TestCase("2020.NZ.2012.13.02.PDTV.XviD-C4TV", "2020nz", 2012, 2, 13)]
|
|
||||||
[TestCase("2020.NZ.2011.12.02.PDTV.XviD-C4TV", "2020nz", 2011, 12, 2)]
|
|
||||||
public void parse_daily_episodes(string postTitle, string title, int year, int month, int day)
|
|
||||||
{
|
|
||||||
var result = Parser.Parser.ParseTitle(postTitle);
|
|
||||||
var airDate = new DateTime(year, month, day);
|
|
||||||
result.Should().NotBeNull();
|
|
||||||
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
|
|
||||||
result.AirDate.Should().Be(airDate.ToString(Episode.AIR_DATE_FORMAT));
|
|
||||||
result.EpisodeNumbers.Should().BeEmpty();
|
|
||||||
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
|
|
||||||
result.FullSeason.Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase("[SubDESU]_High_School_DxD_07_(1280x720_x264-AAC)_[6B7FD717]", "High School DxD", 7, 0, 0)]
|
[TestCase("[SubDESU]_High_School_DxD_07_(1280x720_x264-AAC)_[6B7FD717]", "High School DxD", 7, 0, 0)]
|
||||||
[TestCase("[Chihiro]_Working!!_-_06_[848x480_H.264_AAC][859EEAFA]", "Working!!", 6, 0, 0)]
|
[TestCase("[Chihiro]_Working!!_-_06_[848x480_H.264_AAC][859EEAFA]", "Working!!", 6, 0, 0)]
|
||||||
[TestCase("[Commie]_Senki_Zesshou_Symphogear_-_11_[65F220B4]", "Senki_Zesshou_Symphogear", 11, 0, 0)]
|
[TestCase("[Commie]_Senki_Zesshou_Symphogear_-_11_[65F220B4]", "Senki_Zesshou_Symphogear", 11, 0, 0)]
|
||||||
|
@ -232,138 +56,6 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||||
result.FullSeason.Should().BeFalse();
|
result.FullSeason.Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("Conan {year} {month} {day} Emma Roberts HDTV XviD BFF")]
|
|
||||||
[TestCase("The Tonight Show With Jay Leno {year} {month} {day} 1080i HDTV DD5 1 MPEG2 TrollHD")]
|
|
||||||
[TestCase("The.Daily.Show.{year}.{month}.{day}.Johnny.Knoxville.iTouch-MW")]
|
|
||||||
[TestCase("The Daily Show - {year}-{month}-{day} - Gov. Deval Patrick")]
|
|
||||||
[TestCase("{year}.{month}.{day} - Denis Leary - HD TV.mkv")]
|
|
||||||
[TestCase("The Tonight Show with Jay Leno - {year}-{month}-{day} - Larry David, \"Bachelorette\" Ashley Hebert, Pitbull with Ne-Yo")]
|
|
||||||
[TestCase("2020.NZ.{year}.{month}.{day}.PDTV.XviD-C4TV")]
|
|
||||||
public void should_not_accept_ancient_daily_series(string title)
|
|
||||||
{
|
|
||||||
var yearTooLow = title.Expand(new { year = 1950, month = 10, day = 14 });
|
|
||||||
Parser.Parser.ParseTitle(yearTooLow).Should().BeNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase("Conan {year} {month} {day} Emma Roberts HDTV XviD BFF")]
|
|
||||||
[TestCase("The Tonight Show With Jay Leno {year} {month} {day} 1080i HDTV DD5 1 MPEG2 TrollHD")]
|
|
||||||
[TestCase("The.Daily.Show.{year}.{month}.{day}.Johnny.Knoxville.iTouch-MW")]
|
|
||||||
[TestCase("The Daily Show - {year}-{month}-{day} - Gov. Deval Patrick")]
|
|
||||||
[TestCase("{year}.{month}.{day} - Denis Leary - HD TV.mkv")]
|
|
||||||
[TestCase("The Tonight Show with Jay Leno - {year}-{month}-{day} - Larry David, \"Bachelorette\" Ashley Hebert, Pitbull with Ne-Yo")]
|
|
||||||
[TestCase("2020.NZ.{year}.{month}.{day}.PDTV.XviD-C4TV")]
|
|
||||||
public void should_not_accept_future_dates(string title)
|
|
||||||
{
|
|
||||||
var twoDaysFromNow = DateTime.Now.AddDays(2);
|
|
||||||
|
|
||||||
var validDate = title.Expand(new { year = twoDaysFromNow.Year, month = twoDaysFromNow.Month.ToString("00"), day = twoDaysFromNow.Day.ToString("00") });
|
|
||||||
|
|
||||||
Parser.Parser.ParseTitle(validDate).Should().BeNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void parse_daily_should_fail_if_episode_is_far_in_future()
|
|
||||||
{
|
|
||||||
var title = string.Format("{0:yyyy.MM.dd} - Denis Leary - HD TV.mkv", DateTime.Now.AddDays(2));
|
|
||||||
|
|
||||||
Parser.Parser.ParseTitle(title).Should().BeNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase("30.Rock.Season.04.HDTV.XviD-DIMENSION", "30.Rock", 4)]
|
|
||||||
[TestCase("Parks.and.Recreation.S02.720p.x264-DIMENSION", "Parks.and.Recreation", 2)]
|
|
||||||
[TestCase("The.Office.US.S03.720p.x264-DIMENSION", "The.Office.US", 3)]
|
|
||||||
[TestCase(@"Sons.of.Anarchy.S03.720p.BluRay-CLUE\REWARD", "Sons.of.Anarchy", 3)]
|
|
||||||
[TestCase("Adventure Time S02 720p HDTV x264 CRON", "Adventure Time", 2)]
|
|
||||||
[TestCase("Sealab.2021.S04.iNTERNAL.DVDRip.XviD-VCDVaULT", "Sealab 2021", 4)]
|
|
||||||
public void full_season_release_parse(string postTitle, string title, int season)
|
|
||||||
{
|
|
||||||
var result = Parser.Parser.ParseTitle(postTitle);
|
|
||||||
result.SeasonNumber.Should().Be(season);
|
|
||||||
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
|
|
||||||
result.EpisodeNumbers.Should().BeEmpty();
|
|
||||||
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
|
|
||||||
result.FullSeason.Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase("Conan", "conan")]
|
|
||||||
[TestCase("The Tonight Show With Jay Leno", "tonightshowwithjayleno")]
|
|
||||||
[TestCase("The.Daily.Show", "dailyshow")]
|
|
||||||
[TestCase("Castle (2009)", "castle2009")]
|
|
||||||
[TestCase("Parenthood.2010", "parenthood2010")]
|
|
||||||
[TestCase("Law_and_Order_SVU", "lawordersvu")]
|
|
||||||
public void series_name_normalize(string parsedSeriesName, string seriesName)
|
|
||||||
{
|
|
||||||
var result = parsedSeriesName.CleanSeriesTitle();
|
|
||||||
result.Should().Be(seriesName);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase("CaPitAl", "capital")]
|
|
||||||
[TestCase("peri.od", "period")]
|
|
||||||
[TestCase("this.^&%^**$%@#$!That", "thisthat")]
|
|
||||||
[TestCase("test/test", "testtest")]
|
|
||||||
[TestCase("90210", "90210")]
|
|
||||||
[TestCase("24", "24")]
|
|
||||||
public void Normalize_Title(string dirty, string clean)
|
|
||||||
{
|
|
||||||
var result = dirty.CleanSeriesTitle();
|
|
||||||
result.Should().Be(clean);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase("the")]
|
|
||||||
[TestCase("and")]
|
|
||||||
[TestCase("or")]
|
|
||||||
[TestCase("a")]
|
|
||||||
[TestCase("an")]
|
|
||||||
[TestCase("of")]
|
|
||||||
public void Normalize_removed_common_words(string word)
|
|
||||||
{
|
|
||||||
var dirtyFormat = new[]
|
|
||||||
{
|
|
||||||
"word.{0}.word",
|
|
||||||
"word {0} word",
|
|
||||||
"word-{0}-word",
|
|
||||||
"{0}.word.word",
|
|
||||||
"{0}-word-word",
|
|
||||||
"{0} word word",
|
|
||||||
"word.word.{0}",
|
|
||||||
"word-word-{0}",
|
|
||||||
"word-word {0}",
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (var s in dirtyFormat)
|
|
||||||
{
|
|
||||||
var dirty = String.Format(s, word);
|
|
||||||
dirty.CleanSeriesTitle().Should().Be("wordword");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase("the")]
|
|
||||||
[TestCase("and")]
|
|
||||||
[TestCase("or")]
|
|
||||||
[TestCase("a")]
|
|
||||||
[TestCase("an")]
|
|
||||||
[TestCase("of")]
|
|
||||||
public void Normalize_not_removed_common_words_in_the_middle(string word)
|
|
||||||
{
|
|
||||||
var dirtyFormat = new[]
|
|
||||||
{
|
|
||||||
"word.{0}word",
|
|
||||||
"word {0}word",
|
|
||||||
"word-{0}word",
|
|
||||||
"word{0}.word",
|
|
||||||
"word{0}-word",
|
|
||||||
"word{0}-word",
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (var s in dirtyFormat)
|
|
||||||
{
|
|
||||||
var dirty = String.Format(s, word);
|
|
||||||
dirty.CleanSeriesTitle().Should().Be(("word" + word.ToLower() + "word"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase("Chuck - 4x05 - Title", "Chuck")]
|
[TestCase("Chuck - 4x05 - Title", "Chuck")]
|
||||||
[TestCase("Law & Order - 4x05 - Title", "laworder")]
|
[TestCase("Law & Order - 4x05 - Title", "laworder")]
|
||||||
[TestCase("Bad Format", "badformat")]
|
[TestCase("Bad Format", "badformat")]
|
||||||
|
@ -376,115 +68,10 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||||
[TestCase("Hawaii Five 0", "hawaiifive0")]
|
[TestCase("Hawaii Five 0", "hawaiifive0")]
|
||||||
[TestCase("Match of the Day", "matchday")]
|
[TestCase("Match of the Day", "matchday")]
|
||||||
[TestCase("Match of the Day 2", "matchday2")]
|
[TestCase("Match of the Day 2", "matchday2")]
|
||||||
public void parse_series_name(string postTitle, string title)
|
public void should_parse_series_name(string postTitle, string title)
|
||||||
{
|
{
|
||||||
var result = Parser.Parser.ParseSeriesName(postTitle);
|
var result = Parser.Parser.ParseSeriesName(postTitle);
|
||||||
result.Should().Be(title.CleanSeriesTitle());
|
result.Should().Be(title.CleanSeriesTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("Castle.2009.S01E14.English.HDTV.XviD-LOL", Language.English)]
|
|
||||||
[TestCase("Castle.2009.S01E14.French.HDTV.XviD-LOL", Language.French)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Spanish.HDTV.XviD-LOL", Language.Spanish)]
|
|
||||||
[TestCase("Castle.2009.S01E14.German.HDTV.XviD-LOL", Language.German)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Germany.HDTV.XviD-LOL", Language.English)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Italian.HDTV.XviD-LOL", Language.Italian)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Danish.HDTV.XviD-LOL", Language.Danish)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Dutch.HDTV.XviD-LOL", Language.Dutch)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Japanese.HDTV.XviD-LOL", Language.Japanese)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Cantonese.HDTV.XviD-LOL", Language.Cantonese)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Mandarin.HDTV.XviD-LOL", Language.Mandarin)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Korean.HDTV.XviD-LOL", Language.Korean)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Russian.HDTV.XviD-LOL", Language.Russian)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Polish.HDTV.XviD-LOL", Language.Polish)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Vietnamese.HDTV.XviD-LOL", Language.Vietnamese)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Swedish.HDTV.XviD-LOL", Language.Swedish)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Norwegian.HDTV.XviD-LOL", Language.Norwegian)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Finnish.HDTV.XviD-LOL", Language.Finnish)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Turkish.HDTV.XviD-LOL", Language.Turkish)]
|
|
||||||
[TestCase("Castle.2009.S01E14.Portuguese.HDTV.XviD-LOL", Language.Portuguese)]
|
|
||||||
[TestCase("Castle.2009.S01E14.HDTV.XviD-LOL", Language.English)]
|
|
||||||
[TestCase("person.of.interest.1x19.ita.720p.bdmux.x264-novarip", Language.Italian)]
|
|
||||||
[TestCase("Salamander.S01E01.FLEMISH.HDTV.x264-BRiGAND", Language.Flemish)]
|
|
||||||
[TestCase("H.Polukatoikia.S03E13.Greek.PDTV.XviD-Ouzo", Language.Greek)]
|
|
||||||
[TestCase("Burn.Notice.S04E15.Brotherly.Love.GERMAN.DUBBED.WS.WEBRiP.XviD.REPACK-TVP", Language.German)]
|
|
||||||
[TestCase("Ray Donovan - S01E01.720p.HDtv.x264-Evolve (NLsub)", Language.Norwegian)]
|
|
||||||
[TestCase("Shield,.The.1x13.Tueurs.De.Flics.FR.DVDRip.XviD", Language.French)]
|
|
||||||
[TestCase("True.Detective.S01E01.1080p.WEB-DL.Rus.Eng.TVKlondike", Language.Russian)]
|
|
||||||
public void parse_language(string postTitle, Language language)
|
|
||||||
{
|
|
||||||
var result = Parser.Parser.ParseTitle(postTitle);
|
|
||||||
result.Language.Should().Be(language);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase("Hawaii Five 0 S01 720p WEB DL DD5 1 H 264 NT", "Hawaii Five 0", 1)]
|
|
||||||
[TestCase("30 Rock S03 WS PDTV XviD FUtV", "30 Rock", 3)]
|
|
||||||
[TestCase("The Office Season 4 WS PDTV XviD FUtV", "The Office", 4)]
|
|
||||||
[TestCase("Eureka Season 1 720p WEB DL DD 5 1 h264 TjHD", "Eureka", 1)]
|
|
||||||
[TestCase("The Office Season4 WS PDTV XviD FUtV", "The Office", 4)]
|
|
||||||
[TestCase("Eureka S 01 720p WEB DL DD 5 1 h264 TjHD", "Eureka", 1)]
|
|
||||||
[TestCase("Doctor Who Confidential Season 3", "Doctor Who Confidential", 3)]
|
|
||||||
public void parse_season_info(string postTitle, string seriesName, int seasonNumber)
|
|
||||||
{
|
|
||||||
var result = Parser.Parser.ParseTitle(postTitle);
|
|
||||||
|
|
||||||
result.SeriesTitle.Should().Be(seriesName.CleanSeriesTitle());
|
|
||||||
result.SeasonNumber.Should().Be(seasonNumber);
|
|
||||||
result.FullSeason.Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase("Acropolis Now S05 EXTRAS DVDRip XviD RUNNER")]
|
|
||||||
[TestCase("Punky Brewster S01 EXTRAS DVDRip XviD RUNNER")]
|
|
||||||
[TestCase("Instant Star S03 EXTRAS DVDRip XviD OSiTV")]
|
|
||||||
public void parse_season_extras(string postTitle)
|
|
||||||
{
|
|
||||||
var result = Parser.Parser.ParseTitle(postTitle);
|
|
||||||
|
|
||||||
result.Should().BeNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase("Lie.to.Me.S03.SUBPACK.DVDRip.XviD-REWARD")]
|
|
||||||
[TestCase("The.Middle.S02.SUBPACK.DVDRip.XviD-REWARD")]
|
|
||||||
[TestCase("CSI.S11.SUBPACK.DVDRip.XviD-REWARD")]
|
|
||||||
public void parse_season_subpack(string postTitle)
|
|
||||||
{
|
|
||||||
var result = Parser.Parser.ParseTitle(postTitle);
|
|
||||||
|
|
||||||
result.Should().BeNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase("76El6LcgLzqb426WoVFg1vVVVGx4uCYopQkfjmLe")]
|
|
||||||
[TestCase("Vrq6e1Aba3U amCjuEgV5R2QvdsLEGYF3YQAQkw8")]
|
|
||||||
[TestCase("TDAsqTea7k4o6iofVx3MQGuDK116FSjPobMuh8oB")]
|
|
||||||
[TestCase("yp4nFodAAzoeoRc467HRh1mzuT17qeekmuJ3zFnL")]
|
|
||||||
[TestCase("oxXo8S2272KE1 lfppvxo3iwEJBrBmhlQVK1gqGc")]
|
|
||||||
[TestCase("dPBAtu681Ycy3A4NpJDH6kNVQooLxqtnsW1Umfiv")]
|
|
||||||
[TestCase("password - \"bdc435cb-93c4-4902-97ea-ca00568c3887.337\" yEnc")]
|
|
||||||
public void should_not_parse_crap(string title)
|
|
||||||
{
|
|
||||||
Parser.Parser.ParseTitle(title).Should().BeNull();
|
|
||||||
ExceptionVerification.IgnoreWarns();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase("Castle.2009.S01E14.English.HDTV.XviD-LOL", "LOL")]
|
|
||||||
[TestCase("Castle 2009 S01E14 English HDTV XviD LOL", "LOL")]
|
|
||||||
[TestCase("Acropolis Now S05 EXTRAS DVDRip XviD RUNNER", "RUNNER")]
|
|
||||||
[TestCase("Punky.Brewster.S01.EXTRAS.DVDRip.XviD-RUNNER", "RUNNER")]
|
|
||||||
[TestCase("2020.NZ.2011.12.02.PDTV.XviD-C4TV", "C4TV")]
|
|
||||||
[TestCase("The.Office.S03E115.DVDRip.XviD-OSiTV", "OSiTV")]
|
|
||||||
[TestCase("The Office - S01E01 - Pilot [HTDV-480p]", "DRONE")]
|
|
||||||
[TestCase("The Office - S01E01 - Pilot [HTDV-720p]", "DRONE")]
|
|
||||||
[TestCase("The Office - S01E01 - Pilot [HTDV-1080p]", "DRONE")]
|
|
||||||
public void parse_releaseGroup(string title, string expected)
|
|
||||||
{
|
|
||||||
Parser.Parser.ParseReleaseGroup(title).Should().Be(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_include_extension_in_releaseGroup()
|
|
||||||
{
|
|
||||||
const string path = @"C:\Test\Doctor.Who.2005.s01e01.internal.bdrip.x264-archivist.mkv";
|
|
||||||
|
|
||||||
Parser.Parser.ParsePath(path).ReleaseGroup.Should().Be("archivist");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Expansive;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ParserTests
|
||||||
|
{
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class PathParserFixture : CoreTest
|
||||||
|
{
|
||||||
|
[TestCase(@"z:\tv shows\battlestar galactica (2003)\Season 3\S03E05 - Collaborators.mkv", 3, 5)]
|
||||||
|
[TestCase(@"z:\tv shows\modern marvels\Season 16\S16E03 - The Potato.mkv", 16, 3)]
|
||||||
|
[TestCase(@"z:\tv shows\robot chicken\Specials\S00E16 - Dear Consumer - SD TV.avi", 0, 16)]
|
||||||
|
[TestCase(@"D:\shares\TV Shows\Parks And Recreation\Season 2\S02E21 - 94 Meetings - 720p TV.mkv", 2, 21)]
|
||||||
|
[TestCase(@"D:\shares\TV Shows\Battlestar Galactica (2003)\Season 2\S02E21.avi", 2, 21)]
|
||||||
|
[TestCase("C:/Test/TV/Chuck.4x05.HDTV.XviD-LOL", 4, 5)]
|
||||||
|
[TestCase(@"P:\TV Shows\House\Season 6\S06E13 - 5 to 9 - 720p BluRay.mkv", 6, 13)]
|
||||||
|
[TestCase(@"S:\TV Drop\House - 10x11 - Title [SDTV]\1011 - Title.avi", 10, 11)]
|
||||||
|
[TestCase(@"/TV Drop/House - 10x11 - Title [SDTV]/1011 - Title.avi", 10, 11)]
|
||||||
|
[TestCase(@"S:\TV Drop\King of the Hill - 10x12 - 24 Hour Propane People [SDTV]\1012 - 24 Hour Propane People.avi", 10, 12)]
|
||||||
|
[TestCase(@"/TV Drop/King of the Hill - 10x12 - 24 Hour Propane People [SDTV]/1012 - 24 Hour Propane People.avi", 10, 12)]
|
||||||
|
[TestCase(@"S:\TV Drop\King of the Hill - 10x12 - 24 Hour Propane People [SDTV]\Hour Propane People.avi", 10, 12)]
|
||||||
|
[TestCase(@"/TV Drop/King of the Hill - 10x12 - 24 Hour Propane People [SDTV]/Hour Propane People.avi", 10, 12)]
|
||||||
|
[TestCase(@"E:\Downloads\tv\The.Big.Bang.Theory.S01E01.720p.HDTV\ajifajjjeaeaeqwer_eppj.avi", 1, 1)]
|
||||||
|
[TestCase(@"C:\Test\Unsorted\The.Big.Bang.Theory.S01E01.720p.HDTV\tbbt101.avi", 1, 1)]
|
||||||
|
[TestCase(@"C:\Test\Unsorted\Terminator.The.Sarah.Connor.Chronicles.S02E19.720p.BluRay.x264-SiNNERS-RP\ba27283b17c00d01193eacc02a8ba98eeb523a76.mkv", 2, 19)]
|
||||||
|
[TestCase(@"C:\Test\Unsorted\Terminator.The.Sarah.Connor.Chronicles.S02E18.720p.BluRay.x264-SiNNERS-RP\45a55debe3856da318cc35882ad07e43cd32fd15.mkv", 2, 18)]
|
||||||
|
public void should_parse_from_path(string path, int season, int episode)
|
||||||
|
{
|
||||||
|
var result = Parser.Parser.ParsePath(path);
|
||||||
|
result.EpisodeNumbers.Should().HaveCount(1);
|
||||||
|
result.SeasonNumber.Should().Be(season);
|
||||||
|
result.EpisodeNumbers[0].Should().Be(episode);
|
||||||
|
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
|
||||||
|
result.FullSeason.Should().BeFalse();
|
||||||
|
|
||||||
|
ExceptionVerification.IgnoreWarns();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ParserTests
|
||||||
|
{
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class ReleaseGroupParserFixture : CoreTest
|
||||||
|
{
|
||||||
|
[TestCase("Castle.2009.S01E14.English.HDTV.XviD-LOL", "LOL")]
|
||||||
|
[TestCase("Castle 2009 S01E14 English HDTV XviD LOL", "LOL")]
|
||||||
|
[TestCase("Acropolis Now S05 EXTRAS DVDRip XviD RUNNER", "RUNNER")]
|
||||||
|
[TestCase("Punky.Brewster.S01.EXTRAS.DVDRip.XviD-RUNNER", "RUNNER")]
|
||||||
|
[TestCase("2020.NZ.2011.12.02.PDTV.XviD-C4TV", "C4TV")]
|
||||||
|
[TestCase("The.Office.S03E115.DVDRip.XviD-OSiTV", "OSiTV")]
|
||||||
|
[TestCase("The Office - S01E01 - Pilot [HTDV-480p]", "DRONE")]
|
||||||
|
[TestCase("The Office - S01E01 - Pilot [HTDV-720p]", "DRONE")]
|
||||||
|
[TestCase("The Office - S01E01 - Pilot [HTDV-1080p]", "DRONE")]
|
||||||
|
public void should_parse_release_group(string title, string expected)
|
||||||
|
{
|
||||||
|
Parser.Parser.ParseReleaseGroup(title).Should().Be(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_include_extension_in_release_roup()
|
||||||
|
{
|
||||||
|
const string path = @"C:\Test\Doctor.Who.2005.s01e01.internal.bdrip.x264-archivist.mkv";
|
||||||
|
|
||||||
|
Parser.Parser.ParsePath(path).ReleaseGroup.Should().Be("archivist");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ParserTests
|
||||||
|
{
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class SeasonParserFixture : CoreTest
|
||||||
|
{
|
||||||
|
[TestCase("30.Rock.Season.04.HDTV.XviD-DIMENSION", "30.Rock", 4)]
|
||||||
|
[TestCase("Parks.and.Recreation.S02.720p.x264-DIMENSION", "Parks.and.Recreation", 2)]
|
||||||
|
[TestCase("The.Office.US.S03.720p.x264-DIMENSION", "The.Office.US", 3)]
|
||||||
|
[TestCase(@"Sons.of.Anarchy.S03.720p.BluRay-CLUE\REWARD", "Sons.of.Anarchy", 3)]
|
||||||
|
[TestCase("Adventure Time S02 720p HDTV x264 CRON", "Adventure Time", 2)]
|
||||||
|
[TestCase("Sealab.2021.S04.iNTERNAL.DVDRip.XviD-VCDVaULT", "Sealab 2021", 4)]
|
||||||
|
[TestCase("Hawaii Five 0 S01 720p WEB DL DD5 1 H 264 NT", "Hawaii Five 0", 1)]
|
||||||
|
[TestCase("30 Rock S03 WS PDTV XviD FUtV", "30 Rock", 3)]
|
||||||
|
[TestCase("The Office Season 4 WS PDTV XviD FUtV", "The Office", 4)]
|
||||||
|
[TestCase("Eureka Season 1 720p WEB DL DD 5 1 h264 TjHD", "Eureka", 1)]
|
||||||
|
[TestCase("The Office Season4 WS PDTV XviD FUtV", "The Office", 4)]
|
||||||
|
[TestCase("Eureka S 01 720p WEB DL DD 5 1 h264 TjHD", "Eureka", 1)]
|
||||||
|
[TestCase("Doctor Who Confidential Season 3", "Doctor Who Confidential", 3)]
|
||||||
|
public void should_parsefull_season_release(string postTitle, string title, int season)
|
||||||
|
{
|
||||||
|
var result = Parser.Parser.ParseTitle(postTitle);
|
||||||
|
result.SeasonNumber.Should().Be(season);
|
||||||
|
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
|
||||||
|
result.EpisodeNumbers.Should().BeEmpty();
|
||||||
|
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
|
||||||
|
result.FullSeason.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("Acropolis Now S05 EXTRAS DVDRip XviD RUNNER")]
|
||||||
|
[TestCase("Punky Brewster S01 EXTRAS DVDRip XviD RUNNER")]
|
||||||
|
[TestCase("Instant Star S03 EXTRAS DVDRip XviD OSiTV")]
|
||||||
|
public void should_parse_season_extras(string postTitle)
|
||||||
|
{
|
||||||
|
var result = Parser.Parser.ParseTitle(postTitle);
|
||||||
|
|
||||||
|
result.Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("Lie.to.Me.S03.SUBPACK.DVDRip.XviD-REWARD")]
|
||||||
|
[TestCase("The.Middle.S02.SUBPACK.DVDRip.XviD-REWARD")]
|
||||||
|
[TestCase("CSI.S11.SUBPACK.DVDRip.XviD-REWARD")]
|
||||||
|
public void should_parse_season_subpack(string postTitle)
|
||||||
|
{
|
||||||
|
var result = Parser.Parser.ParseTitle(postTitle);
|
||||||
|
|
||||||
|
result.Should().BeNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ParserTests
|
||||||
|
{
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class SingleEpisodeParserFixture : CoreTest
|
||||||
|
{
|
||||||
|
[TestCase("Sonny.With.a.Chance.S02E15", "Sonny.With.a.Chance", 2, 15)]
|
||||||
|
[TestCase("Two.and.a.Half.Me.103.720p.HDTV.X264-DIMENSION", "Two.and.a.Half.Me", 1, 3)]
|
||||||
|
[TestCase("Two.and.a.Half.Me.113.720p.HDTV.X264-DIMENSION", "Two.and.a.Half.Me", 1, 13)]
|
||||||
|
[TestCase("Two.and.a.Half.Me.1013.720p.HDTV.X264-DIMENSION", "Two.and.a.Half.Me", 10, 13)]
|
||||||
|
[TestCase("Chuck.4x05.HDTV.XviD-LOL", "Chuck", 4, 5)]
|
||||||
|
[TestCase("The.Girls.Next.Door.S03E06.DVDRip.XviD-WiDE", "The.Girls.Next.Door", 3, 6)]
|
||||||
|
[TestCase("Degrassi.S10E27.WS.DSR.XviD-2HD", "Degrassi", 10, 27)]
|
||||||
|
[TestCase("Parenthood.2010.S02E14.HDTV.XviD-LOL", "Parenthood 2010", 2, 14)]
|
||||||
|
[TestCase("Hawaii Five 0 S01E19 720p WEB DL DD5 1 H 264 NT", "Hawaii Five 0", 1, 19)]
|
||||||
|
[TestCase("The Event S01E14 A Message Back 720p WEB DL DD5 1 H264 SURFER", "The Event", 1, 14)]
|
||||||
|
[TestCase("Adam Hills In Gordon St Tonight S01E07 WS PDTV XviD FUtV", "Adam Hills In Gordon St Tonight", 1, 7)]
|
||||||
|
[TestCase("Adam Hills In Gordon St Tonight S01E07 WS PDTV XviD FUtV", "Adam Hills In Gordon St Tonight", 1, 7)]
|
||||||
|
[TestCase("Adventure.Inc.S03E19.DVDRip.XviD-OSiTV", "Adventure.Inc", 3, 19)]
|
||||||
|
[TestCase("S03E09 WS PDTV XviD FUtV", "", 3, 9)]
|
||||||
|
[TestCase("5x10 WS PDTV XviD FUtV", "", 5, 10)]
|
||||||
|
[TestCase("Castle.2009.S01E14.HDTV.XviD-LOL", "Castle 2009", 1, 14)]
|
||||||
|
[TestCase("Pride.and.Prejudice.1995.S03E20.HDTV.XviD-LOL", "Pride and Prejudice 1995", 3, 20)]
|
||||||
|
[TestCase("The.Office.S03E115.DVDRip.XviD-OSiTV", "The.Office", 3, 115)]
|
||||||
|
[TestCase(@"Parks and Recreation - S02E21 - 94 Meetings - 720p TV.mkv", "Parks and Recreation", 2, 21)]
|
||||||
|
[TestCase(@"24-7 Penguins-Capitals- Road to the NHL Winter Classic - S01E03 - Episode 3.mkv", "24-7 Penguins-Capitals- Road to the NHL Winter Classic", 1, 3)]
|
||||||
|
[TestCase("Adventure.Inc.S03E19.DVDRip.\"XviD\"-OSiTV", "Adventure.Inc", 3, 19)]
|
||||||
|
[TestCase("Hawaii Five-0 (2010) - 1x05 - Nalowale (Forgotten/Missing)", "Hawaii Five-0 (2010)", 1, 5)]
|
||||||
|
[TestCase("Hawaii Five-0 (2010) - 1x05 - Title", "Hawaii Five-0 (2010)", 1, 5)]
|
||||||
|
[TestCase("House - S06E13 - 5 to 9 [DVD]", "House", 6, 13)]
|
||||||
|
[TestCase("The Mentalist - S02E21 - 18-5-4", "The Mentalist", 2, 21)]
|
||||||
|
[TestCase("Breaking.In.S01E07.21.0.Jump.Street.720p.WEB-DL.DD5.1.h.264-KiNGS", "Breaking In", 1, 7)]
|
||||||
|
[TestCase("CSI.525", "CSI", 5, 25)]
|
||||||
|
[TestCase("King of the Hill - 10x12 - 24 Hour Propane People [SDTV]", "King of the Hill", 10, 12)]
|
||||||
|
[TestCase("Brew Masters S01E06 3 Beers For Batali DVDRip XviD SPRiNTER", "Brew Masters", 1, 6)]
|
||||||
|
[TestCase("24 7 Flyers Rangers Road to the NHL Winter Classic Part01 720p HDTV x264 ORENJI", "24 7 Flyers Rangers Road to the NHL Winter Classic", 1, 1)]
|
||||||
|
[TestCase("24 7 Flyers Rangers Road to the NHL Winter Classic Part 02 720p HDTV x264 ORENJI", "24 7 Flyers Rangers Road to the NHL Winter Classic", 1, 2)]
|
||||||
|
[TestCase("24-7 Flyers-Rangers- Road to the NHL Winter Classic - S01E01 - Part 1", "24 7 Flyers Rangers Road to the NHL Winter Classic", 1, 1)]
|
||||||
|
[TestCase("The.Kennedys.Part.2.DSR.XviD-SYS", "The Kennedys", 1, 2)]
|
||||||
|
[TestCase("the-pacific-e07-720p", "The Pacific", 1, 7)]
|
||||||
|
[TestCase("S6E02-Unwrapped-(Playing With Food) - [DarkData]", "", 6, 2)]
|
||||||
|
[TestCase("S06E03-Unwrapped-(Number Ones Unwrapped) - [DarkData]", "", 6, 3)]
|
||||||
|
[TestCase("The Mentalist S02E21 18 5 4 720p WEB DL DD5 1 h 264 EbP", "The Mentalist", 2, 21)]
|
||||||
|
[TestCase("01x04 - Halloween, Part 1 - 720p WEB-DL", "", 1, 4)]
|
||||||
|
[TestCase("extras.s03.e05.ws.dvdrip.xvid-m00tv", "Extras", 3, 5)]
|
||||||
|
[TestCase("castle.2009.416.hdtv-lol", "Castle 2009", 4, 16)]
|
||||||
|
[TestCase("hawaii.five-0.2010.217.hdtv-lol", "Hawaii Five-0 (2010)", 2, 17)]
|
||||||
|
[TestCase("Looney Tunes - S1936E18 - I Love to Singa", "Looney Tunes", 1936, 18)]
|
||||||
|
[TestCase("American_Dad!_-_7x6_-_The_Scarlett_Getter_[SDTV]", "American Dad!", 7, 6)]
|
||||||
|
[TestCase("Falling_Skies_-_1x1_-_Live_and_Learn_[HDTV-720p]", "Falling Skies", 1, 1)]
|
||||||
|
[TestCase("Top Gear - 07x03 - 2005.11.70", "Top Gear", 7, 3)]
|
||||||
|
[TestCase("Hatfields and McCoys 2012 Part 1 REPACK 720p HDTV x264 2HD", "Hatfields and McCoys 2012", 1, 1)]
|
||||||
|
[TestCase("Glee.S04E09.Swan.Song.1080p.WEB-DL.DD5.1.H.264-ECI", "Glee", 4, 9)]
|
||||||
|
[TestCase("S08E20 50-50 Carla [DVD]", "", 8, 20)]
|
||||||
|
[TestCase("Cheers S08E20 50-50 Carla [DVD]", "Cheers", 8, 20)]
|
||||||
|
[TestCase("S02E10 6-50 to SLC [SDTV]", "", 2, 10)]
|
||||||
|
[TestCase("Franklin & Bash S02E10 6-50 to SLC [SDTV]", "Franklin & Bash", 2, 10)]
|
||||||
|
[TestCase("The_Big_Bang_Theory_-_6x12_-_The_Egg_Salad_Equivalency_[HDTV-720p]", "The Big Bang Theory", 6, 12)]
|
||||||
|
[TestCase("Top_Gear.19x06.720p_HDTV_x264-FoV", "Top Gear", 19, 6)]
|
||||||
|
[TestCase("Portlandia.S03E10.Alexandra.720p.WEB-DL.AAC2.0.H.264-CROM.mkv", "Portlandia", 3, 10)]
|
||||||
|
[TestCase("(Game of Thrones s03 e - \"Game of Thrones Season 3 Episode 10\"", "Game of Thrones", 3, 10)]
|
||||||
|
[TestCase("House.Hunters.International.S05E607.720p.hdtv.x264", "House.Hunters.International", 5, 607)]
|
||||||
|
[TestCase("Adventure.Time.With.Finn.And.Jake.S01E20.720p.BluRay.x264-DEiMOS", "Adventure.Time.With.Finn.And.Jake", 1, 20)]
|
||||||
|
[TestCase("Hostages.S01E04.2-45.PM.[HDTV-720p].mkv", "Hostages", 1, 4)]
|
||||||
|
[TestCase("S01E04", "", 1, 4)]
|
||||||
|
[TestCase("1x04", "", 1, 4)]
|
||||||
|
[TestCase("10.Things.You.Dont.Know.About.S02E04.Prohibition.HDTV.XviD-AFG", "10 Things You Dont Know About", 2, 4)]
|
||||||
|
[TestCase("30 Rock - S01E01 - Pilot.avi", "30 Rock", 1, 1)]
|
||||||
|
[TestCase("666 Park Avenue - S01E01", "666 Park Avenue", 1, 1)]
|
||||||
|
[TestCase("Warehouse 13 - S01E01", "Warehouse 13", 1, 1)]
|
||||||
|
[TestCase("Don't Trust The B---- in Apartment 23.S01E01", "Don't Trust The B---- in Apartment 23", 1, 1)]
|
||||||
|
[TestCase("Warehouse.13.S01E01", "Warehouse.13", 1, 1)]
|
||||||
|
[TestCase("Dont.Trust.The.B----.in.Apartment.23.S01E01", "Dont.Trust.The.B----.in.Apartment.23", 1, 1)]
|
||||||
|
[TestCase("24 S01E01", "24", 1, 1)]
|
||||||
|
[TestCase("24.S01E01", "24", 1, 1)]
|
||||||
|
[TestCase("Homeland - 2x12 - The Choice [HDTV-1080p].mkv", "Homeland", 2, 12)]
|
||||||
|
[TestCase("Homeland - 2x4 - New Car Smell [HDTV-1080p].mkv", "Homeland", 2, 4)]
|
||||||
|
public void should_parse_single_episode(string postTitle, string title, int seasonNumber, int episodeNumber)
|
||||||
|
{
|
||||||
|
var result = Parser.Parser.ParseTitle(postTitle);
|
||||||
|
result.Should().NotBeNull();
|
||||||
|
result.EpisodeNumbers.Should().HaveCount(1);
|
||||||
|
result.SeasonNumber.Should().Be(seasonNumber);
|
||||||
|
result.EpisodeNumbers.First().Should().Be(episodeNumber);
|
||||||
|
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
|
||||||
|
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
|
||||||
|
result.FullSeason.Should().BeFalse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ namespace NzbDrone.Core.Annotations
|
||||||
Textbox,
|
Textbox,
|
||||||
Password,
|
Password,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Select
|
Select,
|
||||||
|
Path
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,7 @@
|
||||||
using NzbDrone.Core.Datastore;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Blacklisting
|
namespace NzbDrone.Core.Blacklisting
|
||||||
|
@ -6,6 +9,7 @@ namespace NzbDrone.Core.Blacklisting
|
||||||
public interface IBlacklistRepository : IBasicRepository<Blacklist>
|
public interface IBlacklistRepository : IBasicRepository<Blacklist>
|
||||||
{
|
{
|
||||||
bool Blacklisted(string sourceTitle);
|
bool Blacklisted(string sourceTitle);
|
||||||
|
List<Blacklist> BlacklistedBySeries(int seriesId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BlacklistRepository : BasicRepository<Blacklist>, IBlacklistRepository
|
public class BlacklistRepository : BasicRepository<Blacklist>, IBlacklistRepository
|
||||||
|
@ -17,7 +21,12 @@ namespace NzbDrone.Core.Blacklisting
|
||||||
|
|
||||||
public bool Blacklisted(string sourceTitle)
|
public bool Blacklisted(string sourceTitle)
|
||||||
{
|
{
|
||||||
return Query.Any(e => e.SourceTitle.Contains(sourceTitle));
|
return Query.Where(e => e.SourceTitle.Contains(sourceTitle)).Any();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Blacklist> BlacklistedBySeries(int seriesId)
|
||||||
|
{
|
||||||
|
return Query.Where(b => b.SeriesId == seriesId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Tv.Events;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Blacklisting
|
namespace NzbDrone.Core.Blacklisting
|
||||||
{
|
{
|
||||||
|
@ -13,7 +14,7 @@ namespace NzbDrone.Core.Blacklisting
|
||||||
void Delete(int id);
|
void Delete(int id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BlacklistService : IBlacklistService, IHandle<DownloadFailedEvent>, IExecute<ClearBlacklistCommand>
|
public class BlacklistService : IBlacklistService, IExecute<ClearBlacklistCommand>, IHandle<DownloadFailedEvent>, IHandle<SeriesDeletedEvent>
|
||||||
{
|
{
|
||||||
private readonly IBlacklistRepository _blacklistRepository;
|
private readonly IBlacklistRepository _blacklistRepository;
|
||||||
private readonly IRedownloadFailedDownloads _redownloadFailedDownloadService;
|
private readonly IRedownloadFailedDownloads _redownloadFailedDownloadService;
|
||||||
|
@ -39,6 +40,11 @@ namespace NzbDrone.Core.Blacklisting
|
||||||
_blacklistRepository.Delete(id);
|
_blacklistRepository.Delete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Execute(ClearBlacklistCommand message)
|
||||||
|
{
|
||||||
|
_blacklistRepository.Purge();
|
||||||
|
}
|
||||||
|
|
||||||
public void Handle(DownloadFailedEvent message)
|
public void Handle(DownloadFailedEvent message)
|
||||||
{
|
{
|
||||||
var blacklist = new Blacklist
|
var blacklist = new Blacklist
|
||||||
|
@ -55,9 +61,11 @@ namespace NzbDrone.Core.Blacklisting
|
||||||
_redownloadFailedDownloadService.Redownload(message.SeriesId, message.EpisodeIds);
|
_redownloadFailedDownloadService.Redownload(message.SeriesId, message.EpisodeIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(ClearBlacklistCommand message)
|
public void Handle(SeriesDeletedEvent message)
|
||||||
{
|
{
|
||||||
_blacklistRepository.Purge();
|
var blacklisted = _blacklistRepository.BlacklistedBySeries(message.Series.Id);
|
||||||
|
|
||||||
|
_blacklistRepository.DeleteMany(blacklisted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,7 @@ namespace NzbDrone.Core.Configuration
|
||||||
|
|
||||||
public Config Get(string key)
|
public Config Get(string key)
|
||||||
{
|
{
|
||||||
return Query.SingleOrDefault(c => c.Key == key);
|
return Query.Where(c => c.Key == key).SingleOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -54,7 +54,7 @@ namespace NzbDrone.Core.Configuration
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveValues(Dictionary<string, object> configValues)
|
public void SaveConfigDictionary(Dictionary<string, object> configValues)
|
||||||
{
|
{
|
||||||
var allWithDefaults = AllWithDefaults();
|
var allWithDefaults = AllWithDefaults();
|
||||||
|
|
||||||
|
@ -73,69 +73,6 @@ namespace NzbDrone.Core.Configuration
|
||||||
_eventAggregator.PublishEvent(new ConfigSavedEvent());
|
_eventAggregator.PublishEvent(new ConfigSavedEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String SabHost
|
|
||||||
{
|
|
||||||
get { return GetValue("SabHost", "localhost"); }
|
|
||||||
|
|
||||||
set { SetValue("SabHost", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int SabPort
|
|
||||||
{
|
|
||||||
get { return GetValueInt("SabPort", 8080); }
|
|
||||||
|
|
||||||
set { SetValue("SabPort", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public String SabApiKey
|
|
||||||
{
|
|
||||||
get { return GetValue("SabApiKey"); }
|
|
||||||
|
|
||||||
set { SetValue("SabApiKey", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public String SabUsername
|
|
||||||
{
|
|
||||||
get { return GetValue("SabUsername"); }
|
|
||||||
|
|
||||||
set { SetValue("SabUsername", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public String SabPassword
|
|
||||||
{
|
|
||||||
get { return GetValue("SabPassword"); }
|
|
||||||
|
|
||||||
set { SetValue("SabPassword", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public String SabTvCategory
|
|
||||||
{
|
|
||||||
get { return GetValue("SabTvCategory", "tv"); }
|
|
||||||
|
|
||||||
set { SetValue("SabTvCategory", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public SabPriorityType SabRecentTvPriority
|
|
||||||
{
|
|
||||||
get { return GetValueEnum("SabRecentTvPriority", SabPriorityType.Default); }
|
|
||||||
|
|
||||||
set { SetValue("SabRecentTvPriority", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public SabPriorityType SabOlderTvPriority
|
|
||||||
{
|
|
||||||
get { return GetValueEnum("SabOlderTvPriority", SabPriorityType.Default); }
|
|
||||||
|
|
||||||
set { SetValue("SabOlderTvPriority", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SabUseSsl
|
|
||||||
{
|
|
||||||
get { return GetValueBoolean("SabUseSsl", false); }
|
|
||||||
|
|
||||||
set { SetValue("SabUseSsl", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public String DownloadedEpisodesFolder
|
public String DownloadedEpisodesFolder
|
||||||
{
|
{
|
||||||
get { return GetValue(ConfigKey.DownloadedEpisodesFolder.ToString()); }
|
get { return GetValue(ConfigKey.DownloadedEpisodesFolder.ToString()); }
|
||||||
|
@ -155,80 +92,12 @@ namespace NzbDrone.Core.Configuration
|
||||||
set { SetValue("Retention", value); }
|
set { SetValue("Retention", value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public DownloadClientType DownloadClient
|
|
||||||
{
|
|
||||||
get { return GetValueEnum("DownloadClient", DownloadClientType.Blackhole); }
|
|
||||||
|
|
||||||
set { SetValue("DownloadClient", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public string BlackholeFolder
|
|
||||||
{
|
|
||||||
get { return GetValue("BlackholeFolder", String.Empty); }
|
|
||||||
set { SetValue("BlackholeFolder", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public string PneumaticFolder
|
|
||||||
{
|
|
||||||
get { return GetValue("PneumaticFolder", String.Empty); }
|
|
||||||
set { SetValue("PneumaticFolder", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public string RecycleBin
|
public string RecycleBin
|
||||||
{
|
{
|
||||||
get { return GetValue("RecycleBin", String.Empty); }
|
get { return GetValue("RecycleBin", String.Empty); }
|
||||||
set { SetValue("RecycleBin", value); }
|
set { SetValue("RecycleBin", value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public String NzbgetUsername
|
|
||||||
{
|
|
||||||
get { return GetValue("NzbgetUsername", "nzbget"); }
|
|
||||||
|
|
||||||
set { SetValue("NzbgetUsername", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public String NzbgetPassword
|
|
||||||
{
|
|
||||||
get { return GetValue("NzbgetPassword", ""); }
|
|
||||||
|
|
||||||
set { SetValue("NzbgetPassword", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public String NzbgetHost
|
|
||||||
{
|
|
||||||
get { return GetValue("NzbgetHost", "localhost"); }
|
|
||||||
|
|
||||||
set { SetValue("NzbgetHost", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Int32 NzbgetPort
|
|
||||||
{
|
|
||||||
get { return GetValueInt("NzbgetPort", 6789); }
|
|
||||||
|
|
||||||
set { SetValue("NzbgetPort", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public String NzbgetTvCategory
|
|
||||||
{
|
|
||||||
get { return GetValue("NzbgetTvCategory", ""); }
|
|
||||||
|
|
||||||
set { SetValue("NzbgetTvCategory", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public PriorityType NzbgetRecentTvPriority
|
|
||||||
{
|
|
||||||
get { return GetValueEnum("NzbgetRecentTvPriority", PriorityType.Normal); }
|
|
||||||
|
|
||||||
set { SetValue("NzbgetRecentTvPriority", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public PriorityType NzbgetOlderTvPriority
|
|
||||||
{
|
|
||||||
get { return GetValueEnum("NzbgetOlderTvPriority", PriorityType.Normal); }
|
|
||||||
|
|
||||||
set { SetValue("NzbgetOlderTvPriority", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ReleaseRestrictions
|
public string ReleaseRestrictions
|
||||||
{
|
{
|
||||||
get { return GetValue("ReleaseRestrictions", String.Empty).Trim('\r', '\n'); }
|
get { return GetValue("ReleaseRestrictions", String.Empty).Trim('\r', '\n'); }
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Core.Download;
|
|
||||||
using NzbDrone.Core.Download.Clients.Nzbget;
|
|
||||||
using NzbDrone.Core.Download.Clients.Sabnzbd;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Configuration
|
namespace NzbDrone.Core.Configuration
|
||||||
{
|
{
|
||||||
|
@ -10,42 +7,33 @@ namespace NzbDrone.Core.Configuration
|
||||||
{
|
{
|
||||||
IEnumerable<Config> All();
|
IEnumerable<Config> All();
|
||||||
Dictionary<String, Object> AllWithDefaults();
|
Dictionary<String, Object> AllWithDefaults();
|
||||||
String SabHost { get; set; }
|
void SaveConfigDictionary(Dictionary<string, object> configValues);
|
||||||
int SabPort { get; set; }
|
|
||||||
String SabApiKey { get; set; }
|
//Download Client
|
||||||
String SabUsername { get; set; }
|
|
||||||
String SabPassword { get; set; }
|
|
||||||
String SabTvCategory { get; set; }
|
|
||||||
SabPriorityType SabRecentTvPriority { get; set; }
|
|
||||||
SabPriorityType SabOlderTvPriority { get; set; }
|
|
||||||
Boolean SabUseSsl { get; set; }
|
|
||||||
String DownloadedEpisodesFolder { get; set; }
|
String DownloadedEpisodesFolder { get; set; }
|
||||||
bool AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
|
|
||||||
int Retention { get; set; }
|
|
||||||
DownloadClientType DownloadClient { get; set; }
|
|
||||||
string BlackholeFolder { get; set; }
|
|
||||||
string PneumaticFolder { get; set; }
|
|
||||||
string RecycleBin { get; set; }
|
|
||||||
String NzbgetUsername { get; set; }
|
|
||||||
String NzbgetPassword { get; set; }
|
|
||||||
String NzbgetHost { get; set; }
|
|
||||||
Int32 NzbgetPort { get; set; }
|
|
||||||
String NzbgetTvCategory { get; set; }
|
|
||||||
PriorityType NzbgetRecentTvPriority { get; set; }
|
|
||||||
PriorityType NzbgetOlderTvPriority { get; set; }
|
|
||||||
string ReleaseRestrictions { get; set; }
|
|
||||||
Int32 RssSyncInterval { get; set; }
|
|
||||||
Boolean AutoDownloadPropers { get; set; }
|
|
||||||
String DownloadClientWorkingFolders { get; set; }
|
String DownloadClientWorkingFolders { get; set; }
|
||||||
|
|
||||||
|
//Failed Download Handling (Download client)
|
||||||
Boolean AutoRedownloadFailed { get; set; }
|
Boolean AutoRedownloadFailed { get; set; }
|
||||||
Boolean RemoveFailedDownloads { get; set; }
|
Boolean RemoveFailedDownloads { get; set; }
|
||||||
Boolean EnableFailedDownloadHandling { get; set; }
|
Boolean EnableFailedDownloadHandling { get; set; }
|
||||||
|
|
||||||
|
//Media Management
|
||||||
|
Boolean AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
|
||||||
|
String RecycleBin { get; set; }
|
||||||
|
Boolean AutoDownloadPropers { get; set; }
|
||||||
Boolean CreateEmptySeriesFolders { get; set; }
|
Boolean CreateEmptySeriesFolders { get; set; }
|
||||||
void SaveValues(Dictionary<string, object> configValues);
|
|
||||||
|
//Permissions (Media Management)
|
||||||
Boolean SetPermissionsLinux { get; set; }
|
Boolean SetPermissionsLinux { get; set; }
|
||||||
String FileChmod { get; set; }
|
String FileChmod { get; set; }
|
||||||
String FolderChmod { get; set; }
|
String FolderChmod { get; set; }
|
||||||
String ChownUser { get; set; }
|
String ChownUser { get; set; }
|
||||||
String ChownGroup { get; set; }
|
String ChownGroup { get; set; }
|
||||||
|
|
||||||
|
//Indexers
|
||||||
|
Int32 Retention { get; set; }
|
||||||
|
Int32 RssSyncInterval { get; set; }
|
||||||
|
String ReleaseRestrictions { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Web.UI.WebControls;
|
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Cache;
|
using NzbDrone.Common.Cache;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
|
|
@ -73,7 +73,7 @@ namespace NzbDrone.Core.Datastore
|
||||||
|
|
||||||
public TModel Get(int id)
|
public TModel Get(int id)
|
||||||
{
|
{
|
||||||
var model = DataMapper.Query<TModel>().SingleOrDefault(c => c.Id == id);
|
var model = Query.Where(c => c.Id == id).SingleOrDefault();
|
||||||
|
|
||||||
if (model == null)
|
if (model == null)
|
||||||
{
|
{
|
||||||
|
@ -142,23 +142,44 @@ namespace NzbDrone.Core.Datastore
|
||||||
|
|
||||||
public void InsertMany(IList<TModel> models)
|
public void InsertMany(IList<TModel> models)
|
||||||
{
|
{
|
||||||
foreach (var model in models)
|
using (var unitOfWork = new UnitOfWork(() => DataMapper))
|
||||||
{
|
{
|
||||||
Insert(model);
|
unitOfWork.BeginTransaction();
|
||||||
|
|
||||||
|
foreach (var model in models)
|
||||||
|
{
|
||||||
|
unitOfWork.DB.Insert(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
unitOfWork.Commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateMany(IList<TModel> models)
|
public void UpdateMany(IList<TModel> models)
|
||||||
{
|
{
|
||||||
foreach (var model in models)
|
using (var unitOfWork = new UnitOfWork(() => DataMapper))
|
||||||
{
|
{
|
||||||
Update(model);
|
unitOfWork.BeginTransaction();
|
||||||
|
|
||||||
|
foreach (var model in models)
|
||||||
|
{
|
||||||
|
var localModel = model;
|
||||||
|
|
||||||
|
if (model.Id == 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Can't update model with ID 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
unitOfWork.DB.Update(model, c => c.Id == localModel.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
unitOfWork.Commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteMany(List<TModel> models)
|
public void DeleteMany(List<TModel> models)
|
||||||
{
|
{
|
||||||
models.ForEach(Delete);
|
DeleteMany(models.Select(m => m.Id));
|
||||||
}
|
}
|
||||||
|
|
||||||
public TModel Upsert(TModel model)
|
public TModel Upsert(TModel model)
|
||||||
|
@ -179,7 +200,19 @@ namespace NzbDrone.Core.Datastore
|
||||||
|
|
||||||
public void DeleteMany(IEnumerable<int> ids)
|
public void DeleteMany(IEnumerable<int> ids)
|
||||||
{
|
{
|
||||||
ids.ToList().ForEach(Delete);
|
using (var unitOfWork = new UnitOfWork(() => DataMapper))
|
||||||
|
{
|
||||||
|
unitOfWork.BeginTransaction();
|
||||||
|
|
||||||
|
foreach (var id in ids)
|
||||||
|
{
|
||||||
|
var localId = id;
|
||||||
|
|
||||||
|
unitOfWork.DB.Delete<TModel>(c => c.Id == localId);
|
||||||
|
}
|
||||||
|
|
||||||
|
unitOfWork.Commit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Purge()
|
public void Purge()
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(42)]
|
||||||
|
public class add_download_clients_table : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Create.TableForModel("DownloadClients")
|
||||||
|
.WithColumn("Enable").AsBoolean().NotNullable()
|
||||||
|
.WithColumn("Name").AsString().NotNullable()
|
||||||
|
.WithColumn("Implementation").AsString().NotNullable()
|
||||||
|
.WithColumn("Settings").AsString().NotNullable()
|
||||||
|
.WithColumn("ConfigContract").AsString().NotNullable()
|
||||||
|
.WithColumn("Protocol").AsInt32().NotNullable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,197 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Common.Serializer;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(43)]
|
||||||
|
public class convert_config_to_download_clients : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Execute.WithConnection(ConvertToThingyProvder);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConvertToThingyProvder(IDbConnection conn, IDbTransaction tran)
|
||||||
|
{
|
||||||
|
var config = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
using (IDbCommand configCmd = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
configCmd.Transaction = tran;
|
||||||
|
configCmd.CommandText = @"SELECT * FROM Config";
|
||||||
|
using (IDataReader configReader = configCmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
var keyIndex = configReader.GetOrdinal("Key");
|
||||||
|
var valueIndex = configReader.GetOrdinal("Value");
|
||||||
|
|
||||||
|
while (configReader.Read())
|
||||||
|
{
|
||||||
|
var key = configReader.GetString(keyIndex);
|
||||||
|
var value = configReader.GetString(valueIndex);
|
||||||
|
|
||||||
|
config.Add(key.ToLowerInvariant(), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var client = GetConfigValue(config, "DownloadClient", "");
|
||||||
|
|
||||||
|
if (String.IsNullOrWhiteSpace(client))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client.Equals("sabnzbd", StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
var settings = new ClientSettingsForMigration
|
||||||
|
{
|
||||||
|
Host = GetConfigValue(config, "SabHost", "localhost"),
|
||||||
|
Port = GetConfigValue(config, "SabPort", 8080),
|
||||||
|
ApiKey = GetConfigValue(config, "SabApiKey", ""),
|
||||||
|
Username = GetConfigValue(config, "SabUsername", ""),
|
||||||
|
Password = GetConfigValue(config, "SabPassword", ""),
|
||||||
|
TvCategory = GetConfigValue(config, "SabTvCategory", "tv"),
|
||||||
|
RecentTvPriority = GetSabnzbdPriority(GetConfigValue(config, "NzbgetRecentTvPriority", "Default")),
|
||||||
|
OlderTvPriority = GetSabnzbdPriority(GetConfigValue(config, "NzbgetOlderTvPriority", "Default")),
|
||||||
|
UseSsl = GetConfigValue(config, "SabUseSsl", false)
|
||||||
|
};
|
||||||
|
|
||||||
|
AddDownloadClient(conn, tran, "Sabnzbd", "Sabnzbd", settings.ToJson(), "SabnzbdSettings", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (client.Equals("nzbget", StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
var settings = new ClientSettingsForMigration
|
||||||
|
{
|
||||||
|
Host = GetConfigValue(config, "NzbGetHost", "localhost"),
|
||||||
|
Port = GetConfigValue(config, "NzbgetPort", 6789),
|
||||||
|
Username = GetConfigValue(config, "NzbgetUsername", "nzbget"),
|
||||||
|
Password = GetConfigValue(config, "NzbgetPassword", ""),
|
||||||
|
TvCategory = GetConfigValue(config, "NzbgetTvCategory", "tv"),
|
||||||
|
RecentTvPriority = GetNzbgetPriority(GetConfigValue(config, "NzbgetRecentTvPriority", "Normal")),
|
||||||
|
OlderTvPriority = GetNzbgetPriority(GetConfigValue(config, "NzbgetOlderTvPriority", "Normal")),
|
||||||
|
};
|
||||||
|
|
||||||
|
AddDownloadClient(conn, tran, "Nzbget", "Nzbget", settings.ToJson(), "NzbgetSettings", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (client.Equals("pneumatic", StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
var settings = new FolderSettingsForMigration
|
||||||
|
{
|
||||||
|
Folder = GetConfigValue(config, "PneumaticFolder", "")
|
||||||
|
};
|
||||||
|
|
||||||
|
AddDownloadClient(conn, tran, "Pneumatic", "Pneumatic", settings.ToJson(), "FolderSettings", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (client.Equals("blackhole", StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
var settings = new FolderSettingsForMigration
|
||||||
|
{
|
||||||
|
Folder = GetConfigValue(config, "BlackholeFolder", "")
|
||||||
|
};
|
||||||
|
|
||||||
|
AddDownloadClient(conn, tran, "Blackhole", "Blackhole", settings.ToJson(), "FolderSettings", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteOldConfigValues(conn, tran);
|
||||||
|
}
|
||||||
|
|
||||||
|
private T GetConfigValue<T>(Dictionary<string, string> config, string key, T defaultValue)
|
||||||
|
{
|
||||||
|
key = key.ToLowerInvariant();
|
||||||
|
|
||||||
|
if (config.ContainsKey(key))
|
||||||
|
{
|
||||||
|
return (T) Convert.ChangeType(config[key], typeof (T));
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddDownloadClient(IDbConnection conn, IDbTransaction tran, string name, string implementation, string settings,
|
||||||
|
string configContract, int protocol)
|
||||||
|
{
|
||||||
|
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
var text = String.Format("INSERT INTO DownloadClients (Enable, Name, Implementation, Settings, ConfigContract, Protocol) VALUES (1, ?, ?, ?, ?, ?)");
|
||||||
|
updateCmd.AddParameter(name);
|
||||||
|
updateCmd.AddParameter(implementation);
|
||||||
|
updateCmd.AddParameter(settings);
|
||||||
|
updateCmd.AddParameter(configContract);
|
||||||
|
updateCmd.AddParameter(protocol);
|
||||||
|
|
||||||
|
updateCmd.Transaction = tran;
|
||||||
|
updateCmd.CommandText = text;
|
||||||
|
updateCmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteOldConfigValues(IDbConnection conn, IDbTransaction tran)
|
||||||
|
{
|
||||||
|
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
var text = "DELETE FROM Config WHERE [KEY] IN ('nzbgetusername', 'nzbgetpassword', 'nzbgethost', 'nzbgetport', " +
|
||||||
|
"'nzbgettvcategory', 'nzbgetrecenttvpriority', 'nzbgetoldertvpriority', 'sabhost', 'sabport', " +
|
||||||
|
"'sabapikey', 'sabusername', 'sabpassword', 'sabtvcategory', 'sabrecenttvpriority', " +
|
||||||
|
"'saboldertvpriority', 'sabusessl', 'downloadclient', 'blackholefolder', 'pneumaticfolder')";
|
||||||
|
|
||||||
|
updateCmd.Transaction = tran;
|
||||||
|
updateCmd.CommandText = text;
|
||||||
|
updateCmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetSabnzbdPriority(string priority)
|
||||||
|
{
|
||||||
|
return (int)Enum.Parse(typeof(SabnzbdPriorityForMigration), priority, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetNzbgetPriority(string priority)
|
||||||
|
{
|
||||||
|
return (int)Enum.Parse(typeof(NzbGetPriorityForMigration), priority, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ClientSettingsForMigration
|
||||||
|
{
|
||||||
|
public String Host { get; set; }
|
||||||
|
public Int32 Port { get; set; }
|
||||||
|
public String ApiKey { get; set; }
|
||||||
|
public String Username { get; set; }
|
||||||
|
public String Password { get; set; }
|
||||||
|
public String TvCategory { get; set; }
|
||||||
|
public Int32 RecentTvPriority { get; set; }
|
||||||
|
public Int32 OlderTvPriority { get; set; }
|
||||||
|
public Boolean UseSsl { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FolderSettingsForMigration
|
||||||
|
{
|
||||||
|
public String Folder { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SabnzbdPriorityForMigration
|
||||||
|
{
|
||||||
|
Default = -100,
|
||||||
|
Paused = -2,
|
||||||
|
Low = -1,
|
||||||
|
Normal = 0,
|
||||||
|
High = 1,
|
||||||
|
Force = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum NzbGetPriorityForMigration
|
||||||
|
{
|
||||||
|
VeryLow = -100,
|
||||||
|
Low = -50,
|
||||||
|
Normal = 0,
|
||||||
|
High = 50,
|
||||||
|
VeryHigh = 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(44)]
|
||||||
|
public class fix_xbmc_episode_metadata : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
//Convert Episode Metadata to proper type
|
||||||
|
Execute.Sql("UPDATE MetadataFiles " +
|
||||||
|
"SET Type = 2 " +
|
||||||
|
"WHERE Consumer = 'XbmcMetadata' " +
|
||||||
|
"AND EpisodeFileId IS NOT NULL " +
|
||||||
|
"AND Type = 4 " +
|
||||||
|
"AND RelativePath LIKE '%.nfo'");
|
||||||
|
|
||||||
|
//Convert Episode Images to proper type
|
||||||
|
Execute.Sql("UPDATE MetadataFiles " +
|
||||||
|
"SET Type = 5 " +
|
||||||
|
"WHERE Consumer = 'XbmcMetadata' " +
|
||||||
|
"AND EpisodeFileId IS NOT NULL " +
|
||||||
|
"AND Type = 4");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ using NzbDrone.Core.Blacklisting;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.DataAugmentation.Scene;
|
using NzbDrone.Core.DataAugmentation.Scene;
|
||||||
using NzbDrone.Core.Datastore.Converters;
|
using NzbDrone.Core.Datastore.Converters;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Instrumentation;
|
using NzbDrone.Core.Instrumentation;
|
||||||
using NzbDrone.Core.Jobs;
|
using NzbDrone.Core.Jobs;
|
||||||
|
@ -39,6 +40,7 @@ namespace NzbDrone.Core.Datastore
|
||||||
Mapper.Entity<ScheduledTask>().RegisterModel("ScheduledTasks");
|
Mapper.Entity<ScheduledTask>().RegisterModel("ScheduledTasks");
|
||||||
Mapper.Entity<NotificationDefinition>().RegisterModel("Notifications");
|
Mapper.Entity<NotificationDefinition>().RegisterModel("Notifications");
|
||||||
Mapper.Entity<MetadataDefinition>().RegisterModel("Metadata");
|
Mapper.Entity<MetadataDefinition>().RegisterModel("Metadata");
|
||||||
|
Mapper.Entity<DownloadClientDefinition>().RegisterModel("DownloadClients");
|
||||||
|
|
||||||
Mapper.Entity<SceneMapping>().RegisterModel("SceneMappings");
|
Mapper.Entity<SceneMapping>().RegisterModel("SceneMappings");
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace NzbDrone.Core.DecisionEngine
|
||||||
private readonly IParsingService _parsingService;
|
private readonly IParsingService _parsingService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public DownloadDecisionMaker(IEnumerable<IRejectWithReason> specifications, IParsingService parsingService, Logger logger)
|
public DownloadDecisionMaker(IEnumerable<IDecisionEngineSpecification> specifications, IParsingService parsingService, Logger logger)
|
||||||
{
|
{
|
||||||
_specifications = specifications;
|
_specifications = specifications;
|
||||||
_parsingService = parsingService;
|
_parsingService = parsingService;
|
||||||
|
@ -63,6 +63,15 @@ namespace NzbDrone.Core.DecisionEngine
|
||||||
{
|
{
|
||||||
var parsedEpisodeInfo = Parser.Parser.ParseTitle(report.Title);
|
var parsedEpisodeInfo = Parser.Parser.ParseTitle(report.Title);
|
||||||
|
|
||||||
|
if (parsedEpisodeInfo == null || parsedEpisodeInfo.IsPossibleSpecialEpisode())
|
||||||
|
{
|
||||||
|
var specialEpisodeInfo = _parsingService.ParseSpecialEpisodeTitle(report.Title, report.TvRageId, searchCriteria);
|
||||||
|
if (specialEpisodeInfo != null)
|
||||||
|
{
|
||||||
|
parsedEpisodeInfo = specialEpisodeInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (parsedEpisodeInfo != null && !string.IsNullOrWhiteSpace(parsedEpisodeInfo.SeriesTitle))
|
if (parsedEpisodeInfo != null && !string.IsNullOrWhiteSpace(parsedEpisodeInfo.SeriesTitle))
|
||||||
{
|
{
|
||||||
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, report.TvRageId, searchCriteria);
|
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, report.TvRageId, searchCriteria);
|
||||||
|
@ -91,13 +100,12 @@ namespace NzbDrone.Core.DecisionEngine
|
||||||
yield return decision;
|
yield return decision;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private DownloadDecision GetDecisionForReport(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria = null)
|
private DownloadDecision GetDecisionForReport(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria = null)
|
||||||
{
|
{
|
||||||
var reasons = _specifications.Select(c => EvaluateSpec(c, remoteEpisode, searchCriteria))
|
var reasons = _specifications.Select(c => EvaluateSpec(c, remoteEpisode, searchCriteria))
|
||||||
.Where(c => !string.IsNullOrWhiteSpace(c));
|
.Where(c => !string.IsNullOrWhiteSpace(c));
|
||||||
|
|
||||||
return new DownloadDecision(remoteEpisode, reasons.ToArray());
|
return new DownloadDecision(remoteEpisode, reasons.ToArray());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.DecisionEngine
|
namespace NzbDrone.Core.DecisionEngine
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,7 +27,6 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
|
|
||||||
public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
||||||
{
|
{
|
||||||
|
|
||||||
_logger.Trace("Beginning size check for: {0}", subject);
|
_logger.Trace("Beginning size check for: {0}", subject);
|
||||||
|
|
||||||
var quality = subject.ParsedEpisodeInfo.Quality.Quality;
|
var quality = subject.ParsedEpisodeInfo.Quality.Quality;
|
||||||
|
@ -45,34 +44,43 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
}
|
}
|
||||||
|
|
||||||
var qualityDefinition = _qualityDefinitionService.Get(quality);
|
var qualityDefinition = _qualityDefinitionService.Get(quality);
|
||||||
|
var minSize = qualityDefinition.MinSize.Megabytes();
|
||||||
|
|
||||||
|
//Multiply maxSize by Series.Runtime
|
||||||
|
minSize = minSize * subject.Series.Runtime * subject.Episodes.Count;
|
||||||
|
|
||||||
|
//If the parsed size is smaller than minSize we don't want it
|
||||||
|
if (subject.Release.Size < minSize)
|
||||||
|
{
|
||||||
|
_logger.Trace("Item: {0}, Size: {1} is smaller than minimum allowed size ({2}), rejecting.", subject, subject.Release.Size, minSize);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (qualityDefinition.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;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
var maxSize = qualityDefinition.MaxSize.Megabytes();
|
|
||||||
|
|
||||||
//Multiply maxSize by Series.Runtime
|
|
||||||
maxSize = maxSize * subject.Series.Runtime * subject.Episodes.Count;
|
|
||||||
|
|
||||||
//Check if there was only one episode parsed and it is the first
|
|
||||||
if (subject.Episodes.Count == 1 && subject.Episodes.First().EpisodeNumber == 1)
|
|
||||||
{
|
{
|
||||||
maxSize = maxSize * 2;
|
var maxSize = qualityDefinition.MaxSize.Megabytes();
|
||||||
}
|
|
||||||
|
|
||||||
//If the parsed size is greater than maxSize we don't want it
|
//Multiply maxSize by Series.Runtime
|
||||||
if (subject.Release.Size > maxSize)
|
maxSize = maxSize * subject.Series.Runtime * subject.Episodes.Count;
|
||||||
{
|
|
||||||
_logger.Trace("Item: {0}, Size: {1} is greater than maximum allowed size ({2}), rejecting.", subject, subject.Release.Size, maxSize);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//Check if there was only one episode parsed and it is the first
|
||||||
|
if (subject.Episodes.Count == 1 && _episodeService.IsFirstOrLastEpisodeOfSeason(subject.Episodes.First().Id))
|
||||||
|
{
|
||||||
|
maxSize = maxSize * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//If the parsed size is greater than maxSize we don't want it
|
||||||
|
if (subject.Release.Size > maxSize)
|
||||||
|
{
|
||||||
|
_logger.Trace("Item: {0}, Size: {1} is greater than maximum allowed size ({2}), rejecting.", subject, subject.Release.Size, maxSize);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
_logger.Trace("Item: {0}, meets size constraints.", subject);
|
_logger.Trace("Item: {0}, meets size constraints.", subject);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ 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.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
{
|
{
|
||||||
|
@ -32,9 +31,9 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
{
|
{
|
||||||
var downloadClient = _downloadClientProvider.GetDownloadClient();
|
var downloadClient = _downloadClientProvider.GetDownloadClient();
|
||||||
|
|
||||||
if (!downloadClient.IsConfigured)
|
if (downloadClient == null)
|
||||||
{
|
{
|
||||||
_logger.Warn("Download client {0} isn't configured yet.", downloadClient.GetType().Name);
|
_logger.Warn("Download client isn't configured yet.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,10 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
||||||
{
|
{
|
||||||
var age = subject.Release.Age;
|
var age = subject.Release.Age;
|
||||||
|
var retention = _configService.Retention;
|
||||||
|
|
||||||
_logger.Trace("Checking if report meets retention requirements. {0}", age);
|
_logger.Trace("Checking if report meets retention requirements. {0}", age);
|
||||||
if (_configService.Retention > 0 && age > _configService.Retention)
|
if (retention > 0 && age > retention)
|
||||||
{
|
{
|
||||||
_logger.Trace("Report age: {0} rejected by user's retention limit", age);
|
_logger.Trace("Report age: {0} rejected by user's retention limit", age);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_downloadClientProvider.GetDownloadClient().GetType() == typeof (SabnzbdClient))
|
if (_downloadClientProvider.GetDownloadClient().GetType() == typeof (Sabnzbd))
|
||||||
{
|
{
|
||||||
_logger.Trace("Performing history status check on report");
|
_logger.Trace("Performing history status check on report");
|
||||||
foreach (var episode in subject.Episodes)
|
foreach (var episode in subject.Episodes)
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
using NzbDrone.Core.Organizer;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
|
{
|
||||||
|
public class Blackhole : DownloadClientBase<FolderSettings>, IExecute<TestBlackholeCommand>
|
||||||
|
{
|
||||||
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
private readonly IHttpProvider _httpProvider;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public Blackhole(IDiskProvider diskProvider, IHttpProvider httpProvider, Logger logger)
|
||||||
|
{
|
||||||
|
_diskProvider = diskProvider;
|
||||||
|
_httpProvider = httpProvider;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string DownloadNzb(RemoteEpisode remoteEpisode)
|
||||||
|
{
|
||||||
|
var url = remoteEpisode.Release.DownloadUrl;
|
||||||
|
var title = remoteEpisode.Release.Title;
|
||||||
|
|
||||||
|
title = FileNameBuilder.CleanFilename(title);
|
||||||
|
|
||||||
|
var filename = Path.Combine(Settings.Folder, title + ".nzb");
|
||||||
|
|
||||||
|
|
||||||
|
_logger.Trace("Downloading NZB from: {0} to: {1}", url, filename);
|
||||||
|
_httpProvider.DownloadFile(url, filename);
|
||||||
|
_logger.Trace("NZB Download succeeded, saved to: {0}", filename);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<QueueItem> GetQueue()
|
||||||
|
{
|
||||||
|
return new QueueItem[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<HistoryItem> GetHistory(int start = 0, int limit = 10)
|
||||||
|
{
|
||||||
|
return new HistoryItem[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RemoveFromQueue(string id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RemoveFromHistory(string id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute(TestBlackholeCommand message)
|
||||||
|
{
|
||||||
|
var testPath = Path.Combine(message.Folder, "drone_test.txt");
|
||||||
|
_diskProvider.WriteAllText(testPath, DateTime.Now.ToString());
|
||||||
|
_diskProvider.DeleteFile(testPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
|
{
|
||||||
|
public class TestBlackholeCommand : Command
|
||||||
|
{
|
||||||
|
public override bool SendUpdatesToClient
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String Folder { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,68 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Common;
|
|
||||||
using NzbDrone.Core.Configuration;
|
|
||||||
using NzbDrone.Core.Organizer;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients
|
|
||||||
{
|
|
||||||
public class BlackholeProvider : IDownloadClient
|
|
||||||
{
|
|
||||||
private readonly IConfigService _configService;
|
|
||||||
private readonly IHttpProvider _httpProvider;
|
|
||||||
private readonly Logger _logger;
|
|
||||||
|
|
||||||
|
|
||||||
public BlackholeProvider(IConfigService configService, IHttpProvider httpProvider, Logger logger)
|
|
||||||
{
|
|
||||||
_configService = configService;
|
|
||||||
_httpProvider = httpProvider;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string DownloadNzb(RemoteEpisode remoteEpisode)
|
|
||||||
{
|
|
||||||
var url = remoteEpisode.Release.DownloadUrl;
|
|
||||||
var title = remoteEpisode.Release.Title;
|
|
||||||
|
|
||||||
title = FileNameBuilder.CleanFilename(title);
|
|
||||||
|
|
||||||
var filename = Path.Combine(_configService.BlackholeFolder, title + ".nzb");
|
|
||||||
|
|
||||||
|
|
||||||
_logger.Trace("Downloading NZB from: {0} to: {1}", url, filename);
|
|
||||||
_httpProvider.DownloadFile(url, filename);
|
|
||||||
_logger.Trace("NZB Download succeeded, saved to: {0}", filename);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsConfigured
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return !string.IsNullOrWhiteSpace(_configService.BlackholeFolder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<QueueItem> GetQueue()
|
|
||||||
{
|
|
||||||
return new QueueItem[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<HistoryItem> GetHistory(int start = 0, int limit = 0)
|
|
||||||
{
|
|
||||||
return new HistoryItem[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveFromQueue(string id)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveFromHistory(string id)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
using System;
|
||||||
|
using FluentValidation;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Core.Annotations;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Clients
|
||||||
|
{
|
||||||
|
public class FolderSettingsValidator : AbstractValidator<FolderSettings>
|
||||||
|
{
|
||||||
|
public FolderSettingsValidator()
|
||||||
|
{
|
||||||
|
//Todo: Validate that the path actually exists
|
||||||
|
RuleFor(c => c.Folder).IsValidPath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FolderSettings : IProviderConfig
|
||||||
|
{
|
||||||
|
private static readonly FolderSettingsValidator Validator = new FolderSettingsValidator();
|
||||||
|
|
||||||
|
[FieldDefinition(0, Label = "Folder", Type = FieldType.Path)]
|
||||||
|
public String Folder { get; set; }
|
||||||
|
|
||||||
|
public ValidationResult Validate()
|
||||||
|
{
|
||||||
|
return Validator.Validate(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,11 +4,11 @@ using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Nzbget
|
namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
{
|
{
|
||||||
public class NzbGetQueue
|
public class NzbgetQueue
|
||||||
{
|
{
|
||||||
public String Version { get; set; }
|
public String Version { get; set; }
|
||||||
|
|
||||||
[JsonProperty(PropertyName = "result")]
|
[JsonProperty(PropertyName = "result")]
|
||||||
public List<NzbGetQueueItem> QueueItems { get; set; }
|
public List<NzbgetQueueItem> QueueItems { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,11 @@
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Nzbget
|
namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
{
|
{
|
||||||
public class NzbGetQueueItem
|
public class NzbgetQueueItem
|
||||||
{
|
{
|
||||||
private string _nzbName;
|
private string _nzbName;
|
||||||
|
|
||||||
public Int32 NzbId { get; set; }
|
public Int32 NzbId { get; set; }
|
||||||
|
|
||||||
public string NzbName { get; set; }
|
public string NzbName { get; set; }
|
||||||
|
|
||||||
public String Category { get; set; }
|
public String Category { get; set; }
|
||||||
public Int32 FileSizeMb { get; set; }
|
public Int32 FileSizeMb { get; set; }
|
||||||
public Int32 RemainingSizeMb { get; set; }
|
public Int32 RemainingSizeMb { get; set; }
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using Omu.ValueInjecter;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
|
{
|
||||||
|
public class Nzbget : DownloadClientBase<NzbgetSettings>, IExecute<TestNzbgetCommand>
|
||||||
|
{
|
||||||
|
private readonly INzbgetProxy _proxy;
|
||||||
|
private readonly IParsingService _parsingService;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public Nzbget(INzbgetProxy proxy,
|
||||||
|
IParsingService parsingService,
|
||||||
|
Logger logger)
|
||||||
|
{
|
||||||
|
_proxy = proxy;
|
||||||
|
_parsingService = parsingService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string DownloadNzb(RemoteEpisode remoteEpisode)
|
||||||
|
{
|
||||||
|
var url = remoteEpisode.Release.DownloadUrl;
|
||||||
|
var title = remoteEpisode.Release.Title + ".nzb";
|
||||||
|
|
||||||
|
string cat = Settings.TvCategory;
|
||||||
|
int priority = remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority;
|
||||||
|
|
||||||
|
_logger.Info("Adding report [{0}] to the queue.", title);
|
||||||
|
|
||||||
|
var success = _proxy.AddNzb(Settings, title, cat, priority, false, url);
|
||||||
|
|
||||||
|
_logger.Debug("Queue Response: [{0}]", success);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<QueueItem> GetQueue()
|
||||||
|
{
|
||||||
|
var items = _proxy.GetQueue(Settings);
|
||||||
|
|
||||||
|
foreach (var nzbGetQueueItem in items)
|
||||||
|
{
|
||||||
|
var queueItem = new QueueItem();
|
||||||
|
queueItem.Id = nzbGetQueueItem.NzbId.ToString();
|
||||||
|
queueItem.Title = nzbGetQueueItem.NzbName;
|
||||||
|
queueItem.Size = nzbGetQueueItem.FileSizeMb;
|
||||||
|
queueItem.Sizeleft = nzbGetQueueItem.RemainingSizeMb;
|
||||||
|
queueItem.Status = nzbGetQueueItem.FileSizeMb == nzbGetQueueItem.PausedSizeMb ? "paused" : "queued";
|
||||||
|
|
||||||
|
var parsedEpisodeInfo = Parser.Parser.ParseTitle(queueItem.Title);
|
||||||
|
if (parsedEpisodeInfo == null) continue;
|
||||||
|
|
||||||
|
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0);
|
||||||
|
if (remoteEpisode.Series == null) continue;
|
||||||
|
|
||||||
|
queueItem.RemoteEpisode = remoteEpisode;
|
||||||
|
|
||||||
|
yield return queueItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<HistoryItem> GetHistory(int start = 0, int limit = 10)
|
||||||
|
{
|
||||||
|
return new HistoryItem[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RemoveFromQueue(string id)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RemoveFromHistory(string id)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public VersionResponse GetVersion(string host = null, int port = 0, string username = null, string password = null)
|
||||||
|
{
|
||||||
|
return _proxy.GetVersion(Settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute(TestNzbgetCommand message)
|
||||||
|
{
|
||||||
|
var settings = new NzbgetSettings();
|
||||||
|
settings.InjectFrom(message);
|
||||||
|
|
||||||
|
_proxy.GetVersion(settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,136 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Common;
|
|
||||||
using NzbDrone.Common.Serializer;
|
|
||||||
using NzbDrone.Core.Configuration;
|
|
||||||
using NzbDrone.Core.Parser;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Nzbget
|
|
||||||
{
|
|
||||||
public class NzbgetClient : IDownloadClient
|
|
||||||
{
|
|
||||||
private readonly IConfigService _configService;
|
|
||||||
private readonly IHttpProvider _httpProvider;
|
|
||||||
private readonly INzbGetCommunicationProxy _proxy;
|
|
||||||
private readonly IParsingService _parsingService;
|
|
||||||
private readonly Logger _logger;
|
|
||||||
|
|
||||||
public NzbgetClient(IConfigService configService,
|
|
||||||
IHttpProvider httpProvider,
|
|
||||||
INzbGetCommunicationProxy proxy,
|
|
||||||
IParsingService parsingService,
|
|
||||||
Logger logger)
|
|
||||||
{
|
|
||||||
_configService = configService;
|
|
||||||
_httpProvider = httpProvider;
|
|
||||||
_proxy = proxy;
|
|
||||||
_parsingService = parsingService;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string DownloadNzb(RemoteEpisode remoteEpisode)
|
|
||||||
{
|
|
||||||
var url = remoteEpisode.Release.DownloadUrl;
|
|
||||||
var title = remoteEpisode.Release.Title + ".nzb";
|
|
||||||
|
|
||||||
string cat = _configService.NzbgetTvCategory;
|
|
||||||
int priority = remoteEpisode.IsRecentEpisode() ? (int)_configService.NzbgetRecentTvPriority : (int)_configService.NzbgetOlderTvPriority;
|
|
||||||
|
|
||||||
_logger.Info("Adding report [{0}] to the queue.", title);
|
|
||||||
|
|
||||||
var success = _proxy.AddNzb(title, cat, priority, false, url);
|
|
||||||
|
|
||||||
_logger.Debug("Queue Response: [{0}]", success);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsConfigured
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return !string.IsNullOrWhiteSpace(_configService.NzbgetHost) && _configService.NzbgetPort != 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual IEnumerable<QueueItem> GetQueue()
|
|
||||||
{
|
|
||||||
var items = _proxy.GetQueue();
|
|
||||||
|
|
||||||
foreach (var nzbGetQueueItem in items)
|
|
||||||
{
|
|
||||||
var queueItem = new QueueItem();
|
|
||||||
queueItem.Id = nzbGetQueueItem.NzbId.ToString();
|
|
||||||
queueItem.Title = nzbGetQueueItem.NzbName;
|
|
||||||
queueItem.Size = nzbGetQueueItem.FileSizeMb;
|
|
||||||
queueItem.Sizeleft = nzbGetQueueItem.RemainingSizeMb;
|
|
||||||
queueItem.Status = nzbGetQueueItem.FileSizeMb == nzbGetQueueItem.PausedSizeMb ? "paused" : "queued";
|
|
||||||
|
|
||||||
var parsedEpisodeInfo = Parser.Parser.ParseTitle(queueItem.Title);
|
|
||||||
if (parsedEpisodeInfo == null) continue;
|
|
||||||
|
|
||||||
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0);
|
|
||||||
if (remoteEpisode.Series == null) continue;
|
|
||||||
|
|
||||||
queueItem.RemoteEpisode = remoteEpisode;
|
|
||||||
|
|
||||||
yield return queueItem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<HistoryItem> GetHistory(int start = 0, int limit = 0)
|
|
||||||
{
|
|
||||||
return new HistoryItem[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveFromQueue(string id)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveFromHistory(string id)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual VersionModel GetVersion(string host = null, int port = 0, string username = null, string password = null)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
|
|
||||||
//Get saved values if any of these are defaults
|
|
||||||
if (host == null)
|
|
||||||
host = _configService.NzbgetHost;
|
|
||||||
|
|
||||||
if (port == 0)
|
|
||||||
port = _configService.NzbgetPort;
|
|
||||||
|
|
||||||
if (username == null)
|
|
||||||
username = _configService.NzbgetUsername;
|
|
||||||
|
|
||||||
if (password == null)
|
|
||||||
password = _configService.NzbgetPassword;
|
|
||||||
|
|
||||||
|
|
||||||
var response = _proxy.GetVersion();
|
|
||||||
|
|
||||||
return Json.Deserialize<VersionModel>(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual string Test(string host, int port, string username, string password)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var version = GetVersion(host, port, username, password);
|
|
||||||
return version.Result;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.DebugException("Failed to Test Nzbget", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return String.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
namespace NzbDrone.Core.Download.Clients.Nzbget
|
namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
{
|
{
|
||||||
public enum PriorityType
|
public enum NzbgetPriority
|
||||||
{
|
{
|
||||||
VeryLow = -100,
|
VeryLow = -100,
|
||||||
Low = -50,
|
Low = -50,
|
|
@ -1,57 +1,52 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Configuration;
|
|
||||||
using NzbDrone.Core.Rest;
|
using NzbDrone.Core.Rest;
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Nzbget
|
namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
{
|
{
|
||||||
public interface INzbGetCommunicationProxy
|
public interface INzbgetProxy
|
||||||
{
|
{
|
||||||
bool AddNzb(params object[] parameters);
|
bool AddNzb(NzbgetSettings settings, params object[] parameters);
|
||||||
List<NzbGetQueueItem> GetQueue();
|
List<NzbgetQueueItem> GetQueue(NzbgetSettings settings);
|
||||||
string GetVersion();
|
VersionResponse GetVersion(NzbgetSettings settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NzbGetCommunicationProxy : INzbGetCommunicationProxy
|
public class NzbgetProxy : INzbgetProxy
|
||||||
{
|
{
|
||||||
private readonly IConfigService _configService;
|
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public NzbGetCommunicationProxy(IConfigService configService, Logger logger)
|
public NzbgetProxy(Logger logger)
|
||||||
{
|
{
|
||||||
_configService = configService;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AddNzb(params object[] parameters)
|
public bool AddNzb(NzbgetSettings settings, params object[] parameters)
|
||||||
{
|
{
|
||||||
var request = BuildRequest(new JsonRequest("appendurl", parameters));
|
var request = BuildRequest(new JsonRequest("appendurl", parameters));
|
||||||
|
|
||||||
return Json.Deserialize<EnqueueResponse>(ProcessRequest(request)).Result;
|
return Json.Deserialize<EnqueueResponse>(ProcessRequest(request, settings)).Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<NzbGetQueueItem> GetQueue()
|
public List<NzbgetQueueItem> GetQueue(NzbgetSettings settings)
|
||||||
{
|
{
|
||||||
var request = BuildRequest(new JsonRequest("listgroups"));
|
var request = BuildRequest(new JsonRequest("listgroups"));
|
||||||
|
|
||||||
return Json.Deserialize<NzbGetQueue>(ProcessRequest(request)).QueueItems;
|
return Json.Deserialize<NzbgetQueue>(ProcessRequest(request, settings)).QueueItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetVersion()
|
public VersionResponse GetVersion(NzbgetSettings settings)
|
||||||
{
|
{
|
||||||
var request = BuildRequest(new JsonRequest("version"));
|
var request = BuildRequest(new JsonRequest("version"));
|
||||||
|
|
||||||
return ProcessRequest(request);
|
return Json.Deserialize<VersionResponse>(ProcessRequest(request, settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ProcessRequest(IRestRequest restRequest)
|
private string ProcessRequest(IRestRequest restRequest, NzbgetSettings settings)
|
||||||
{
|
{
|
||||||
var client = BuildClient();
|
var client = BuildClient(settings);
|
||||||
var response = client.Execute(restRequest);
|
var response = client.Execute(restRequest);
|
||||||
_logger.Trace("Response: {0}", response.Content);
|
_logger.Trace("Response: {0}", response.Content);
|
||||||
|
|
||||||
|
@ -60,14 +55,14 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
return response.Content;
|
return response.Content;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IRestClient BuildClient()
|
private IRestClient BuildClient(NzbgetSettings settings)
|
||||||
{
|
{
|
||||||
var url = String.Format("http://{0}:{1}/jsonrpc",
|
var url = String.Format("http://{0}:{1}/jsonrpc",
|
||||||
_configService.NzbgetHost,
|
settings.Host,
|
||||||
_configService.NzbgetPort);
|
settings.Port);
|
||||||
|
|
||||||
var client = new RestClient(url);
|
var client = new RestClient(url);
|
||||||
client.Authenticator = new HttpBasicAuthenticator(_configService.NzbgetUsername, _configService.NzbgetPassword);
|
client.Authenticator = new HttpBasicAuthenticator(settings.Username, settings.Password);
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
using System;
|
||||||
|
using FluentValidation;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NzbDrone.Core.Annotations;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
|
{
|
||||||
|
public class NzbgetSettingsValidator : AbstractValidator<NzbgetSettings>
|
||||||
|
{
|
||||||
|
public NzbgetSettingsValidator()
|
||||||
|
{
|
||||||
|
RuleFor(c => c.Host).NotEmpty();
|
||||||
|
RuleFor(c => c.Port).GreaterThan(0);
|
||||||
|
RuleFor(c => c.Username).NotEmpty();
|
||||||
|
RuleFor(c => c.Password).NotEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NzbgetSettings : IProviderConfig
|
||||||
|
{
|
||||||
|
private static readonly NzbgetSettingsValidator Validator = new NzbgetSettingsValidator();
|
||||||
|
|
||||||
|
public NzbgetSettings()
|
||||||
|
{
|
||||||
|
Host = "localhost";
|
||||||
|
Port = 6789;
|
||||||
|
TvCategory = "tv";
|
||||||
|
RecentTvPriority = (int)NzbgetPriority.Normal;
|
||||||
|
OlderTvPriority = (int)NzbgetPriority.Normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
||||||
|
public String Host { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(1, Label = "Port", Type = FieldType.Textbox)]
|
||||||
|
public Int32 Port { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(2, Label = "Username", Type = FieldType.Textbox)]
|
||||||
|
public String Username { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(3, Label = "Password", Type = FieldType.Password)]
|
||||||
|
public String Password { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(4, Label = "Category", Type = FieldType.Textbox)]
|
||||||
|
public String TvCategory { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(5, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(NzbgetPriority))]
|
||||||
|
public Int32 RecentTvPriority { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(6, Label = "Older Priority", Type = FieldType.Select, SelectOptions = typeof(NzbgetPriority))]
|
||||||
|
public Int32 OlderTvPriority { get; set; }
|
||||||
|
|
||||||
|
public ValidationResult Validate()
|
||||||
|
{
|
||||||
|
return Validator.Validate(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
using System;
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
|
{
|
||||||
|
public class TestNzbgetCommand : Command
|
||||||
|
{
|
||||||
|
public override bool SendUpdatesToClient
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String Host { get; set; }
|
||||||
|
public Int32 Port { get; set; }
|
||||||
|
public String Username { get; set; }
|
||||||
|
public String Password { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Nzbget
|
namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
{
|
{
|
||||||
public class VersionModel
|
public class VersionResponse
|
||||||
{
|
{
|
||||||
public String Version { get; set; }
|
public String Version { get; set; }
|
||||||
public String Result { get; set; }
|
public String Result { get; set; }
|
|
@ -6,12 +6,13 @@ using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Instrumentation;
|
using NzbDrone.Common.Instrumentation;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients
|
namespace NzbDrone.Core.Download.Clients.Pneumatic
|
||||||
{
|
{
|
||||||
public class PneumaticClient : IDownloadClient
|
public class Pneumatic : DownloadClientBase<FolderSettings>, IExecute<TestPneumaticCommand>
|
||||||
{
|
{
|
||||||
private readonly IConfigService _configService;
|
private readonly IConfigService _configService;
|
||||||
private readonly IHttpProvider _httpProvider;
|
private readonly IHttpProvider _httpProvider;
|
||||||
|
@ -19,7 +20,7 @@ namespace NzbDrone.Core.Download.Clients
|
||||||
|
|
||||||
private static readonly Logger logger = NzbDroneLogger.GetLogger();
|
private static readonly Logger logger = NzbDroneLogger.GetLogger();
|
||||||
|
|
||||||
public PneumaticClient(IConfigService configService, IHttpProvider httpProvider,
|
public Pneumatic(IConfigService configService, IHttpProvider httpProvider,
|
||||||
IDiskProvider diskProvider)
|
IDiskProvider diskProvider)
|
||||||
{
|
{
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
|
@ -27,20 +28,20 @@ namespace NzbDrone.Core.Download.Clients
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string DownloadNzb(RemoteEpisode remoteEpisode)
|
public override string DownloadNzb(RemoteEpisode remoteEpisode)
|
||||||
{
|
{
|
||||||
var url = remoteEpisode.Release.DownloadUrl;
|
var url = remoteEpisode.Release.DownloadUrl;
|
||||||
var title = remoteEpisode.Release.Title;
|
var title = remoteEpisode.Release.Title;
|
||||||
|
|
||||||
if (remoteEpisode.ParsedEpisodeInfo.FullSeason)
|
if (remoteEpisode.ParsedEpisodeInfo.FullSeason)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("Full season Pneumatic releases are not supported.");
|
throw new NotImplementedException("Full season releases are not supported with Pneumatic.");
|
||||||
}
|
}
|
||||||
|
|
||||||
title = FileNameBuilder.CleanFilename(title);
|
title = FileNameBuilder.CleanFilename(title);
|
||||||
|
|
||||||
//Save to the Pneumatic directory (The user will need to ensure its accessible by XBMC)
|
//Save to the Pneumatic directory (The user will need to ensure its accessible by XBMC)
|
||||||
var filename = Path.Combine(_configService.PneumaticFolder, title + ".nzb");
|
var filename = Path.Combine(Settings.Folder, title + ".nzb");
|
||||||
|
|
||||||
logger.Trace("Downloading NZB from: {0} to: {1}", url, filename);
|
logger.Trace("Downloading NZB from: {0} to: {1}", url, filename);
|
||||||
_httpProvider.DownloadFile(url, filename);
|
_httpProvider.DownloadFile(url, filename);
|
||||||
|
@ -57,31 +58,33 @@ namespace NzbDrone.Core.Download.Clients
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return !string.IsNullOrWhiteSpace(_configService.PneumaticFolder);
|
return !string.IsNullOrWhiteSpace(Settings.Folder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<QueueItem> GetQueue()
|
public override IEnumerable<QueueItem> GetQueue()
|
||||||
{
|
{
|
||||||
return new QueueItem[0];
|
return new QueueItem[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<HistoryItem> GetHistory(int start = 0, int limit = 0)
|
public override IEnumerable<HistoryItem> GetHistory(int start = 0, int limit = 10)
|
||||||
{
|
{
|
||||||
return new HistoryItem[0];
|
return new HistoryItem[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveFromQueue(string id)
|
public override void RemoveFromQueue(string id)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveFromHistory(string id)
|
public override void RemoveFromHistory(string id)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool IsInQueue(RemoteEpisode newEpisode)
|
public void Execute(TestPneumaticCommand message)
|
||||||
{
|
{
|
||||||
return false;
|
var testPath = Path.Combine(message.Folder, "drone_test.txt");
|
||||||
|
_diskProvider.WriteAllText(testPath, DateTime.Now.ToString());
|
||||||
|
_diskProvider.DeleteFile(testPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Clients.Pneumatic
|
||||||
|
{
|
||||||
|
public class TestPneumaticCommand : Command
|
||||||
|
{
|
||||||
|
public override bool SendUpdatesToClient
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String Folder { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
|
||||||
{
|
|
||||||
public class ConnectionInfoModel
|
|
||||||
{
|
|
||||||
public string Address { get; set; }
|
|
||||||
public int Port { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,7 +7,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd.JsonConverters
|
||||||
{
|
{
|
||||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
{
|
{
|
||||||
var priorityType = (SabPriorityType)value;
|
var priorityType = (SabnzbdPriority)value;
|
||||||
writer.WriteValue(priorityType.ToString());
|
writer.WriteValue(priorityType.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd.JsonConverters
|
||||||
{
|
{
|
||||||
var queuePriority = reader.Value.ToString();
|
var queuePriority = reader.Value.ToString();
|
||||||
|
|
||||||
SabPriorityType output;
|
SabnzbdPriority output;
|
||||||
Enum.TryParse(queuePriority, out output);
|
Enum.TryParse(queuePriority, out output);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
@ -23,7 +23,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd.JsonConverters
|
||||||
|
|
||||||
public override bool CanConvert(Type objectType)
|
public override bool CanConvert(Type objectType)
|
||||||
{
|
{
|
||||||
return objectType == typeof(SabPriorityType);
|
return objectType == typeof(SabnzbdPriority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Clients.Sabnzbd.Responses
|
||||||
|
{
|
||||||
|
public class SabnzbdAddResponse
|
||||||
|
{
|
||||||
|
public SabnzbdAddResponse()
|
||||||
|
{
|
||||||
|
Ids = new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Status { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(PropertyName = "nzo_ids")]
|
||||||
|
public List<string> Ids { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Clients.Sabnzbd.Responses
|
||||||
|
{
|
||||||
|
public class SabnzbdCategoryResponse
|
||||||
|
{
|
||||||
|
public SabnzbdCategoryResponse()
|
||||||
|
{
|
||||||
|
Categories = new List<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> Categories { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
namespace NzbDrone.Core.Download.Clients.Sabnzbd.Responses
|
||||||
|
{
|
||||||
|
public class SabnzbdVersionResponse
|
||||||
|
{
|
||||||
|
public string Version { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,19 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
|
||||||
{
|
|
||||||
public class SabAddResponse
|
|
||||||
{
|
|
||||||
public SabAddResponse()
|
|
||||||
{
|
|
||||||
Ids = new List<String>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Status { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(PropertyName = "nzo_ids")]
|
|
||||||
public List<String> Ids { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,100 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.NetworkInformation;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Common.Instrumentation;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
|
||||||
{
|
|
||||||
public class SabAutoConfigureService
|
|
||||||
{
|
|
||||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
|
|
||||||
|
|
||||||
public SabModel AutoConfigureSab()
|
|
||||||
{
|
|
||||||
var info = GetConnectionList();
|
|
||||||
return FindApiKey(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<ConnectionInfoModel> GetConnectionList()
|
|
||||||
{
|
|
||||||
IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
|
|
||||||
var info =
|
|
||||||
ipProperties.GetActiveTcpListeners().Select(
|
|
||||||
p =>
|
|
||||||
new ConnectionInfoModel { Address = p.Address.ToString().Replace("0.0.0.0", "127.0.0.1"), Port = p.Port }).Distinct().
|
|
||||||
ToList();
|
|
||||||
|
|
||||||
info.RemoveAll(i => i.Port == 135);
|
|
||||||
info.RemoveAll(i => i.Port == 139);
|
|
||||||
info.RemoveAll(i => i.Port == 445);
|
|
||||||
info.RemoveAll(i => i.Port == 3389);
|
|
||||||
info.RemoveAll(i => i.Port == 5900);
|
|
||||||
info.RemoveAll(i => i.Address.Contains("::"));
|
|
||||||
|
|
||||||
info.Reverse();
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
private SabModel FindApiKey(List<ConnectionInfoModel> info)
|
|
||||||
{
|
|
||||||
foreach (var connection in info)
|
|
||||||
{
|
|
||||||
var apiKey = GetApiKey(connection.Address, connection.Port);
|
|
||||||
if (!String.IsNullOrEmpty(apiKey))
|
|
||||||
return new SabModel
|
|
||||||
{
|
|
||||||
Host = connection.Address,
|
|
||||||
Port = connection.Port,
|
|
||||||
ApiKey = apiKey
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetApiKey(string ipAddress, int port)
|
|
||||||
{
|
|
||||||
var request = String.Format("http://{0}:{1}/config/general/", ipAddress, port);
|
|
||||||
var result = DownloadString(request);
|
|
||||||
|
|
||||||
Regex regex =
|
|
||||||
new Regex("\\<input\\Wtype\\=\\\"text\\\"\\Wid\\=\\\"apikey\\\"\\Wvalue\\=\\\"(?<apikey>\\w+)\\W",
|
|
||||||
RegexOptions.IgnoreCase
|
|
||||||
| RegexOptions.Compiled);
|
|
||||||
var match = regex.Match(result);
|
|
||||||
|
|
||||||
if (match.Success)
|
|
||||||
{
|
|
||||||
return match.Groups["apikey"].Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return String.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string DownloadString(string url)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var request = WebRequest.Create(url);
|
|
||||||
request.Timeout = 2000;
|
|
||||||
|
|
||||||
var response = request.GetResponse();
|
|
||||||
|
|
||||||
var reader = new StreamReader(response.GetResponseStream());
|
|
||||||
return reader.ReadToEnd();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logger.Trace("Failed to get response from: {0}", url);
|
|
||||||
Logger.Trace(ex.Message, ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return String.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
|
||||||
{
|
|
||||||
public class SabCategoryModel
|
|
||||||
{
|
|
||||||
public List<string> categories { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,130 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Common.Serializer;
|
|
||||||
using NzbDrone.Core.Configuration;
|
|
||||||
using RestSharp;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
|
||||||
{
|
|
||||||
public interface ISabCommunicationProxy
|
|
||||||
{
|
|
||||||
SabAddResponse DownloadNzb(Stream nzb, string name, string category, int priority);
|
|
||||||
void RemoveFrom(string source, string id);
|
|
||||||
string ProcessRequest(IRestRequest restRequest, string action);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SabCommunicationProxy : ISabCommunicationProxy
|
|
||||||
{
|
|
||||||
private readonly IConfigService _configService;
|
|
||||||
private readonly Logger _logger;
|
|
||||||
|
|
||||||
public SabCommunicationProxy(IConfigService configService, Logger logger)
|
|
||||||
{
|
|
||||||
_configService = configService;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SabAddResponse DownloadNzb(Stream nzb, string title, string category, int priority)
|
|
||||||
{
|
|
||||||
var request = new RestRequest(Method.POST);
|
|
||||||
var action = String.Format("mode=addfile&cat={0}&priority={1}", category, priority);
|
|
||||||
|
|
||||||
request.AddFile("name", ReadFully(nzb), title, "application/x-nzb");
|
|
||||||
|
|
||||||
SabAddResponse response;
|
|
||||||
|
|
||||||
if (!Json.TryDeserialize<SabAddResponse>(ProcessRequest(request, action), out response))
|
|
||||||
{
|
|
||||||
response = new SabAddResponse();
|
|
||||||
response.Status = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveFrom(string source, string id)
|
|
||||||
{
|
|
||||||
var request = new RestRequest();
|
|
||||||
var action = String.Format("mode={0}&name=delete&del_files=1&value={1}", source, id);
|
|
||||||
|
|
||||||
ProcessRequest(request, action);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ProcessRequest(IRestRequest restRequest, string action)
|
|
||||||
{
|
|
||||||
var client = BuildClient(action);
|
|
||||||
var response = client.Execute(restRequest);
|
|
||||||
_logger.Trace("Response: {0}", response.Content);
|
|
||||||
|
|
||||||
CheckForError(response);
|
|
||||||
|
|
||||||
return response.Content;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IRestClient BuildClient(string action)
|
|
||||||
{
|
|
||||||
var protocol = _configService.SabUseSsl ? "https" : "http";
|
|
||||||
|
|
||||||
var url = string.Format(@"{0}://{1}:{2}/api?{3}&apikey={4}&ma_username={5}&ma_password={6}&output=json",
|
|
||||||
protocol,
|
|
||||||
_configService.SabHost,
|
|
||||||
_configService.SabPort,
|
|
||||||
action,
|
|
||||||
_configService.SabApiKey,
|
|
||||||
_configService.SabUsername,
|
|
||||||
_configService.SabPassword);
|
|
||||||
|
|
||||||
_logger.Trace(url);
|
|
||||||
|
|
||||||
return new RestClient(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CheckForError(IRestResponse response)
|
|
||||||
{
|
|
||||||
if (response.ResponseStatus != ResponseStatus.Completed)
|
|
||||||
{
|
|
||||||
throw new ApplicationException("Unable to connect to SABnzbd, please check your settings");
|
|
||||||
}
|
|
||||||
|
|
||||||
SabJsonError result;
|
|
||||||
|
|
||||||
if (!Json.TryDeserialize<SabJsonError>(response.Content, out result))
|
|
||||||
{
|
|
||||||
//Handle plain text responses from SAB
|
|
||||||
result = new SabJsonError();
|
|
||||||
|
|
||||||
if (response.Content.StartsWith("error", StringComparison.InvariantCultureIgnoreCase))
|
|
||||||
{
|
|
||||||
result.Status = "false";
|
|
||||||
result.Error = response.Content.Replace("error: ", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result.Status = "true";
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Error = response.Content.Replace("error: ", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.Failed)
|
|
||||||
throw new ApplicationException(result.Error);
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Find a better home for this
|
|
||||||
private byte[] ReadFully(Stream input)
|
|
||||||
{
|
|
||||||
byte[] buffer = new byte[16 * 1024];
|
|
||||||
using (MemoryStream ms = new MemoryStream())
|
|
||||||
{
|
|
||||||
int read;
|
|
||||||
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
|
|
||||||
{
|
|
||||||
ms.Write(buffer, 0, read);
|
|
||||||
}
|
|
||||||
return ms.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
|
||||||
{
|
|
||||||
public class SabModel
|
|
||||||
{
|
|
||||||
public string Host { get; set; }
|
|
||||||
public int Port { get; set; }
|
|
||||||
public string ApiKey { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
|
||||||
{
|
|
||||||
public class SabVersionModel
|
|
||||||
{
|
|
||||||
public string Version { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue