Merge branch 'develop'

pull/38/merge
Mark McDowall 11 years ago
commit b621b49b62

@ -6,7 +6,6 @@ using NzbDrone.Api.Mapping;
using NzbDrone.Api.Validation;
using NzbDrone.Common.Composition;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Commands.Tracking;
using NzbDrone.Core.Messaging.Events;

@ -3,7 +3,7 @@ using FluentValidation;
using NLog;
using Nancy;
using NzbDrone.Api.Extensions;
using NzbDrone.Core;
using NzbDrone.Core.Exceptions;
using HttpStatusCode = Nancy.HttpStatusCode;
namespace NzbDrone.Api.ErrorManagement
@ -17,9 +17,11 @@ namespace NzbDrone.Api.ErrorManagement
_logger = logger;
}
public Response HandleException(NancyContext context, Exception exception)
public Response HandleException(NancyContext context, Exception aggregateException)
{
var apiException = exception as ApiException;
var innerException = (aggregateException.InnerException).InnerException;
var apiException = innerException as ApiException;
if (apiException != null)
{
@ -27,7 +29,7 @@ namespace NzbDrone.Api.ErrorManagement
return apiException.ToErrorResponse();
}
var validationException = exception as ValidationException;
var validationException = innerException as ValidationException;
if (validationException != null)
{
@ -36,23 +38,23 @@ namespace NzbDrone.Api.ErrorManagement
return validationException.Errors.AsResponse(HttpStatusCode.BadRequest);
}
var clientException = exception as NzbDroneClientException;
var clientException = innerException as NzbDroneClientException;
if (clientException != null)
{
return new ErrorModel
{
Message = exception.Message,
Description = exception.ToString()
Message = innerException.Message,
Description = innerException.ToString()
}.AsResponse((HttpStatusCode)clientException.StatusCode);
}
_logger.FatalException("Request Failed", exception);
_logger.FatalException("Request Failed", innerException);
return new ErrorModel
{
Message = exception.Message,
Description = exception.ToString()
Message = innerException.Message,
Description = innerException.ToString()
}.AsResponse(HttpStatusCode.InternalServerError);
}
}

@ -1,4 +1,5 @@
using System.IO;
using Nancy;
using NLog;
using NzbDrone.Common;
using NzbDrone.Common.EnvironmentInfo;
@ -27,6 +28,14 @@ namespace NzbDrone.Api.Frontend.Mappers
return !resourceUrl.Contains(".");
}
public override Response GetResponse(string resourceUrl)
{
var response = base.GetResponse(resourceUrl);
response.Headers["X-UA-Compatible"] = "IE=edge";
return response;
}
protected override Stream GetContentStream(string filePath)
{
return StringToStream(GetIndexText());

@ -33,7 +33,7 @@ namespace NzbDrone.Api.Frontend.Mappers
public abstract bool CanHandle(string resourceUrl);
public Response GetResponse(string resourceUrl)
public virtual Response GetResponse(string resourceUrl)
{
var filePath = Map(resourceUrl);

@ -1,7 +1,8 @@
using System.Collections.Generic;
using FluentValidation;
using Nancy;
using NLog;
using NzbDrone.Api.Mapping;
using NzbDrone.Api.REST;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Download;
@ -9,6 +10,7 @@ using NzbDrone.Core.IndexerSearch;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv;
using Omu.ValueInjecter;
using System.Linq;
using Nancy.ModelBinding;
@ -37,13 +39,14 @@ namespace NzbDrone.Api.Indexers
_parsingService = parsingService;
GetResourceAll = GetReleases;
Post["/"] = x=> DownloadRelease(this.Bind<ReleaseResource>());
PostValidator.RuleFor(s => s.DownloadAllowed).Equal(true);
}
private Response DownloadRelease(ReleaseResource release)
{
var remoteEpisode = _parsingService.Map(release.InjectTo<ParsedEpisodeInfo>(), 0);
remoteEpisode.Release = release.InjectTo<ReleaseInfo>();
_downloadService.DownloadReport(remoteEpisode);
return release.AsResponse();
@ -86,6 +89,7 @@ namespace NzbDrone.Api.Indexers
release.InjectFrom(downloadDecision.RemoteEpisode.ParsedEpisodeInfo);
release.InjectFrom(downloadDecision);
release.Rejections = downloadDecision.Rejections.ToList();
release.DownloadAllowed = downloadDecision.RemoteEpisode.DownloadAllowed;
result.Add(release);
}

@ -28,5 +28,6 @@ namespace NzbDrone.Api.Indexers
public String CommentUrl { get; set; }
public String DownloadUrl { get; set; }
public String InfoUrl { get; set; }
public Boolean DownloadAllowed { get; set; }
}
}

@ -7,7 +7,6 @@ using NzbDrone.Api.Extensions.Pipelines;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;
using TinyIoC;

@ -46,12 +46,13 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.SignalR.Core.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Core.dll</HintPath>
</Reference>
<Reference Include="Nancy">
<HintPath>..\packages\Nancy.0.18.0\lib\net40\Nancy.dll</HintPath>
<Reference Include="Nancy, Version=0.20.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Nancy.0.20.0\lib\net40\Nancy.dll</HintPath>
</Reference>
<Reference Include="Nancy.Authentication.Basic, Version=0.18.0.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="Nancy.Authentication.Basic, Version=0.20.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Nancy.Authentication.Basic.0.18.0\lib\net40\Nancy.Authentication.Basic.dll</HintPath>
<HintPath>..\packages\Nancy.Authentication.Basic.0.20.0\lib\net40\Nancy.Authentication.Basic.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@ -190,4 +191,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>

@ -1,7 +1,6 @@
using NzbDrone.Api.REST;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.SignalR;

