Merge branch 'develop'
This commit is contained in:
commit
e7c2eda995
Logo
src
NzbDrone.Api
Config
DownloadClientConfigModule.csDownloadClientConfigResource.csHostConfigModule.csHostConfigResource.csIndexerConfigModule.csIndexerConfigResource.csMediaManagementConfigModule.csMediaManagementConfigResource.csNamingConfigModule.csNzbDroneConfigModule.csSettingsModule.cs
DownloadClient
NzbDrone.Api.csprojRootFolders
Series
Validation
NzbDrone.Common
NzbDrone.Core.Test
Configuration
DecisionEngineTests
AcceptableSizeSpecificationFixture.csDownloadDecisionMakerFixture.csHistorySpecificationFixture.csNotInQueueSpecificationFixture.csRetentionSpecificationFixture.cs
Download
DownloadClientTests
DownloadServiceFixture.csFiles
MediaFiles/EpisodeImport
MetadataSourceTests
NzbDrone.Core.Test.csprojParserTests
AbsoluteEpisodeNumberParserFixture.csCrapParserFixture.csDailyEpisodeParserFixture.csIsPossibleSpecialEpisodeFixture.csLanguageParserFixture.csMultiEpisodeParserFixture.csNormalizeTitleFixture.csParserFixture.csPathParserFixture.csReleaseGroupParserFixture.csSeasonParserFixture.csSingleEpisodeParserFixture.cs
NzbDrone.Core
Annotations
Blacklisting
Configuration
DataAugmentation/Xem
Datastore
BasicRepository.cs
Migration
042_add_download_clients_table.cs043_convert_config_to_download_clients.cs044_fix_xbmc_episode_metadata.cs
TableMapping.csDecisionEngine
Download/Clients
BIN
Logo/64.png
BIN
Logo/64.png
Binary file not shown.
Before ![]() (image error) Size: 1.5 KiB After ![]() (image error) Size: 3.5 KiB ![]() ![]() |
Binary file not shown.
Before ![]() (image error) Size: 79 KiB |
Binary file not shown.
Before ![]() (image error) Size: 65 KiB |
Binary file not shown.
Before ![]() (image error) 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
|
||||
{
|
||||
public class NamingModule : NzbDroneRestModule<NamingConfigResource>
|
||||
public class NamingConfigModule : NzbDroneRestModule<NamingConfigResource>
|
||||
{
|
||||
private readonly INamingConfigService _namingConfigService;
|
||||
private readonly IFilenameSampleService _filenameSampleService;
|
||||
private readonly IFilenameValidationService _filenameValidationService;
|
||||
private readonly IBuildFileNames _filenameBuilder;
|
||||
|
||||
public NamingModule(INamingConfigService namingConfigService,
|
||||
public NamingConfigModule(INamingConfigService namingConfigService,
|
||||
IFilenameSampleService filenameSampleService,
|
||||
IFilenameValidationService filenameValidationService,
|
||||
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="Commands\CommandModule.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\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\DiskSpaceResource.cs" />
|
||||
<Compile Include="EpisodeFiles\EpisodeFileModule.cs" />
|
||||
|
@ -122,6 +133,7 @@
|
|||
<Compile Include="History\HistoryModule.cs" />
|
||||
<Compile Include="Metadata\MetadataResource.cs" />
|
||||
<Compile Include="Metadata\MetadataModule.cs" />
|
||||
<Compile Include="Notifications\NotificationSchemaModule.cs" />
|
||||
<Compile Include="ProviderResource.cs" />
|
||||
<Compile Include="ProviderModuleBase.cs" />
|
||||
<Compile Include="Indexers\IndexerSchemaModule.cs" />
|
||||
|
@ -145,7 +157,7 @@
|
|||
<Compile Include="Queue\QueueModule.cs" />
|
||||
<Compile Include="Queue\QueueResource.cs" />
|
||||
<Compile Include="ResourceChangeMessage.cs" />
|
||||
<Compile Include="Notifications\NotificationSchemaModule.cs" />
|
||||
<Compile Include="DownloadClient\DownloadClientSchemaModule.cs" />
|
||||
<Compile Include="Notifications\NotificationModule.cs" />
|
||||
<Compile Include="Notifications\NotificationResource.cs" />
|
||||
<Compile Include="NzbDroneRestModule.cs" />
|
||||
|
@ -174,11 +186,9 @@
|
|||
<Compile Include="Qualities\QualityDefinitionResource.cs" />
|
||||
<Compile Include="Qualities\QualityDefinitionModule.cs" />
|
||||
<Compile Include="Extensions\ReqResExtensions.cs" />
|
||||
<Compile Include="Config\SettingsModule.cs" />
|
||||
<Compile Include="System\SystemModule.cs" />
|
||||
<Compile Include="TinyIoCNancyBootstrapper.cs" />
|
||||
<Compile Include="Update\UpdateModule.cs" />
|
||||
<Compile Include="Validation\PathValidator.cs" />
|
||||
<Compile Include="Validation\RuleBuilderExtensions.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -5,7 +5,7 @@ using FluentValidation.Results;
|
|||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.RootFolders;
|
||||
using NzbDrone.Api.Mapping;
|
||||
using NzbDrone.Api.Validation;
|
||||
using NzbDrone.Core.Validation.Paths;
|
||||
|
||||
namespace NzbDrone.Api.RootFolders
|
||||
{
|
||||
|
@ -13,7 +13,11 @@ namespace NzbDrone.Api.RootFolders
|
|||
{
|
||||
private readonly IRootFolderService _rootFolderService;
|
||||
|
||||
public RootFolderModule(IRootFolderService rootFolderService, ICommandExecutor commandExecutor)
|
||||
public RootFolderModule(IRootFolderService rootFolderService,
|
||||
ICommandExecutor commandExecutor,
|
||||
RootFolderValidator rootFolderValidator,
|
||||
PathExistsValidator pathExistsValidator,
|
||||
DroneFactoryValidator droneFactoryValidator)
|
||||
: base(commandExecutor)
|
||||
{
|
||||
_rootFolderService = rootFolderService;
|
||||
|
@ -23,7 +27,12 @@ namespace NzbDrone.Api.RootFolders
|
|||
CreateResource = CreateRootFolder;
|
||||
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)
|
||||
|
@ -33,15 +42,7 @@ namespace NzbDrone.Api.RootFolders
|
|||
|
||||
private int CreateRootFolder(RootFolderResource rootFolderResource)
|
||||
{
|
||||
try
|
||||
{
|
||||
return GetNewId<RootFolder>(_rootFolderService.Add, rootFolderResource);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ValidationException(new [] { new ValidationFailure("Path", ex.Message) });
|
||||
}
|
||||
|
||||
return GetNewId<RootFolder>(_rootFolderService.Add, rootFolderResource);
|
||||
}
|
||||
|
||||
private List<RootFolderResource> GetRootFolders()
|
||||
|
|
|
@ -12,6 +12,7 @@ using NzbDrone.Core.Tv;
|
|||
using NzbDrone.Api.Validation;
|
||||
using NzbDrone.Api.Mapping;
|
||||
using NzbDrone.Core.Tv.Events;
|
||||
using NzbDrone.Core.Validation.Paths;
|
||||
|
||||
namespace NzbDrone.Api.Series
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System.Text.RegularExpressions;
|
||||
using FluentValidation;
|
||||
using FluentValidation.Validators;
|
||||
using NzbDrone.Core.Validation.Paths;
|
||||
|
||||
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://");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return ruleBuilder.SetValidator(new NotNullValidator()).SetValidator(new NotEmptyValidator(""));
|
||||
|
|
|
@ -71,7 +71,6 @@ namespace NzbDrone.Common
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static bool ContainsInvalidPathChars(this string text)
|
||||
{
|
||||
return text.IndexOfAny(Path.GetInvalidPathChars()) >= 0;
|
||||
|
|
|
@ -179,9 +179,7 @@ namespace NzbDrone.Common.Processes
|
|||
public ProcessOutput StartAndCapture(string path, string args = null)
|
||||
{
|
||||
var output = new ProcessOutput();
|
||||
var process = Start(path, args, s => output.Standard.Add(s), error => output.Error.Add(error));
|
||||
|
||||
WaitForExit(process);
|
||||
Start(path, args, s => output.Standard.Add(s), error => output.Error.Add(error)).WaitForExit();
|
||||
|
||||
return output;
|
||||
}
|
||||
|
@ -190,10 +188,7 @@ namespace NzbDrone.Common.Processes
|
|||
{
|
||||
Logger.Trace("Waiting for process {0} to exit.", process.ProcessName);
|
||||
|
||||
if (!process.HasExited)
|
||||
{
|
||||
process.WaitForExit();
|
||||
}
|
||||
process.WaitForExit();
|
||||
}
|
||||
|
||||
public void SetPriority(int processId, ProcessPriorityClass priority)
|
||||
|
|
|
@ -105,16 +105,6 @@ namespace NzbDrone.Core.Test.Configuration
|
|||
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]
|
||||
[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()
|
||||
|
|
|
@ -15,340 +15,166 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
|
||||
public class AcceptableSizeSpecificationFixture : CoreTest<AcceptableSizeSpecification>
|
||||
{
|
||||
private RemoteEpisode parseResultMultiSet;
|
||||
private RemoteEpisode parseResultMulti;
|
||||
private RemoteEpisode parseResultSingle;
|
||||
private Series series30minutes;
|
||||
private Series series60minutes;
|
||||
private Series series;
|
||||
private QualityDefinition qualityType;
|
||||
|
||||
[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
|
||||
{
|
||||
Release = new ReleaseInfo(),
|
||||
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.SDTV, true) },
|
||||
Episodes = new List<Episode> { new Episode(), new Episode() }
|
||||
};
|
||||
{
|
||||
Series = series,
|
||||
Release = new ReleaseInfo(),
|
||||
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.SDTV, true) },
|
||||
Episodes = new List<Episode> { new Episode(), new Episode() }
|
||||
};
|
||||
|
||||
parseResultSingle = new RemoteEpisode
|
||||
{
|
||||
Series = series,
|
||||
Release = new ReleaseInfo(),
|
||||
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.SDTV, true) },
|
||||
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()
|
||||
.With(q => q.MinSize = 0)
|
||||
.With(q => q.MinSize = 2)
|
||||
.With(q => q.MaxSize = 10)
|
||||
.With(q => q.Quality = Quality.SDTV)
|
||||
.Build();
|
||||
|
||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsAcceptableSize_true_single_episode_not_first_or_last_30_minute()
|
||||
private void GivenLastEpisode()
|
||||
{
|
||||
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(
|
||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||
.Returns(true);
|
||||
|
||||
|
||||
bool result = Subject.IsSatisfiedBy(parseResultSingle, null);
|
||||
|
||||
|
||||
result.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsAcceptableSize_true_single_episode_first_60_minute()
|
||||
{
|
||||
parseResultSingle.Series = series60minutes;
|
||||
parseResultSingle.Release.Size = 368572800;
|
||||
[TestCase(30, 50, false)]
|
||||
[TestCase(30, 250, true)]
|
||||
[TestCase(30, 500, false)]
|
||||
[TestCase(60, 100, false)]
|
||||
[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(
|
||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||
.Returns(true);
|
||||
.Returns(false);
|
||||
|
||||
|
||||
bool result = Subject.IsSatisfiedBy(parseResultSingle, null);
|
||||
|
||||
|
||||
result.Should().BeTrue();
|
||||
Subject.IsSatisfiedBy(parseResultMulti, null).Should().Be(expectedResult);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsAcceptableSize_false_single_episode_first_30_minute()
|
||||
[TestCase(30, 50 * 6, false)]
|
||||
[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;
|
||||
parseResultSingle.Release.Size = 1.Gigabytes();
|
||||
|
||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||
series.Runtime = runtime;
|
||||
parseResultMultiSet.Series = series;
|
||||
parseResultMultiSet.Release.Size = sizeInMegaBytes.Megabytes();
|
||||
|
||||
Mocker.GetMock<IEpisodeService>().Setup(
|
||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||
.Returns(true);
|
||||
.Returns(false);
|
||||
|
||||
|
||||
bool result = Subject.IsSatisfiedBy(parseResultSingle, null);
|
||||
|
||||
|
||||
result.Should().BeFalse();
|
||||
Subject.IsSatisfiedBy(parseResultMultiSet, null).Should().Be(expectedResult);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsAcceptableSize_false_single_episode_first_60_minute()
|
||||
public void should_return_true_if_unlimited_30_minute()
|
||||
{
|
||||
GivenLastEpisode();
|
||||
|
||||
|
||||
parseResultSingle.Series = series60minutes;
|
||||
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;
|
||||
series.Runtime = 30;
|
||||
parseResultSingle.Series = series;
|
||||
parseResultSingle.Release.Size = 18457280000;
|
||||
qualityType.MaxSize = 0;
|
||||
|
||||
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().BeTrue();
|
||||
Subject.IsSatisfiedBy(parseResultSingle, null).Should().BeTrue();
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void IsAcceptableSize_true_unlimited_60_minute()
|
||||
public void should_return_true_if_unlimited_60_minute()
|
||||
{
|
||||
GivenLastEpisode();
|
||||
|
||||
|
||||
parseResultSingle.Series = series60minutes;
|
||||
series.Runtime = 60;
|
||||
parseResultSingle.Series = series;
|
||||
parseResultSingle.Release.Size = 36857280000;
|
||||
qualityType.MaxSize = 0;
|
||||
|
||||
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().BeTrue();
|
||||
Subject.IsSatisfiedBy(parseResultSingle, null).Should().BeTrue();;
|
||||
}
|
||||
|
||||
[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.Release.Size = 300.Megabytes();
|
||||
|
||||
qualityType.MaxSize = (int)600.Megabytes();
|
||||
qualityType.MaxSize = 10;
|
||||
|
||||
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().BeTrue();
|
||||
Subject.IsSatisfiedBy(parseResultSingle, null).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -362,9 +188,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
Subject.IsSatisfiedBy(parseResult, null).Should().BeTrue();
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_always_return_false_if_unknow()
|
||||
public void should_always_return_false_if_unknown()
|
||||
{
|
||||
var parseResult = new RemoteEpisode
|
||||
{
|
||||
|
@ -373,7 +198,6 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
|
||||
Subject.IsSatisfiedBy(parseResult, null).Should().BeFalse();
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
Mocker.SetConstant<IEnumerable<IRejectWithReason>>(mocks.Select(c => c.Object));
|
||||
Mocker.SetConstant<IEnumerable<IDecisionEngineSpecification>>(mocks.Select(c => c.Object));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -83,7 +83,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
private void GivenSabnzbdDownloadClient()
|
||||
{
|
||||
Mocker.GetMock<IProvideDownloadClient>()
|
||||
.Setup(c => c.GetDownloadClient()).Returns(Mocker.Resolve<SabnzbdClient>());
|
||||
.Setup(c => c.GetDownloadClient()).Returns(Mocker.Resolve<Sabnzbd>());
|
||||
}
|
||||
|
||||
private void GivenMostRecentForEpisode(HistoryEventType eventType)
|
||||
|
|
|
@ -56,9 +56,6 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
Mocker.GetMock<IProvideDownloadClient>()
|
||||
.Setup(s => s.GetDownloadClient())
|
||||
.Returns(_downloadClient.Object);
|
||||
|
||||
_downloadClient.SetupGet(s => s.IsConfigured)
|
||||
.Returns(true);
|
||||
}
|
||||
|
||||
private void GivenEmptyQueue()
|
||||
|
|
|
@ -20,65 +20,62 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
{
|
||||
parseResult = new RemoteEpisode
|
||||
{
|
||||
Release = new ReleaseInfo
|
||||
{
|
||||
PublishDate = DateTime.Now.AddDays(-100)
|
||||
}
|
||||
Release = new ReleaseInfo()
|
||||
};
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private void WithShortRetention()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>().SetupGet(c => c.Retention).Returns(10);
|
||||
}
|
||||
|
||||
private void WithEqualRetention()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>().SetupGet(c => c.Retention).Returns(100);
|
||||
parseResult.Release.PublishDate = DateTime.Now.AddDays(-days);
|
||||
}
|
||||
|
||||
[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();
|
||||
}
|
||||
|
||||
[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();
|
||||
}
|
||||
|
||||
[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();
|
||||
}
|
||||
|
||||
[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();
|
||||
}
|
||||
|
||||
[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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,9 @@ using Moq;
|
|||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.Clients;
|
||||
using NzbDrone.Core.Download.Clients.Blackhole;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
|
@ -13,7 +14,7 @@ using NzbDrone.Test.Common;
|
|||
namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class BlackholeProviderFixture : CoreTest<BlackholeProvider>
|
||||
public class BlackholeProviderFixture : CoreTest<Blackhole>
|
||||
{
|
||||
private const string _nzbUrl = "http://www.nzbs.com/url";
|
||||
private const string _title = "some_nzb_title";
|
||||
|
@ -27,13 +28,16 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
|||
_blackHoleFolder = @"c:\nzb\blackhole\".AsOsAgnostic();
|
||||
_nzbPath = @"c:\nzb\blackhole\some_nzb_title.nzb".AsOsAgnostic();
|
||||
|
||||
|
||||
Mocker.GetMock<IConfigService>().SetupGet(c => c.BlackholeFolder).Returns(_blackHoleFolder);
|
||||
|
||||
_remoteEpisode = new RemoteEpisode();
|
||||
_remoteEpisode.Release = new ReleaseInfo();
|
||||
_remoteEpisode.Release.Title = _title;
|
||||
_remoteEpisode.Release.DownloadUrl = _nzbUrl;
|
||||
|
||||
Subject.Definition = new DownloadClientDefinition();
|
||||
Subject.Definition.Settings = new FolderSettings
|
||||
{
|
||||
Folder = _blackHoleFolder
|
||||
};
|
||||
}
|
||||
|
||||
private void WithExistingFile()
|
||||
|
|
|
@ -3,17 +3,15 @@ using System.Linq;
|
|||
using FizzWare.NBuilder;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.Clients.Nzbget;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
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 _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))
|
||||
.Build()
|
||||
.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]
|
||||
|
@ -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"};
|
||||
|
||||
Mocker.GetMock<INzbGetCommunicationProxy>()
|
||||
.Setup(s => s.AddNzb(p))
|
||||
Mocker.GetMock<INzbgetProxy>()
|
||||
.Setup(s => s.AddNzb(It.IsAny<NzbgetSettings>(), p))
|
||||
.Returns(true);
|
||||
|
||||
Mocker.Resolve<NzbgetClient>().DownloadNzb(_remoteEpisode);
|
||||
Subject.DownloadNzb(_remoteEpisode);
|
||||
|
||||
Mocker.GetMock<INzbGetCommunicationProxy>()
|
||||
.Verify(v => v.AddNzb(It.IsAny<object []>()), Times.Once());
|
||||
Mocker.GetMock<INzbgetProxy>()
|
||||
.Verify(v => v.AddNzb(It.IsAny<NzbgetSettings>(), It.IsAny<object []>()), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,40 +5,52 @@ using FizzWare.NBuilder;
|
|||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.Clients.Nzbget;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
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]
|
||||
public void Setup()
|
||||
{
|
||||
_queue = Builder<NzbGetQueueItem>.CreateListOfSize(5)
|
||||
_queue = Builder<NzbgetQueueItem>.CreateListOfSize(5)
|
||||
.All()
|
||||
.With(q => q.NzbName = "30.Rock.S01E01.Pilot.720p.hdtv.nzb")
|
||||
.Build()
|
||||
.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()
|
||||
{
|
||||
Mocker.GetMock<INzbGetCommunicationProxy>()
|
||||
.Setup(s => s.GetQueue())
|
||||
Mocker.GetMock<INzbgetProxy>()
|
||||
.Setup(s => s.GetQueue(It.IsAny<NzbgetSettings>()))
|
||||
.Returns(_queue);
|
||||
}
|
||||
|
||||
private void WithEmptyQueue()
|
||||
{
|
||||
Mocker.GetMock<INzbGetCommunicationProxy>()
|
||||
.Setup(s => s.GetQueue())
|
||||
.Returns(new List<NzbGetQueueItem>());
|
||||
Mocker.GetMock<INzbgetProxy>()
|
||||
.Setup(s => s.GetQueue(It.IsAny<NzbgetSettings>()))
|
||||
.Returns(new List<NzbgetQueueItem>());
|
||||
}
|
||||
|
||||
[Test]
|
|
@ -6,7 +6,9 @@ using NUnit.Framework;
|
|||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.Clients;
|
||||
using NzbDrone.Core.Download.Clients.Pneumatic;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
|
@ -14,7 +16,7 @@ using NzbDrone.Test.Common;
|
|||
namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class PneumaticProviderFixture : CoreTest<PneumaticClient>
|
||||
public class PneumaticProviderFixture : CoreTest<Pneumatic>
|
||||
{
|
||||
private const string _nzbUrl = "http://www.nzbs.com/url";
|
||||
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();
|
||||
_sabDrop = @"d:\unsorted tv\".AsOsAgnostic();
|
||||
|
||||
Mocker.GetMock<IConfigService>().SetupGet(c => c.PneumaticFolder).Returns(_pneumaticFolder);
|
||||
Mocker.GetMock<IConfigService>().SetupGet(c => c.DownloadedEpisodesFolder).Returns(_sabDrop);
|
||||
|
||||
_remoteEpisode = new RemoteEpisode();
|
||||
|
@ -41,6 +42,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
|||
|
||||
_remoteEpisode.ParsedEpisodeInfo = new ParsedEpisodeInfo();
|
||||
_remoteEpisode.ParsedEpisodeInfo.FullSeason = false;
|
||||
|
||||
Subject.Definition = new DownloadClientDefinition();
|
||||
Subject.Definition.Settings = new FolderSettings
|
||||
{
|
||||
Folder = _pneumaticFolder
|
||||
};
|
||||
}
|
||||
|
||||
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.Net;
|
||||
using FizzWare.NBuilder;
|
||||
|
@ -33,9 +34,6 @@ namespace NzbDrone.Core.Test.Download
|
|||
.With(c => c.Release = Builder<ReleaseInfo>.CreateNew().Build())
|
||||
.With(c => c.Episodes = episodes)
|
||||
.Build();
|
||||
|
||||
|
||||
Mocker.GetMock<IDownloadClient>().Setup(c => c.IsConfigured).Returns(true);
|
||||
}
|
||||
|
||||
private void WithSuccessfulAdd()
|
||||
|
@ -85,7 +83,8 @@ namespace NzbDrone.Core.Test.Download
|
|||
[Test]
|
||||
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);
|
||||
|
||||
|
|
|
@ -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>()
|
||||
.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);
|
||||
|
||||
|
||||
|
@ -150,7 +150,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
|||
{
|
||||
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>();
|
||||
|
||||
_videoFiles = new List<String>
|
||||
|
@ -168,7 +168,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
|||
Subject.GetImportDecisions(_videoFiles, _series, false);
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace NzbDrone.Core.Test.MetadataSourceTests
|
|||
[TestCase("Franklin & Bash", "Franklin & Bash")]
|
||||
[TestCase("Mr. D", "Mr. D")]
|
||||
[TestCase("Rob & Big", "Rob and Big")]
|
||||
[TestCase("M*A*S*H", "M*A*S*H")]
|
||||
public void successful_search(string title, string expected)
|
||||
{
|
||||
var result = Subject.SearchForNewSeries(title);
|
||||
|
@ -38,7 +39,7 @@ namespace NzbDrone.Core.Test.MetadataSourceTests
|
|||
}
|
||||
|
||||
[TestCase(75978)]
|
||||
[TestCase(79349)]
|
||||
[TestCase(83462)]
|
||||
public void should_be_able_to_get_series_detail(int tvdbId)
|
||||
{
|
||||
var details = Subject.GetSeriesInfo(tvdbId);
|
||||
|
|
|
@ -122,10 +122,10 @@
|
|||
<Compile Include="Download\DownloadApprovedReportsTests\DownloadApprovedFixture.cs" />
|
||||
<Compile Include="Download\DownloadApprovedReportsTests\GetQualifiedReportsFixture.cs" />
|
||||
<Compile Include="Download\DownloadClientTests\BlackholeProviderFixture.cs" />
|
||||
<Compile Include="Download\DownloadClientTests\NzbgetProviderTests\DownloadNzbFixture.cs" />
|
||||
<Compile Include="Download\DownloadClientTests\NzbgetProviderTests\QueueFixture.cs" />
|
||||
<Compile Include="Download\DownloadClientTests\NzbgetTests\DownloadNzbFixture.cs" />
|
||||
<Compile Include="Download\DownloadClientTests\NzbgetTests\QueueFixture.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\FailedDownloadServiceFixture.cs" />
|
||||
<Compile Include="Framework\CoreTest.cs" />
|
||||
|
@ -180,6 +180,17 @@
|
|||
<Compile Include="NotificationTests\Xbmc\OnDownloadFixture.cs" />
|
||||
<Compile Include="OrganizerTests\BuildFilePathFixture.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\GetSeriesFixture.cs" />
|
||||
<Compile Include="ParserTests\ParsingServiceTests\MapFixture.cs" />
|
||||
|
@ -287,18 +298,9 @@
|
|||
<Content Include="Files\LongOverview.txt">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Files\HistoryEmpty.txt">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Files\Queue.txt">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</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">
|
||||
<Link>App.config</Link>
|
||||
</None>
|
||||
|
@ -330,9 +332,6 @@
|
|||
<Content Include="Files\RSS\newznab.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Files\Categories_json.txt">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Files\RSS\SizeParsing\newznab.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</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 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
|
||||
{
|
||||
|
@ -26,179 +23,6 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
* 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("[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)]
|
||||
|
@ -232,138 +56,6 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
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("Law & Order - 4x05 - Title", "laworder")]
|
||||
[TestCase("Bad Format", "badformat")]
|
||||
|
@ -376,115 +68,10 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
[TestCase("Hawaii Five 0", "hawaiifive0")]
|
||||
[TestCase("Match of the Day", "matchday")]
|
||||
[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);
|
||||
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,
|
||||
Password,
|
||||
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;
|
||||
|
||||
namespace NzbDrone.Core.Blacklisting
|
||||
|
@ -6,6 +9,7 @@ namespace NzbDrone.Core.Blacklisting
|
|||
public interface IBlacklistRepository : IBasicRepository<Blacklist>
|
||||
{
|
||||
bool Blacklisted(string sourceTitle);
|
||||
List<Blacklist> BlacklistedBySeries(int seriesId);
|
||||
}
|
||||
|
||||
public class BlacklistRepository : BasicRepository<Blacklist>, IBlacklistRepository
|
||||
|
@ -17,7 +21,12 @@ namespace NzbDrone.Core.Blacklisting
|
|||
|
||||
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.Messaging.Commands;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Tv.Events;
|
||||
|
||||
namespace NzbDrone.Core.Blacklisting
|
||||
{
|
||||
|
@ -13,7 +14,7 @@ namespace NzbDrone.Core.Blacklisting
|
|||
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 IRedownloadFailedDownloads _redownloadFailedDownloadService;
|
||||
|
@ -39,6 +40,11 @@ namespace NzbDrone.Core.Blacklisting
|
|||
_blacklistRepository.Delete(id);
|
||||
}
|
||||
|
||||
public void Execute(ClearBlacklistCommand message)
|
||||
{
|
||||
_blacklistRepository.Purge();
|
||||
}
|
||||
|
||||
public void Handle(DownloadFailedEvent message)
|
||||
{
|
||||
var blacklist = new Blacklist
|
||||
|
@ -55,9 +61,11 @@ namespace NzbDrone.Core.Blacklisting
|
|||
_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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
public void SaveValues(Dictionary<string, object> configValues)
|
||||
public void SaveConfigDictionary(Dictionary<string, object> configValues)
|
||||
{
|
||||
var allWithDefaults = AllWithDefaults();
|
||||
|
||||
|
@ -73,69 +73,6 @@ namespace NzbDrone.Core.Configuration
|
|||
_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
|
||||
{
|
||||
get { return GetValue(ConfigKey.DownloadedEpisodesFolder.ToString()); }
|
||||
|
@ -155,80 +92,12 @@ namespace NzbDrone.Core.Configuration
|
|||
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
|
||||
{
|
||||
get { return GetValue("RecycleBin", String.Empty); }
|
||||
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
|
||||
{
|
||||
get { return GetValue("ReleaseRestrictions", String.Empty).Trim('\r', '\n'); }
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.Clients.Nzbget;
|
||||
using NzbDrone.Core.Download.Clients.Sabnzbd;
|
||||
|
||||
namespace NzbDrone.Core.Configuration
|
||||
{
|
||||
|
@ -10,42 +7,33 @@ namespace NzbDrone.Core.Configuration
|
|||
{
|
||||
IEnumerable<Config> All();
|
||||
Dictionary<String, Object> AllWithDefaults();
|
||||
String SabHost { get; set; }
|
||||
int SabPort { get; set; }
|
||||
String SabApiKey { get; set; }
|
||||
String SabUsername { get; set; }
|
||||
String SabPassword { get; set; }
|
||||
String SabTvCategory { get; set; }
|
||||
SabPriorityType SabRecentTvPriority { get; set; }
|
||||
SabPriorityType SabOlderTvPriority { get; set; }
|
||||
Boolean SabUseSsl { get; set; }
|
||||
void SaveConfigDictionary(Dictionary<string, object> configValues);
|
||||
|
||||
//Download Client
|
||||
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; }
|
||||
|
||||
//Failed Download Handling (Download client)
|
||||
Boolean AutoRedownloadFailed { get; set; }
|
||||
Boolean RemoveFailedDownloads { get; set; }
|
||||
Boolean EnableFailedDownloadHandling { get; set; }
|
||||
|
||||
//Media Management
|
||||
Boolean AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
|
||||
String RecycleBin { get; set; }
|
||||
Boolean AutoDownloadPropers { get; set; }
|
||||
Boolean CreateEmptySeriesFolders { get; set; }
|
||||
void SaveValues(Dictionary<string, object> configValues);
|
||||
|
||||
//Permissions (Media Management)
|
||||
Boolean SetPermissionsLinux { get; set; }
|
||||
String FileChmod { get; set; }
|
||||
String FolderChmod { get; set; }
|
||||
String ChownUser { 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.Linq;
|
||||
using System.Web.UI.WebControls;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace NzbDrone.Core.Datastore
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -142,23 +142,44 @@ namespace NzbDrone.Core.Datastore
|
|||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
models.ForEach(Delete);
|
||||
DeleteMany(models.Select(m => m.Id));
|
||||
}
|
||||
|
||||
public TModel Upsert(TModel model)
|
||||
|
@ -179,7 +200,19 @@ namespace NzbDrone.Core.Datastore
|
|||
|
||||
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()
|
||||
|
|
|
@ -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.DataAugmentation.Scene;
|
||||
using NzbDrone.Core.Datastore.Converters;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Instrumentation;
|
||||
using NzbDrone.Core.Jobs;
|
||||
|
@ -39,6 +40,7 @@ namespace NzbDrone.Core.Datastore
|
|||
Mapper.Entity<ScheduledTask>().RegisterModel("ScheduledTasks");
|
||||
Mapper.Entity<NotificationDefinition>().RegisterModel("Notifications");
|
||||
Mapper.Entity<MetadataDefinition>().RegisterModel("Metadata");
|
||||
Mapper.Entity<DownloadClientDefinition>().RegisterModel("DownloadClients");
|
||||
|
||||
Mapper.Entity<SceneMapping>().RegisterModel("SceneMappings");
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace NzbDrone.Core.DecisionEngine
|
|||
private readonly IParsingService _parsingService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public DownloadDecisionMaker(IEnumerable<IRejectWithReason> specifications, IParsingService parsingService, Logger logger)
|
||||
public DownloadDecisionMaker(IEnumerable<IDecisionEngineSpecification> specifications, IParsingService parsingService, Logger logger)
|
||||
{
|
||||
_specifications = specifications;
|
||||
_parsingService = parsingService;
|
||||
|
@ -63,6 +63,15 @@ namespace NzbDrone.Core.DecisionEngine
|
|||
{
|
||||
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))
|
||||
{
|
||||
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, report.TvRageId, searchCriteria);
|
||||
|
@ -91,13 +100,12 @@ namespace NzbDrone.Core.DecisionEngine
|
|||
yield return decision;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private DownloadDecision GetDecisionForReport(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria = null)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using NLog;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
|
|
|
@ -27,7 +27,6 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
|||
|
||||
public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
||||
{
|
||||
|
||||
_logger.Trace("Beginning size check for: {0}", subject);
|
||||
|
||||
var quality = subject.ParsedEpisodeInfo.Quality.Quality;
|
||||
|
@ -45,34 +44,43 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
_logger.Trace("Max size is 0 (unlimited) - skipping check.");
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
else
|
||||
{
|
||||
maxSize = maxSize * 2;
|
||||
}
|
||||
var maxSize = qualityDefinition.MaxSize.Megabytes();
|
||||
|
||||
//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;
|
||||
}
|
||||
//Multiply maxSize by Series.Runtime
|
||||
maxSize = maxSize * subject.Series.Runtime * subject.Episodes.Count;
|
||||
|
||||
//Check if there was only one episode parsed and it is the first
|
||||
if (subject.Episodes.Count == 1 && _episodeService.IsFirstOrLastEpisodeOfSeason(subject.Episodes.First().Id))
|
||||
{
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ using NzbDrone.Core.Download;
|
|||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
{
|
||||
|
@ -32,9 +31,9 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,9 +28,10 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
|||
public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
||||
{
|
||||
var age = subject.Release.Age;
|
||||
var retention = _configService.Retention;
|
||||
|
||||
_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);
|
||||
return false;
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
|
|||
return true;
|
||||
}
|
||||
|
||||
if (_downloadClientProvider.GetDownloadClient().GetType() == typeof (SabnzbdClient))
|
||||
if (_downloadClientProvider.GetDownloadClient().GetType() == typeof (Sabnzbd))
|
||||
{
|
||||
_logger.Trace("Performing history status check on report");
|
||||
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
|
||||
{
|
||||
public class NzbGetQueue
|
||||
public class NzbgetQueue
|
||||
{
|
||||
public String Version { get; set; }
|
||||
|
||||
[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
|
||||
{
|
||||
public class NzbGetQueueItem
|
||||
public class NzbgetQueueItem
|
||||
{
|
||||
private string _nzbName;
|
||||
|
||||
public Int32 NzbId { get; set; }
|
||||
|
||||
public string NzbName { get; set; }
|
||||
|
||||
public String Category { get; set; }
|
||||
public Int32 FileSizeMb { 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
|
||||
{
|
||||
public enum PriorityType
|
||||
public enum NzbgetPriority
|
||||
{
|
||||
VeryLow = -100,
|
||||
Low = -50,
|
|
@ -1,57 +1,52 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Rest;
|
||||
using RestSharp;
|
||||
|
||||
namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||
{
|
||||
public interface INzbGetCommunicationProxy
|
||||
public interface INzbgetProxy
|
||||
{
|
||||
bool AddNzb(params object[] parameters);
|
||||
List<NzbGetQueueItem> GetQueue();
|
||||
string GetVersion();
|
||||
bool AddNzb(NzbgetSettings settings, params object[] parameters);
|
||||
List<NzbgetQueueItem> GetQueue(NzbgetSettings settings);
|
||||
VersionResponse GetVersion(NzbgetSettings settings);
|
||||
}
|
||||
|
||||
public class NzbGetCommunicationProxy : INzbGetCommunicationProxy
|
||||
public class NzbgetProxy : INzbgetProxy
|
||||
{
|
||||
private readonly IConfigService _configService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public NzbGetCommunicationProxy(IConfigService configService, Logger logger)
|
||||
public NzbgetProxy(Logger logger)
|
||||
{
|
||||
_configService = configService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public bool AddNzb(params object[] parameters)
|
||||
public bool AddNzb(NzbgetSettings settings, params object[] 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"));
|
||||
|
||||
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);
|
||||
_logger.Trace("Response: {0}", response.Content);
|
||||
|
||||
|
@ -60,14 +55,14 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
|||
return response.Content;
|
||||
}
|
||||
|
||||
private IRestClient BuildClient()
|
||||
private IRestClient BuildClient(NzbgetSettings settings)
|
||||
{
|
||||
var url = String.Format("http://{0}:{1}/jsonrpc",
|
||||
_configService.NzbgetHost,
|
||||
_configService.NzbgetPort);
|
||||
settings.Host,
|
||||
settings.Port);
|
||||
|
||||
var client = new RestClient(url);
|
||||
client.Authenticator = new HttpBasicAuthenticator(_configService.NzbgetUsername, _configService.NzbgetPassword);
|
||||
client.Authenticator = new HttpBasicAuthenticator(settings.Username, settings.Password);
|
||||
|
||||
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
|
||||
{
|
||||
public class VersionModel
|
||||
public class VersionResponse
|
||||
{
|
||||
public String Version { get; set; }
|
||||
public String Result { get; set; }
|
|
@ -6,12 +6,13 @@ using NzbDrone.Common;
|
|||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Organizer;
|
||||
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 IHttpProvider _httpProvider;
|
||||
|
@ -19,7 +20,7 @@ namespace NzbDrone.Core.Download.Clients
|
|||
|
||||
private static readonly Logger logger = NzbDroneLogger.GetLogger();
|
||||
|
||||
public PneumaticClient(IConfigService configService, IHttpProvider httpProvider,
|
||||
public Pneumatic(IConfigService configService, IHttpProvider httpProvider,
|
||||
IDiskProvider diskProvider)
|
||||
{
|
||||
_configService = configService;
|
||||
|
@ -27,20 +28,20 @@ namespace NzbDrone.Core.Download.Clients
|
|||
_diskProvider = diskProvider;
|
||||
}
|
||||
|
||||
public string DownloadNzb(RemoteEpisode remoteEpisode)
|
||||
public override string DownloadNzb(RemoteEpisode remoteEpisode)
|
||||
{
|
||||
var url = remoteEpisode.Release.DownloadUrl;
|
||||
var title = remoteEpisode.Release.Title;
|
||||
|
||||
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);
|
||||
|
||||
//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);
|
||||
_httpProvider.DownloadFile(url, filename);
|
||||
|
@ -57,31 +58,33 @@ namespace NzbDrone.Core.Download.Clients
|
|||
{
|
||||
get
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(_configService.PneumaticFolder);
|
||||
return !string.IsNullOrWhiteSpace(Settings.Folder);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<QueueItem> GetQueue()
|
||||
public override IEnumerable<QueueItem> GetQueue()
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
var priorityType = (SabPriorityType)value;
|
||||
var priorityType = (SabnzbdPriority)value;
|
||||
writer.WriteValue(priorityType.ToString());
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd.JsonConverters
|
|||
{
|
||||
var queuePriority = reader.Value.ToString();
|
||||
|
||||
SabPriorityType output;
|
||||
SabnzbdPriority output;
|
||||
Enum.TryParse(queuePriority, out output);
|
||||
|
||||
return output;
|
||||
|
@ -23,7 +23,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd.JsonConverters
|
|||
|
||||
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