@ -8,9 +8,9 @@ namespace NzbDrone.Api.Qualities
{
public class QualityProfileModule : NzbDroneRestModule<QualityProfileResource>
{
private readonly QualityProfileService _qualityProfileService;
private readonly IQualityProfileService _qualityProfileService;
public QualityProfileModule(QualityProfileService qualityProfileService)
public QualityProfileModule(IQualityProfileService qualityProfileService)
: base("/qualityprofiles")
{
_qualityProfileService = qualityProfileService;

@ -6,9 +6,9 @@ namespace NzbDrone.Api.Qualities
{
public class QualitySizeModule : NzbDroneRestModule<QualitySizeResource>
{
private readonly QualitySizeService _qualityTypeProvider;
private readonly IQualitySizeService _qualityTypeProvider;
public QualitySizeModule(QualitySizeService qualityTypeProvider)
public QualitySizeModule(IQualitySizeService qualityTypeProvider)
{
_qualityTypeProvider = qualityTypeProvider;

@ -2,8 +2,8 @@
<packages>
<package id="FluentValidation" version="4.0.0.1" targetFramework="net40" />
<package id="Microsoft.AspNet.SignalR.Core" version="1.1.3" targetFramework="net40" />
<package id="Nancy" version="0.18.0" targetFramework="net40" />
<package id="Nancy.Authentication.Basic" version="0.18.0" targetFramework="net40" />
<package id="Nancy" version="0.20.0" targetFramework="net40" />
<package id="Nancy.Authentication.Basic" version="0.20.0" targetFramework="net40" />
<package id="Newtonsoft.Json" version="5.0.6" targetFramework="net40" />
<package id="NLog" version="2.0.1.2" targetFramework="net40" />
<package id="ValueInjecter" version="2.3.3" targetFramework="net40" />

@ -6,7 +6,6 @@ using NzbDrone.Core.Download;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Jobs;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Host;

@ -4,6 +4,7 @@ using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Common.Model;
using NzbDrone.Common.Processes;
using NzbDrone.Host;
using NzbDrone.Test.Common;

@ -1,36 +1,43 @@
using FluentAssertions;
using System.IO;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Test.Common;
namespace NzbDrone.Common.Test.DiskProviderTests
{
[TestFixture]
public class IsParentFixture : TestBase<DiskProvider>
public class FreeSpaceFixture : TestBase<DiskProvider>
{
private string _parent = @"C:\Test".AsOsAgnostic();
[Test]
public void should_return_false_when_not_a_child()
public void should_get_free_space_for_folder()
{
var path = @"C:\Another Folder".AsOsAgnostic();
var path = @"C:\".AsOsAgnostic();
Subject.IsParent(_parent, path).Should().BeFalse();
Subject.GetAvailableSpace(path).Should().NotBe(0);
}
[Test]
public void should_return_true_when_folder_is_parent_of_another_folder()
public void should_get_free_space_for_folder_that_doesnt_exist()
{
var path = @"C:\Test\TV".AsOsAgnostic();
var path = @"C:\".AsOsAgnostic();
Subject.IsParent(_parent, path).Should().BeTrue();
Subject.GetAvailableSpace(Path.Combine(path, "invalidFolder")).Should().NotBe(0);
}
[Test]
public void should_return_true_when_folder_is_parent_of_a_file()
public void should_get_free_space_for_drive_that_doesnt_exist()
{
var path = @"C:\Test\30.Rock.S01E01.Pilot.avi".AsOsAgnostic();
WindowsOnly();
Assert.Throws<DirectoryNotFoundException>(() => Subject.GetAvailableSpace("J:\\").Should().NotBe(0));
}
Subject.IsParent(_parent, path).Should().BeTrue();
[Test]
public void should_be_able_to_check_space_on_ramdrive()
{
LinuxOnly();
Subject.GetAvailableSpace("/run/").Should().NotBe(0);
}
}
}

@ -1,43 +1,36 @@
using System.IO;
using FluentAssertions;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Test.Common;
namespace NzbDrone.Common.Test.DiskProviderTests
{
[TestFixture]
public class FreeSpaceFixture : TestBase<DiskProvider>
public class IsParentFixture : TestBase<DiskProvider>
{
[Test]
public void should_get_free_space_for_folder()
{
var path = @"C:\".AsOsAgnostic();
Subject.GetAvailableSpace(path).Should().NotBe(0);
}
private string _parent = @"C:\Test".AsOsAgnostic();
[Test]
public void should_get_free_space_for_folder_that_doesnt_exist()
public void should_return_false_when_not_a_child()
{
var path = @"C:\".AsOsAgnostic();
var path = @"C:\Another Folder".AsOsAgnostic();
Subject.GetAvailableSpace(Path.Combine(path, "invalidFolder")).Should().NotBe(0);
Subject.IsParent(_parent, path).Should().BeFalse();
}
[Test]
public void should_get_free_space_for_drive_that_doesnt_exist()
public void should_return_true_when_folder_is_parent_of_another_folder()
{
WindowsOnly();
var path = @"C:\Test\TV".AsOsAgnostic();
Assert.Throws<DirectoryNotFoundException>(() => Subject.GetAvailableSpace("J:\\").Should().NotBe(0));
Subject.IsParent(_parent, path).Should().BeTrue();
}
[Test]
public void should_be_able_to_check_space_on_ramdrive()
public void should_return_true_when_folder_is_parent_of_a_file()
{
LinuxOnly();
Subject.GetAvailableSpace("/run/").Should().NotBe(0);
var path = @"C:\Test\30.Rock.S01E01.Pilot.avi".AsOsAgnostic();
Subject.IsParent(_parent, path).Should().BeTrue();
}
}
}

@ -6,6 +6,7 @@ using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.Model;
using NzbDrone.Common.Processes;
using NzbDrone.Test.Common;
using NzbDrone.Test.Dummy;

@ -3,7 +3,6 @@ using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Host;
using NzbDrone.Test.Common;

@ -1,21 +0,0 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace NzbDrone.Common.Contract
{
public class ParseErrorReport : ReportBase
{
[JsonProperty("t")]
public string Title { get; set; }
protected override Dictionary<string, string> GetString()
{
var dic = new Dictionary<string, string>
{
{"Title", Title.NullSafe()},
};
return dic;
}
}
}

@ -1,31 +0,0 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace NzbDrone.Common.Contract
{
public abstract class ReportBase
{
[JsonProperty("v")]
public string Version { get; set; }
[JsonProperty("p")]
public bool IsProduction { get; set; }
[JsonProperty("u")]
public Guid UGuid { get; set; }
public override string ToString()
{
var childString = "";
foreach (var keyValue in GetString())
{
childString += string.Format("{0}: {1} ", keyValue.Key, keyValue.Value);
}
return string.Format("[{0} Prd:{1} V:{2} ID:{3} | {4}]", GetType().Name, IsProduction, Version, UGuid, childString.Trim());
}
protected abstract Dictionary<string,string> GetString();
}
}

@ -1,4 +1,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using NzbDrone.Common.EnsureThat.Resources;
using NzbDrone.Common.EnvironmentInfo;
@ -73,7 +76,6 @@ namespace NzbDrone.Common.EnsureThat
return param;
}
[DebuggerStepThrough]
public static Param<string> IsRelativePath(this Param<string> param)
{
@ -94,8 +96,6 @@ namespace NzbDrone.Common.EnsureThat
return param;
}
[DebuggerStepThrough]
public static Param<string> IsValidPath(this Param<string> param)
{

@ -4,7 +4,7 @@ using System.Linq;
namespace NzbDrone.Common
{
public static class IEnumerableExtensions
public static class EnumerableExtensions
{
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{

@ -98,6 +98,8 @@
<Compile Include="Messaging\IEvent.cs" />
<Compile Include="Messaging\IMessage.cs" />
<Compile Include="PathEqualityComparer.cs" />
<Compile Include="Processes\ProcessOutput.cs" />
<Compile Include="Serializer\IntConverter.cs" />
<Compile Include="Services.cs" />
<Compile Include="TPL\LimitedConcurrencyLevelTaskScheduler.cs" />
<Compile Include="Security\IgnoreCertErrorPolicy.cs" />
@ -117,16 +119,13 @@
<Compile Include="ServiceFactory.cs" />
<Compile Include="HttpProvider.cs" />
<Compile Include="ConsoleService.cs" />
<Compile Include="Contract\ReportBase.cs" />
<Compile Include="Contract\ParseErrorReport.cs" />
<Compile Include="PathExtensions.cs" />
<Compile Include="DiskProvider.cs" />
<Compile Include="EnvironmentInfo\AppFolderInfo.cs" />
<Compile Include="Model\ProcessInfo.cs" />
<Compile Include="ProcessProvider.cs" />
<Compile Include="Processes\ProcessProvider.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\SharedAssemblyInfo.cs" />
<Compile Include="RestProvider.cs" />
<Compile Include="ServiceProvider.cs" />
<Compile Include="TinyIoC.cs" />
<Compile Include="TPL\TaskExtensions.cs" />

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
namespace NzbDrone.Common.Processes
{
public class ProcessOutput
{
public List<String> Standard { get; set; }
public List<String> Error { get; set; }
public ProcessOutput()
{
Standard = new List<string>();
Error = new List<string>();
}
}
}

@ -9,7 +9,7 @@ using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Common.Model;
namespace NzbDrone.Common
namespace NzbDrone.Common.Processes
{
public interface IProcessProvider
{
@ -23,6 +23,7 @@ namespace NzbDrone.Common
ProcessPriorityClass GetCurrentProcessPriority();
Process Start(string path, string args = null, Action<string> onOutputDataReceived = null, Action<string> onErrorDataReceived = null);
Process SpawnNewProcess(string path, string args = null);
ProcessOutput StartAndCapture(string path, string args = null);
}
public class ProcessProvider : IProcessProvider
@ -88,11 +89,8 @@ namespace NzbDrone.Common
process.Start();
}
public Process Start(string path, string args = null, Action<string> onOutputDataReceived = null, Action<string> onErrorDataReceived = null)
{
if (OsInfo.IsMono && path.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase))
{
args = path + " " + args;
@ -147,7 +145,6 @@ namespace NzbDrone.Common
process.BeginErrorReadLine();
process.BeginOutputReadLine();
return process;
}
@ -172,6 +169,16 @@ namespace NzbDrone.Common
return process;
}
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);
return output;
}
public void WaitForExit(Process process)
{
Logger.Trace("Waiting for process {0} to exit.", process.ProcessName);
@ -225,7 +232,6 @@ namespace NzbDrone.Common
return null;
}
private static string GetExeFileName(Process process)
{
if (process.MainModule.FileName != "mono.exe")

@ -1,60 +0,0 @@
using System;
using System.IO;
using System.Net;
using System.Text;
using Newtonsoft.Json;
using NzbDrone.Common.Contract;
using NzbDrone.Common.EnvironmentInfo;
namespace NzbDrone.Common
{
public class RestProvider
{
private const int TIMEOUT = 15000;
private const string METHOD = "POST";
public virtual void PostData(string url, ReportBase reportBase)
{
reportBase.Version = BuildInfo.Version.ToString();
reportBase.IsProduction = RuntimeInfo.IsProduction;
PostData(url, reportBase as object);
}
private static void PostData(string url, object message)
{
try
{
var json = JsonConvert.SerializeObject(message);
var request = (HttpWebRequest)WebRequest.Create(url);
request.Timeout = TIMEOUT;
request.Proxy = WebRequest.DefaultWebProxy;
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
request.Method = METHOD;
request.ContentType = "application/json";
byte[] postBytes = Encoding.UTF8.GetBytes(json);
request.ContentLength = postBytes.Length;
var requestStream = request.GetRequestStream();
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
var response = (HttpWebResponse)request.GetResponse();
var streamreader = new StreamReader(response.GetResponseStream());
streamreader.Close();
}
catch (Exception e)
{
e.Data.Add("URL", url);
throw;
}
}
}
}

@ -0,0 +1,39 @@
using System;
using Newtonsoft.Json;
namespace NzbDrone.Common.Serializer
{
public class IntConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
}
else
{
writer.WriteValue(value);
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (!CanConvert(objectType))
{
throw new JsonSerializationException("Can't convert type " + existingValue.GetType().FullName + " to number");
}
if (objectType == typeof(Int64))
{
return Convert.ToInt64(reader.Value);
}
return Convert.ToInt32(reader.Value);
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Int32) || objectType == typeof(Int64) || objectType == typeof(int);
}
}
}

@ -8,42 +8,48 @@ namespace NzbDrone.Common.Serializer
{
public static class Json
{
private static readonly JsonSerializer JsonNetSerializer;
private static readonly JsonSerializer Serializer;
private static readonly JsonSerializerSettings SerializerSetting;
static Json()
{
JsonNetSerializer = new JsonSerializer()
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
NullValueHandling = NullValueHandling.Ignore,
Formatting = Formatting.Indented,
DefaultValueHandling = DefaultValueHandling.Include,
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
JsonNetSerializer.Converters.Add(new StringEnumConverter { CamelCaseText = true });
SerializerSetting = new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
NullValueHandling = NullValueHandling.Ignore,
Formatting = Formatting.Indented,
DefaultValueHandling = DefaultValueHandling.Include,
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
SerializerSetting.Converters.Add(new StringEnumConverter { CamelCaseText = true });
//SerializerSetting.Converters.Add(new IntConverter());
SerializerSetting.Converters.Add(new VersionConverter());
Serializer = JsonSerializer.Create(SerializerSetting);
}
public static T Deserialize<T>(string json) where T : class, new()
public static T Deserialize<T>(string json) where T : new()
{
return JsonConvert.DeserializeObject<T>(json);
return JsonConvert.DeserializeObject<T>(json, SerializerSetting);
}
public static object Deserialize(string json, Type type)
{
return JsonConvert.DeserializeObject(json, type);
return JsonConvert.DeserializeObject(json, type, SerializerSetting);
}
public static string ToJson(this object obj)
{
return JsonConvert.SerializeObject(obj);
return JsonConvert.SerializeObject(obj, SerializerSetting);
}
public static void Serialize<TModel>(TModel model, TextWriter outputStream)
{
var jsonTextWriter = new JsonTextWriter(outputStream);
JsonNetSerializer.Serialize(jsonTextWriter, model);
Serializer.Serialize(jsonTextWriter, model);
jsonTextWriter.Flush();
}

@ -1,7 +1,7 @@
using System.Net;
using FluentAssertions;
using NUnit.Framework;
using Newtonsoft.Json;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.DataAugmentation.Scene;
using NzbDrone.Core.Test.Framework;

@ -4,6 +4,7 @@ using FizzWare.NBuilder;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Download.Clients.Nzbget;
using NzbDrone.Core.Parser.Model;
@ -51,9 +52,16 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
[Test]
public void should_add_item_to_queue()
{
var command = new JsonRequest
{
Method = "appendurl",
Params = new object[] { "30.Rock.S01E01.Pilot.720p.hdtv.nzb", "TV", 50, false, "http://www.nzbdrone.com" }
};
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.PostCommand("192.168.5.55:6789", "nzbget", "pass",
It.Is<String>(c => c.Equals("{\"method\":\"appendurl\",\"params\":[\"30.Rock.S01E01.Pilot.720p.hdtv.nzb\",\"TV\",50,false,\"http://www.nzbdrone.com\"]}"))))
It.Is<String>(c => c.Equals(command.ToJson()))))
.Returns("{\"version\": \"1.1\",\"result\": true}");
Mocker.Resolve<NzbgetClient>().DownloadNzb(_remoteEpisode);

@ -8,7 +8,6 @@ using Moq;
using NUnit.Framework;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Migration.Framework;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;
@ -61,8 +60,6 @@ namespace NzbDrone.Core.Test.Framework
}
}
[Category("DbTest")]
public abstract class DbTest : CoreTest
{

@ -1,26 +0,0 @@
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Helpers;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.HelperTests
{
[TestFixture]
public class SortHelperTest : CoreTest
{
[TestCase("The Office (US)", "Office (US)")]
[TestCase("A Man in Anger", "Man in Anger")]
[TestCase("An Idiot Abroad", "Idiot Abroad")]
[TestCase("American Gladiators", "American Gladiators")]
[TestCase("Ancient Apocalyps", "Ancient Apocalyps")]
[TestCase("There Will Be Brawl", "There Will Be Brawl")]
[TestCase("30 Rock", "30 Rock")]
[TestCase(null, "")]
public void SkipArticles(string title, string expected)
{
var result = title.IgnoreArticles();
result.Should().Be(expected);
}
}
}

@ -4,6 +4,7 @@ using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.History;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Test.HistoryTests
{

@ -0,0 +1,43 @@
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Housekeeping.Housekeepers;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
{
[TestFixture]
public class CleanupOrphanedEpisodesFixture : DbTest<CleanupOrphanedEpisodes, Episode>
{
[Test]
public void should_delete_orphaned_episodes()
{
var episode = Builder<Episode>.CreateNew()
.BuildNew();
Db.Insert(episode);
Subject.Clean();
AllStoredModels.Should().BeEmpty();
}
[Test]
public void should_not_delete_unorphaned_episodes()
{
var series = Builder<Series>.CreateNew()
.BuildNew();
Db.Insert(series);
var episodes = Builder<Episode>.CreateListOfSize(2)
.TheFirst(1)
.With(e => e.SeriesId = series.Id)
.BuildListOfNew();
Db.InsertMany(episodes);
Subject.Clean();
AllStoredModels.Should().HaveCount(1);
AllStoredModels.Should().Contain(e => e.SeriesId == series.Id);
}
}
}

@ -0,0 +1,105 @@
using System;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Housekeeping.Housekeepers;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
{
[TestFixture]
public class CleanupOrphanedHistoryItemsFixture : DbTest<CleanupOrphanedHistoryItems, History.History>
{
private Series _series;
private Episode _episode;
[SetUp]
public void Setup()
{
_series = Builder<Series>.CreateNew()
.BuildNew();
_episode = Builder<Episode>.CreateNew()
.BuildNew();
}
private void GivenSeries()
{
Db.Insert(_series);
}
private void GivenEpisode()
{
Db.Insert(_episode);
}
[Test]
public void should_delete_orphaned_items_by_series()
{
GivenEpisode();
var history = Builder<History.History>.CreateNew()
.With(h => h.EpisodeId = _episode.Id)
.BuildNew();
Db.Insert(history);
Subject.Clean();
AllStoredModels.Should().BeEmpty();
}
[Test]
public void should_delete_orphaned_items_by_episode()
{
GivenSeries();
var history = Builder<History.History>.CreateNew()
.With(h => h.SeriesId = _series.Id)
.BuildNew();
Db.Insert(history);
Subject.Clean();
AllStoredModels.Should().BeEmpty();
}
[Test]
public void should_not_delete_unorphaned_data_by_series()
{
GivenSeries();
GivenEpisode();
var history = Builder<History.History>.CreateListOfSize(2)
.All()
.With(h => h.EpisodeId = _episode.Id)
.TheFirst(1)
.With(h => h.SeriesId = _series.Id)
.BuildListOfNew();
Db.InsertMany(history);
Subject.Clean();
AllStoredModels.Should().HaveCount(1);
AllStoredModels.Should().Contain(h => h.SeriesId == _series.Id);
}
[Test]
public void should_not_delete_unorphaned_data_by_episode()
{
GivenSeries();
GivenEpisode();
var history = Builder<History.History>.CreateListOfSize(2)
.All()
.With(h => h.SeriesId = _series.Id)
.TheFirst(1)
.With(h => h.EpisodeId = _episode.Id)
.BuildListOfNew();
Db.InsertMany(history);
Subject.Clean();
AllStoredModels.Should().HaveCount(1);
AllStoredModels.Should().Contain(h => h.EpisodeId == _episode.Id);
}
}
}

@ -7,7 +7,6 @@ using NUnit.Framework;
using NzbDrone.Core.MediaFiles.EpisodeImport.Specifications;
using NzbDrone.Core.MediaFiles.MediaInfo;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
using NzbDrone.Test.Common;

@ -7,7 +7,6 @@ using NUnit.Framework;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.EpisodeImport;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;

@ -1,12 +1,10 @@
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.MediaFiles
{
@ -33,37 +31,5 @@ namespace NzbDrone.Core.Test.MediaFiles
seriesFiles.Should().OnlyContain(c => c.SeriesId == 12);
}
[Test]
public void GetFileByPath_should_return_null_if_file_does_not_exist_in_database()
{
Subject.GetFileByPath(@"C:\Test\EpisodeFile.avi").Should().BeNull();
}
[Test]
public void exists_should_return_false_if_file_doesnt_exist()
{
Subject.Exists(@"C:\Test\EpisodeFile.avi").Should().BeFalse();
}
[Test]
public void GetFileByPath_should_return_EpisodeFile_if_file_exists_in_database()
{
var path = @"C:\Test\EpisodeFile.avi".AsOsAgnostic();
var episodeFile = Builder<EpisodeFile>.CreateNew()
.With(f => f.Id = 0)
.With(f => f.Path = path.CleanFilePath())
.Build();
Subject.Insert(episodeFile);
var file = Subject.GetFileByPath(path);
//Resolve
file.Should().NotBeNull();
file.Path.Should().Be(path.CleanFilePath());
}
}
}

@ -8,7 +8,6 @@ using NzbDrone.Core.MediaFiles.Commands;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Test.MediaFiles

@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Threading;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;

@ -3,7 +3,7 @@ using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.Notifications.Xbmc;
using NzbDrone.Core.Model.Xbmc;
using NzbDrone.Core.Notifications.Xbmc.Model;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.NotificationTests.Xbmc

@ -125,6 +125,7 @@
<Compile Include="Framework\CoreTest.cs" />
<Compile Include="Framework\DbTest.cs" />
<Compile Include="Framework\NBuilderExtensions.cs" />
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedHistoryItemsFixture.cs" />
<Compile Include="IndexerSearchTests\SearchDefinitionFixture.cs" />
<Compile Include="IndexerTests\BasicRssParserFixture.cs" />
<Compile Include="IndexerTests\IndexerServiceFixture.cs" />
@ -165,6 +166,7 @@
<Compile Include="OrganizerTests\BuildFilePathFixture.cs" />
<Compile Include="ParserTests\ParsingServiceTests\GetEpisodesFixture.cs" />
<Compile Include="ParserTests\ParsingServiceTests\MapFixture.cs" />
<Compile Include="Providers\XemProxyFixture.cs" />
<Compile Include="Qualities\QualitySizeRepositoryFixture.cs" />
<Compile Include="Qualities\QualityProfileRepositoryFixture.cs" />
<Compile Include="RootFolderTests\FreeSpaceOnDrivesFixture.cs" />
@ -178,6 +180,7 @@
<Compile Include="ProviderTests\RecycleBinProviderTests\DeleteFileFixture.cs" />
<Compile Include="ProviderTests\RecycleBinProviderTests\DeleteDirectoryFixture.cs" />
<Compile Include="NotificationTests\PlexProviderTest.cs" />
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodesFixture.cs" />
<Compile Include="TvTests\RefreshEpisodeServiceFixture.cs" />
<Compile Include="TvTests\EpisodeProviderTests\HandleEpisodeFileDeletedFixture.cs" />
<Compile Include="TvTests\EpisodeRepositoryTests\FindEpisodeFixture.cs" />
@ -197,9 +200,6 @@
<Compile Include="TvTests\SeriesRepositoryTests\QualityProfileRepositoryFixture.cs" />
<Compile Include="TvTests\SeriesServiceTests\UpdateSeriesFixture.cs" />
<Compile Include="UpdateTests\UpdateServiceFixture.cs" />
<Compile Include="ProviderTests\XemCommunicationProviderTests\GetSceneTvdbMappingsFixture.cs" />
<Compile Include="ProviderTests\XemCommunicationProviderTests\GetXemSeriesIdsFixture.cs" />
<Compile Include="HelperTests\SortHelperTest.cs" />
<Compile Include="DecisionEngineTests\AcceptableSizeSpecificationFixture.cs" />
<Compile Include="Qualities\QualitySizeServiceFixture.cs" />
<Compile Include="TvTests\EpisodeProviderTests\EpisodeProviderTest_GetEpisodesByParseResult.cs" />

@ -3,7 +3,6 @@ using System.Linq;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Common.Contract;
using NzbDrone.Common.Expansive;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Test.Framework;
@ -116,17 +115,6 @@ namespace NzbDrone.Core.Test.ParserTests
ExceptionVerification.IgnoreWarns();
}
[Test]
[Ignore]
public void unparsable_path_should_report_the_path()
{
Parser.Parser.ParsePath("C:\\SOMETHING 12345.avi").Should().BeNull();
MockedRestProvider.Verify(c => c.PostData(It.IsAny<string>(), It.IsAny<ParseErrorReport>()), Times.Exactly(2));
ExceptionVerification.IgnoreWarns();
}
[TestCase("[DmonHiro] The Severing Crime Edge - Cut 02 - Portrait Of Heresy [BD, 720p] [BE36E9E0]")]
public void unparsable_title_should_log_warn_and_return_null(string title)
{

@ -1,11 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FizzWare.NBuilder;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.DataAugmentation.Scene;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FizzWare.NBuilder;
using Moq;
using NUnit.Framework;

@ -1,70 +0,0 @@
using System;
using System.Linq;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.ProviderTests.XemCommunicationProviderTests
{
[TestFixture]
public class GetSceneTvdbMappingsFixture : CoreTest
{
private void WithFailureJson()
{
Mocker.GetMock<IHttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
.Returns(ReadAllText("Files","Xem","Failure.txt"));
}
private void WithIdsJson()
{
Mocker.GetMock<IHttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
.Returns(ReadAllText("Files","Xem","Ids.txt"));
}
private void WithMappingsJson()
{
Mocker.GetMock<IHttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
.Returns(ReadAllText("Files","Xem","Mappings.txt"));
}
[Test]
public void should_throw_when_failure_is_found()
{
WithFailureJson();
Assert.Throws<Exception>(() => Mocker.Resolve<XemCommunicationProvider>().GetSceneTvdbMappings(12345));
}
[Test]
public void should_get_list_of_mappings()
{
WithMappingsJson();
Mocker.Resolve<XemCommunicationProvider>().GetSceneTvdbMappings(12345).Should().NotBeEmpty();
}
[Test]
public void should_have_two_mappings()
{
WithMappingsJson();
Mocker.Resolve<XemCommunicationProvider>().GetSceneTvdbMappings(12345).Should().HaveCount(2);
}
[Test]
public void should_have_expected_results()
{
WithMappingsJson();
var results = Mocker.Resolve<XemCommunicationProvider>().GetSceneTvdbMappings(12345);
var first = results.First();
first.Scene.Absolute.Should().Be(1);
first.Scene.Season.Should().Be(1);
first.Scene.Episode.Should().Be(1);
first.Tvdb.Absolute.Should().Be(1);
first.Tvdb.Season.Should().Be(1);
first.Tvdb.Episode.Should().Be(1);
}
}
}

@ -1,55 +0,0 @@
using System;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.ProviderTests.XemCommunicationProviderTests
{
[TestFixture]
public class GetXemSeriesIdsFixture : CoreTest
{
private void WithFailureJson()
{
Mocker.GetMock<IHttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
.Returns(ReadAllText("Files", "Xem", "Failure.txt"));
}
private void WithIdsJson()
{
Mocker.GetMock<IHttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
.Returns(ReadAllText("Files", "Xem", "Ids.txt"));
}
private void WithMappingsJson()
{
Mocker.GetMock<IHttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
.Returns(ReadAllText("Files", "Xem", "Mappings.txt"));
}
[Test]
public void should_throw_when_failure_is_found()
{
WithFailureJson();
Assert.Throws<Exception>(() => Mocker.Resolve<XemCommunicationProvider>().GetXemSeriesIds());
}
[Test]
public void should_get_list_of_int()
{
WithIdsJson();
Mocker.Resolve<XemCommunicationProvider>().GetXemSeriesIds().Should().NotBeEmpty();
}
[Test]
public void should_have_two_ids()
{
WithIdsJson();
Mocker.Resolve<XemCommunicationProvider>().GetXemSeriesIds().Should().HaveCount(2);
}
}
}

@ -0,0 +1,60 @@
using System;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.DataAugmentation;
using NzbDrone.Core.DataAugmentation.Xem;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common.Categories;
namespace NzbDrone.Core.Test.Providers
{
[TestFixture]
[IntegrationTest]
public class XemProxyFixture : CoreTest<XemProxy>
{
[SetUp]
public void Setup()
{
UseRealHttp();
}
[Test]
public void get_series_ids()
{
Subject.GetXemSeriesIds().Should().NotBeEmpty();
}
[Test]
[Ignore("XEM's data is not clean")]
public void get_mapping_for_all_series()
{
var ids = Subject.GetXemSeriesIds();
var randomIds = ids.OrderBy(x => Guid.NewGuid()).Take(5);
foreach (var randomId in randomIds)
{
Subject.GetSceneTvdbMappings(randomId).Should().NotBeEmpty();
}
}
[Test]
public void should_return_empty_when_series_is_not_found()
{
Subject.GetSceneTvdbMappings(12345).Should().BeEmpty();
}
[Test]
public void should_get_mapping()
{
var result = Subject.GetSceneTvdbMappings(82807);
result.Should().NotBeEmpty();
result.Should().OnlyContain(c => c.Scene != null);
result.Should().OnlyContain(c => c.Tvdb != null);
}
}
}

@ -6,6 +6,7 @@ using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Model;
using NzbDrone.Common.Processes;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Update;
using NzbDrone.Core.Update.Commands;

@ -1,6 +1,6 @@
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Model.Xbmc;
using NzbDrone.Core.Notifications.Xbmc.Model;
namespace NzbDrone.Core.Test
{

@ -9,7 +9,6 @@ using NzbDrone.Common.Cache;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Configuration.Events;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;
@ -21,6 +20,8 @@ namespace NzbDrone.Core.Configuration
void SaveConfigDictionary(Dictionary<string, object> configValues);
int Port { get; }
int SslPort { get; }
bool EnableSsl { get; }
bool LaunchBrowser { get; }
bool AuthenticationEnabled { get; }
string Username { get; }
@ -28,6 +29,7 @@ namespace NzbDrone.Core.Configuration
string LogLevel { get; }
string Branch { get; }
bool Torrent { get; }
string SslCertHash { get; }
}
public class ConfigFileProvider : IConfigFileProvider
@ -91,6 +93,16 @@ namespace NzbDrone.Core.Configuration
get { return GetValueInt("Port", 8989); }
}
public int SslPort
{
get { return GetValueInt("SslPort", 9898); }
}
public bool EnableSsl
{
get { return GetValueBoolean("EnableSsl", false); }
}
public bool LaunchBrowser
{
get { return GetValueBoolean("LaunchBrowser", true); }
@ -126,6 +138,11 @@ namespace NzbDrone.Core.Configuration
get { return GetValue("LogLevel", "Info"); }
}
public string SslCertHash
{
get { return GetValue("SslCertHash", ""); }
}
public int GetValueInt(string key, int defaultValue)
{
return Convert.ToInt32(GetValue(key, defaultValue));

@ -1,6 +1,5 @@
using System.Linq;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;

@ -6,7 +6,6 @@ using NzbDrone.Core.Configuration.Events;
using NzbDrone.Core.Download;
using NzbDrone.Core.Download.Clients.Nzbget;
using NzbDrone.Core.Download.Clients.Sabnzbd;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;

@ -1,5 +1,4 @@
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;

@ -3,7 +3,6 @@ using System.Linq;
using NLog;
using NzbDrone.Common.Cache;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Parser;

@ -1,4 +1,4 @@
namespace NzbDrone.Core.Model.Xem
namespace NzbDrone.Core.DataAugmentation.Xem.Model
{
public class XemResult<T>
{

@ -1,4 +1,4 @@
namespace NzbDrone.Core.Model.Xem
namespace NzbDrone.Core.DataAugmentation.Xem.Model
{
public class XemSceneTvdbMapping
{

@ -1,4 +1,4 @@
namespace NzbDrone.Core.Model.Xem
namespace NzbDrone.Core.DataAugmentation.Xem.Model
{
public class XemValues
{

@ -0,0 +1,9 @@
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.DataAugmentation.Xem
{
public class UpdateXemMappingsCommand : Command
{
}
}

@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Core.DataAugmentation.Xem.Model;
using NzbDrone.Core.Rest;
using RestSharp;
namespace NzbDrone.Core.DataAugmentation.Xem
{
public interface IXemProxy
{
List<int> GetXemSeriesIds();
List<XemSceneTvdbMapping> GetSceneTvdbMappings(int id);
}
public class XemProxy : IXemProxy
{
private readonly Logger _logger;
private const string XEM_BASE_URL = "http://thexem.de/map/";
public XemProxy(Logger logger)
{
_logger = logger;
}
private static RestRequest BuildRequest(string resource)
{
var req = new RestRequest(resource, Method.GET);
req.AddParameter("origin", "tvdb");
return req;
}
public List<int> GetXemSeriesIds()
{
_logger.Trace("Fetching Series IDs from");
var restClient = new RestClient(XEM_BASE_URL);
var request = BuildRequest("havemap");
var response = restClient.ExecuteAndValidate<XemResult<List<int>>>(request);
CheckForFailureResult(response);
return response.Data.ToList();
}
public List<XemSceneTvdbMapping> GetSceneTvdbMappings(int id)
{
_logger.Trace("Fetching Mappings for: {0}", id);
var url = String.Format("{0}all?id={1}&origin=tvdb", XEM_BASE_URL, id);
var restClient = new RestClient(XEM_BASE_URL);
var request = BuildRequest("all");
request.AddParameter("id", id);
var response = restClient.ExecuteAndValidate<XemResult<List<XemSceneTvdbMapping>>>(request);
CheckForFailureResult(response);
return response.Data;
}
private static void CheckForFailureResult<T>(XemResult<T> response)
{
if (response.Result.Equals("failure", StringComparison.InvariantCultureIgnoreCase) &&
!response.Message.Contains("no show with the tvdb_id"))
{
throw new Exception("Error response received from Xem: " + response.Message);
}
}
}
}

@ -3,45 +3,52 @@ using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Common.Cache;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Tv.Events;
namespace NzbDrone.Core.Providers
namespace NzbDrone.Core.DataAugmentation.Xem
{
public interface IXemProvider
{
void UpdateMappings();
void UpdateMappings(int seriesId);
void UpdateMappings(Series series);
void PerformUpdate(Series series);
}
public class XemProvider : IXemProvider, IExecute<UpdateXemMappingsCommand>, IHandle<SeriesUpdatedEvent>, IHandleAsync<ApplicationStartedEvent>
public class XemService : IExecute<UpdateXemMappingsCommand>, IHandle<SeriesUpdatedEvent>, IHandleAsync<ApplicationStartedEvent>
{
private readonly IEpisodeService _episodeService;
private readonly IXemCommunicationProvider _xemCommunicationProvider;
private readonly IXemProxy _xemProxy;
private readonly ISeriesService _seriesService;
private readonly Logger _logger;
private readonly ICached<bool> _cache;
private static readonly Logger _logger = NzbDroneLogger.GetLogger();
public XemProvider(IEpisodeService episodeService,
IXemCommunicationProvider xemCommunicationProvider,
ISeriesService seriesService, ICacheManger cacheManger)
public XemService(IEpisodeService episodeService,
IXemProxy xemProxy,
ISeriesService seriesService, ICacheManger cacheManger, Logger logger)
{
if (seriesService == null) throw new ArgumentNullException("seriesService");
_episodeService = episodeService;
_xemCommunicationProvider = xemCommunicationProvider;
_xemProxy = xemProxy;
_seriesService = seriesService;
_logger = logger;
_logger = logger;
_cache = cacheManger.GetCache<bool>(GetType());
}
public void UpdateMappings()
public void Execute(UpdateXemMappingsCommand message)
{
UpdateMappings();
}
public void Handle(SeriesUpdatedEvent message)
{
UpdateMappings(message.Series);
}
public void HandleAsync(ApplicationStartedEvent message)
{
GetXemSeriesIds();
}
private void UpdateMappings()
{
_logger.Trace("Starting scene numbering update");
@ -66,20 +73,7 @@ namespace NzbDrone.Core.Providers
}
}
public void UpdateMappings(int seriesId)
{
var series = _seriesService.GetSeries(seriesId);
if (series == null)
{
_logger.Trace("Series could not be found: {0}", seriesId);
return;
}
UpdateMappings(series);
}
public void UpdateMappings(Series series)
private void UpdateMappings(Series series)
{
if (!_cache.Find(series.TvdbId.ToString()))
{
@ -90,17 +84,18 @@ namespace NzbDrone.Core.Providers
PerformUpdate(series);
}
public void PerformUpdate(Series series)
private void PerformUpdate(Series series)
{
_logger.Trace("Updating scene numbering mapping for: {0}", series);
try
{
var episodesToUpdate = new List<Episode>();
var mappings = _xemCommunicationProvider.GetSceneTvdbMappings(series.TvdbId);
var mappings = _xemProxy.GetSceneTvdbMappings(series.TvdbId);
if (mappings == null)
if (!mappings.Any())
{
_logger.Trace("Mappings for: {0} are null, skipping", series);
_logger.Trace("Mappings for: {0} are empty, skipping", series);
_cache.Remove(series.TvdbId.ToString());
return;
}
@ -142,7 +137,7 @@ namespace NzbDrone.Core.Providers
{
_cache.Clear();
var ids = _xemCommunicationProvider.GetXemSeriesIds();
var ids = _xemProxy.GetXemSeriesIds();
foreach (var id in ids)
{
@ -151,27 +146,5 @@ namespace NzbDrone.Core.Providers
return ids;
}
public void Execute(UpdateXemMappingsCommand message)
{
if (message.SeriesId.HasValue)
{
UpdateMappings(message.SeriesId.Value);
}
else
{
UpdateMappings();
}
}
public void Handle(SeriesUpdatedEvent message)
{
UpdateMappings(message.Series);
}
public void HandleAsync(ApplicationStartedEvent message)
{
GetXemSeriesIds();
}
}
}

@ -6,7 +6,6 @@ using Marr.Data;
using Marr.Data.QGen;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Common;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;

@ -5,7 +5,6 @@ using Marr.Data.Reflection;
using NzbDrone.Common.Composition;
using NzbDrone.Core.Datastore.Migration.Framework;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;

@ -70,6 +70,7 @@ namespace NzbDrone.Core.DecisionEngine
if (remoteEpisode.Series != null)
{
remoteEpisode.DownloadAllowed = true;
decision = GetDecisionForReport(remoteEpisode, searchCriteria);
}
else

@ -1,14 +1,10 @@
using System;
using Newtonsoft.Json;
namespace NzbDrone.Core.Download.Clients.Nzbget
{
public class JsonRequest
{
[JsonProperty(PropertyName = "method")]
public String Method { get; set; }
[JsonProperty(PropertyName = "params")]
public object[] Params { get; set; }
}
}

@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using NLog;
using NzbDrone.Common;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Parser.Model;
@ -36,11 +36,11 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
};
_logger.Info("Adding report [{0}] to the queue.", title);
var response = PostCommand(JsonConvert.SerializeObject(command));
var response = PostCommand(command.ToJson());
CheckForError(response);
var success = JsonConvert.DeserializeObject<EnqueueResponse>(response).Result;
var success = Json.Deserialize<EnqueueResponse>(response).Result;
_logger.Debug("Queue Response: [{0}]", success);
}
@ -61,11 +61,11 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
Params = null
};
var response = PostCommand(JsonConvert.SerializeObject(command));
var response = PostCommand(command.ToJson());
CheckForError(response);
var itmes = JsonConvert.DeserializeObject<NzbGetQueue>(response).QueueItems;
var itmes = Json.Deserialize<NzbGetQueue>(response).QueueItems;
foreach (var nzbGetQueueItem in itmes)
{
@ -101,11 +101,11 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
};
var address = String.Format(@"{0}:{1}", host, port);
var response = _httpProvider.PostCommand(address, username, password, JsonConvert.SerializeObject(command));
var response = _httpProvider.PostCommand(address, username, password, command.ToJson());
CheckForError(response);
return JsonConvert.DeserializeObject<VersionModel>(response);
return Json.Deserialize<VersionModel>(response);
}
public virtual string Test(string host, int port, string username, string password)
@ -134,7 +134,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
private void CheckForError(string response)
{
var result = JsonConvert.DeserializeObject<JsonError>(response);
var result = Json.Deserialize<JsonError>(response);
if (result.Error != null)
throw new ApplicationException(result.Error.ToString());

@ -1,11 +1,11 @@
using System;
using System.Collections.Generic;
using System.Web;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
using NzbDrone.Common;
using NzbDrone.Common.Cache;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Parser.Model;
using RestSharp;
@ -107,7 +107,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
CheckForError(response);
var sabQueue = JsonConvert.DeserializeObject<SabQueue>(JObject.Parse(response).SelectToken("queue").ToString()).Items;
var sabQueue = Json.Deserialize<SabQueue>(JObject.Parse(response).SelectToken("queue").ToString()).Items;
var queueItems = new List<QueueItem>();
@ -134,7 +134,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
CheckForError(response);
var items = JsonConvert.DeserializeObject<SabHistory>(JObject.Parse(response).SelectToken("history").ToString()).Items;
var items = Json.Deserialize<SabHistory>(JObject.Parse(response).SelectToken("history").ToString()).Items;
return items ?? new List<SabHistoryItem>();
}
@ -166,7 +166,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
if (String.IsNullOrWhiteSpace(response))
return new SabCategoryModel { categories = new List<string>() };
var categories = JsonConvert.DeserializeObject<SabCategoryModel>(response);
var categories = Json.Deserialize<SabCategoryModel>(response);
return categories;
}
@ -199,7 +199,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
if (String.IsNullOrWhiteSpace(response))
return null;
var version = JsonConvert.DeserializeObject<SabVersionModel>(response);
var version = Json.Deserialize<SabVersionModel>(response);
return version;
}
@ -232,7 +232,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
private void CheckForError(string response)
{
var result = JsonConvert.DeserializeObject<SabJsonError>(response);
var result = Json.Deserialize<SabJsonError>(response);
if (result.Status != null && result.Status.Equals("false", StringComparison.InvariantCultureIgnoreCase))
throw new ApplicationException(result.Error);

@ -1,6 +1,6 @@
using NLog;
using NzbDrone.Common.EnsureThat;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Parser.Model;
@ -28,6 +28,9 @@ namespace NzbDrone.Core.Download
public void DownloadReport(RemoteEpisode remoteEpisode)
{
Ensure.That(() => remoteEpisode.Series).IsNotNull();
Ensure.That(() => remoteEpisode.Episodes).HasItems();
var downloadTitle = remoteEpisode.Release.Title;
var downloadClient = _downloadClientProvider.GetDownloadClient();

@ -0,0 +1,15 @@
using System.Net;
namespace NzbDrone.Core.Exceptions
{
public class BadRequestException : DownstreamException
{
public BadRequestException(HttpStatusCode statusCode, string message) : base(statusCode, message)
{
}
public BadRequestException(HttpStatusCode statusCode, string message, params object[] args) : base(statusCode, message, args)
{
}
}
}

@ -0,0 +1,21 @@
using System.Net;
using NzbDrone.Common.Exceptions;
namespace NzbDrone.Core.Exceptions
{
public class DownstreamException : NzbDroneException
{
public HttpStatusCode StatusCode { get; private set; }
public DownstreamException(HttpStatusCode statusCode, string message, params object[] args) : base(message, args)
{
StatusCode = statusCode;
}
public DownstreamException(HttpStatusCode statusCode, string message)
: base(message)
{
StatusCode = statusCode;
}
}
}

@ -1,7 +1,7 @@
using System.Net;
using NzbDrone.Common.Exceptions;
namespace NzbDrone.Core
namespace NzbDrone.Core.Exceptions
{
public class NzbDroneClientException : NzbDroneException
{

@ -0,0 +1,31 @@
using System;
using System.Net;
namespace NzbDrone.Core.Exceptions
{
public static class StatusCodeToExceptions
{
public static void VerifyStatusCode(this HttpStatusCode statusCode, string message = null)
{
if (String.IsNullOrEmpty(message))
{
message = statusCode.ToString();
}
switch (statusCode)
{
case HttpStatusCode.BadRequest:
throw new BadRequestException(statusCode, message);
case HttpStatusCode.Unauthorized:
throw new UnauthorizedAccessException(message);
case HttpStatusCode.PaymentRequired:
throw new DownstreamException(statusCode, message);
case HttpStatusCode.InternalServerError:
throw new DownstreamException(statusCode, message);
}
}
}
}

@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
namespace NzbDrone.Core.Helpers
{
public static class SortHelper
{
public static string IgnoreArticles(this string input)
{
if (String.IsNullOrEmpty(input))
return String.Empty;
var articles = new List<string> { "The ", "An ", "A " };
foreach (string article in articles)
{
if (input.ToLower().StartsWith(article, StringComparison.InvariantCultureIgnoreCase))
return input.Substring(article.Length).Trim();
}
return input;
}
}
}

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using Marr.Data.QGen;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Tv;
@ -17,9 +16,12 @@ namespace NzbDrone.Core.History
public class HistoryRepository : BasicRepository<History>, IHistoryRepository
{
private readonly IDatabase _database;
public HistoryRepository(IDatabase database, IEventAggregator eventAggregator)
: base(database, eventAggregator)
{
_database = database;
}
public void Trim()

@ -5,7 +5,6 @@ using NLog;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Download;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Tv;

@ -0,0 +1,32 @@
using NLog;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Housekeeping.Housekeepers
{
public class CleanupOrphanedEpisodes : IHousekeepingTask
{
private readonly IDatabase _database;
private readonly Logger _logger;
public CleanupOrphanedEpisodes(IDatabase database, Logger logger)
{
_database = database;
_logger = logger;
}
public void Clean()
{
_logger.Trace("Running orphaned episodes cleanup");
var mapper = _database.GetDataMapper();
mapper.ExecuteNonQuery(@"DELETE FROM Episodes
WHERE Id IN (
SELECT Episodes.Id FROM Episodes
LEFT OUTER JOIN Series
ON Episodes.SeriesId = Series.Id
WHERE Series.Id IS NULL)");
}
}
}

@ -0,0 +1,49 @@
using NLog;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.History;
namespace NzbDrone.Core.Housekeeping.Housekeepers
{
public class CleanupOrphanedHistoryItems : IHousekeepingTask
{
private readonly IDatabase _database;
private readonly Logger _logger;
public CleanupOrphanedHistoryItems(IDatabase database, Logger logger)
{
_database = database;
_logger = logger;
}
public void Clean()
{
_logger.Trace("Running orphaned history cleanup");
CleanupOrphanedBySeries();
CleanupOrphanedByEpisode();
}
private void CleanupOrphanedBySeries()
{
var mapper = _database.GetDataMapper();
mapper.ExecuteNonQuery(@"DELETE FROM History
WHERE Id IN (
SELECT History.Id FROM History
LEFT OUTER JOIN Series
ON History.SeriesId = Series.Id
WHERE Series.Id IS NULL)");
}
private void CleanupOrphanedByEpisode()
{
var mapper = _database.GetDataMapper();
mapper.ExecuteNonQuery(@"DELETE FROM History
WHERE Id IN (
SELECT History.Id FROM History
LEFT OUTER JOIN Episodes
ON History.EpisodeId = Episodes.Id
WHERE Episodes.Id IS NULL)");
}
}
}

@ -0,0 +1,8 @@
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.Housekeeping
{
public class HousekeepingCommand : Command
{
}
}

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using NLog;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.Housekeeping
{
public class HousekeepingService : IExecute<HousekeepingCommand>
{
private readonly IEnumerable<IHousekeepingTask> _housekeepers;
private readonly Logger _logger;
public HousekeepingService(IEnumerable<IHousekeepingTask> housekeepers, Logger logger)
{
_housekeepers = housekeepers;
_logger = logger;
}
public void Execute(HousekeepingCommand message)
{
_logger.Info("Running housecleaning tasks");
foreach (var housekeeper in _housekeepers)
{
try
{
housekeeper.Clean();
}
catch (Exception ex)
{
_logger.ErrorException("Error running housekeeping task: " + housekeeper.GetType().FullName, ex);
}
}
}
}
}

@ -0,0 +1,7 @@
namespace NzbDrone.Core.Housekeeping
{
public interface IHousekeepingTask
{
void Clean();
}
}

@ -1,7 +1,6 @@
using NLog;
using NzbDrone.Core.Download;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.IndexerSearch

@ -1,7 +1,6 @@
using NLog;
using NzbDrone.Core.Download;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.IndexerSearch

@ -1,8 +1,6 @@
using System.Linq;
using NLog;
using NLog;
using NzbDrone.Core.Download;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Tv;

@ -1,6 +1,5 @@
using System;
using System.Xml.Linq;
using NLog;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.IO;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers

@ -1,7 +1,6 @@
using System;
using System.Linq;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;

@ -6,7 +6,6 @@ using NzbDrone.Common.Serializer;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Indexers.Newznab;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;
using Omu.ValueInjecter;

@ -1,4 +1,4 @@
using Newtonsoft.Json;
using NzbDrone.Common.Serializer;
namespace NzbDrone.Core.Indexers
{
@ -25,7 +25,7 @@ namespace NzbDrone.Core.Indexers
return new TSetting();
}
return JsonConvert.DeserializeObject<TSetting>(indexerDef.Settings);
return Json.Deserialize<TSetting>(indexerDef.Settings);
}
}
}

@ -17,12 +17,12 @@ namespace NzbDrone.Core.Indexers.Newznab
var attributes = item.Elements("attr").ToList();
var sizeElement = attributes.SingleOrDefault(e => e.Attribute("name").Value.Equals("size", StringComparison.CurrentCultureIgnoreCase));
if (sizeElement == null)
if (sizeElement != null)
{
return Convert.ToInt64(sizeElement.Attribute("value").Value);
}
return Convert.ToInt64(sizeElement.Attribute("value").Value);
return ParseSize(item.Description());
}
protected override ReleaseInfo PostProcessor(XElement item, ReleaseInfo currentResult)

@ -108,8 +108,6 @@ namespace NzbDrone.Core.Indexers
return currentResult;
}
public static string ParseReleaseGroup(string title)
{
title = title.Trim();
@ -132,8 +130,6 @@ namespace NzbDrone.Core.Indexers
private static readonly Regex ReportSizeRegex = new Regex(@"(?<value>\d+\.\d{1,2}|\d+\,\d+\.\d{1,2}|\d+)\W?(?<unit>GB|MB|GiB|MiB)",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
public static long ParseSize(string sizeString)
{
var match = ReportSizeRegex.Matches(sizeString);

@ -3,7 +3,6 @@ using NLog;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.Indexers

@ -4,7 +4,6 @@ using NLog;
using NLog.Layouts;
using NLog.Targets;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;
namespace NzbDrone.Core.Instrumentation

@ -3,7 +3,6 @@ using NLog;
using NzbDrone.Common;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Instrumentation.Commands;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.Instrumentation

@ -1,6 +1,5 @@
using System;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;

@ -1,6 +1,5 @@
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Instrumentation.Commands;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.Instrumentation

@ -1,33 +0,0 @@
using System;
namespace NzbDrone.Core.Jobs
{
public class JobQueueItem : IEquatable<JobQueueItem>
{
public Type JobType { get; set; }
public dynamic Options { get; set; }
public JobSourceType Source { get; set; }
public bool Equals(JobQueueItem other)
{
return (JobType == other.JobType && Options == other.Options);
}
public override string ToString()
{
if (Options != null)
{
return string.Format("[{0}({1})]", JobType.Name, Options);
}
return string.Format("[{0}]", JobType.Name);
}
public enum JobSourceType
{
User,
Scheduler
}
}
}

@ -4,14 +4,16 @@ using System.Linq;
using NLog;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Configuration.Events;
using NzbDrone.Core.DataAugmentation;
using NzbDrone.Core.DataAugmentation.Scene;
using NzbDrone.Core.DataAugmentation.Xem;
using NzbDrone.Core.Housekeeping;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Instrumentation.Commands;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.MediaFiles.Commands;
using NzbDrone.Core.Messaging.Commands.Tracking;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Tv.Commands;
using NzbDrone.Core.Update.Commands;
@ -51,7 +53,8 @@ namespace NzbDrone.Core.Jobs
new ScheduledTask{ Interval = 60, TypeName = typeof(ApplicationUpdateCommand).FullName},
new ScheduledTask{ Interval = 1*60, TypeName = typeof(TrimLogCommand).FullName},
new ScheduledTask{ Interval = 3*60, TypeName = typeof(UpdateSceneMappingCommand).FullName},
new ScheduledTask{ Interval = 1, TypeName = typeof(TrackedCommandCleanupCommand).FullName}
new ScheduledTask{ Interval = 1, TypeName = typeof(TrackedCommandCleanupCommand).FullName},
new ScheduledTask{ Interval = 24*60, TypeName = typeof(HousekeepingCommand).FullName}
};
var currentTasks = _scheduledTaskRepository.All();

@ -5,7 +5,6 @@ using System.Net;
using NLog;
using NzbDrone.Common;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Tv.Events;

@ -5,7 +5,6 @@ using NzbDrone.Common;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.MediaFiles.Commands;
using NzbDrone.Core.MediaFiles.EpisodeImport;
using NzbDrone.Core.Messaging;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Tv;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save