diff --git a/NzbDrone.Services.Api/ApiServicesRegistrationExtention.cs b/NzbDrone.Services.Api/ApiServicesRegistrationExtention.cs new file mode 100644 index 000000000..8da4ac084 --- /dev/null +++ b/NzbDrone.Services.Api/ApiServicesRegistrationExtention.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Web; +using Autofac; +using MongoDB.Driver; +using NzbDrone.Services.Api.Datastore; + +namespace NzbDrone.Services.Api +{ + public static class ApiServicesRegistrationExtention + { + public static ContainerBuilder RegisterApiServices(this ContainerBuilder containerBuilder) + { + containerBuilder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).SingleInstance(); + + containerBuilder.Register(c => c.Resolve().GetMainDb()) + .As().SingleInstance(); + + return containerBuilder; + } + } +} \ No newline at end of file diff --git a/NzbDrone.Services.Api/Bootstrapper.cs b/NzbDrone.Services.Api/Bootstrapper.cs new file mode 100644 index 000000000..8d9c2895e --- /dev/null +++ b/NzbDrone.Services.Api/Bootstrapper.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Web; +using Autofac; +using NLog; +using Nancy.Bootstrapper; +using Nancy.Bootstrappers.Autofac; +using NzbDrone.Services.Api.NancyExtensions; + +namespace NzbDrone.Services.Api +{ + public class Bootstrapper : AutofacNancyBootstrapper + { + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + + protected override ILifetimeScope GetApplicationContainer() + { + ApplicationPipelines.OnError.AddItemToEndOfPipeline((context, exception) => + { + Logger.FatalException("Application Exception", exception); + return null; + }); + + var builder = new ContainerBuilder(); + builder.RegisterApiServices(); + var container = builder.Build(); + + return container; + } + + protected override NancyInternalConfiguration InternalConfiguration + { + get + { + return NancyInternalConfiguration.WithOverrides(c => c.Serializers.Add(typeof(ServiceStackSerializer))); + } + } + } +} \ No newline at end of file diff --git a/NzbDrone.Services.Api/DailySeries/DailySeriesModel.cs b/NzbDrone.Services.Api/DailySeries/DailySeriesModel.cs new file mode 100644 index 000000000..41dab258d --- /dev/null +++ b/NzbDrone.Services.Api/DailySeries/DailySeriesModel.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using MongoDB.Bson.Serialization.Attributes; + + +namespace NzbDrone.Services.Api.DailySeries +{ + public class DailySeriesModel + { + public const string CollectionName = "DailySeries"; + + [BsonId] + public Int32 Id { get; set; } + + [BsonElement("t")] + public String Title { get; set; } + + [BsonElement("p")] + public Boolean Public { get; set; } + } +} \ No newline at end of file diff --git a/NzbDrone.Services.Api/DailySeries/DailySeriesModule.cs b/NzbDrone.Services.Api/DailySeries/DailySeriesModule.cs new file mode 100644 index 000000000..4e7c957a6 --- /dev/null +++ b/NzbDrone.Services.Api/DailySeries/DailySeriesModule.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using Nancy; +using NzbDrone.Services.Api.NancyExtensions; + +namespace NzbDrone.Services.Api.DailySeries +{ + public class DailySeriesModule : NancyModule + { + private readonly DailySeriesProvider _dailySeriesProvider; + + public DailySeriesModule(DailySeriesProvider dailySeriesProvider) + : base("/dailyseries") + { + _dailySeriesProvider = dailySeriesProvider; + + Get["/"] = x => OnGet(); + Get["/all"] = x => OnGet(); + Get["/{Id}"] = x => OnGet((int)x.Id); + Get["/isdaily/{Id}"] = x => OnGet((int)x.Id); + } + + private Response OnGet() + { + return _dailySeriesProvider.Public().AsResponse(); + } + + private Response OnGet(int seriesId) + { + return _dailySeriesProvider.IsDaily(seriesId).AsResponse(); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Services.Api/DailySeries/DailySeriesProvider.cs b/NzbDrone.Services.Api/DailySeries/DailySeriesProvider.cs new file mode 100644 index 000000000..36f00c117 --- /dev/null +++ b/NzbDrone.Services.Api/DailySeries/DailySeriesProvider.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using MongoDB.Driver; +using MongoDB.Driver.Builders; + +namespace NzbDrone.Services.Api.DailySeries +{ + public class DailySeriesProvider + { + private readonly MongoDatabase _mongoDb; + + public DailySeriesProvider(MongoDatabase mongoDb) + { + _mongoDb = mongoDb; + } + + public DailySeriesProvider() + { + } + + public List All() + { + return _mongoDb.GetCollection(DailySeriesModel.CollectionName).FindAll().ToList(); + } + + public List Public() + { + var query = Query.EQ(d => d.Public, true); + return _mongoDb.GetCollection(DailySeriesModel.CollectionName).Find(query).ToList(); + } + + public Boolean IsDaily(int seriesId) + { + var query = Query.EQ(d => d.Id, seriesId); + return _mongoDb.GetCollection(DailySeriesModel.CollectionName).Count(query) > 0; + } + } +} \ No newline at end of file diff --git a/NzbDrone.Services.Api/Datastore/Connection.cs b/NzbDrone.Services.Api/Datastore/Connection.cs new file mode 100644 index 000000000..312214cec --- /dev/null +++ b/NzbDrone.Services.Api/Datastore/Connection.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using MongoDB.Driver; + +namespace NzbDrone.Services.Api.Datastore +{ + public class Connection + { + public MongoDatabase GetMainDb() + { + var db = GetMongoDb("mongodb://nzbdrone:h53huDrAzufRe8a3@ds035147.mongolab.com:35147/?safe=true;wtimeoutMS=2000", "services-dev"); + return db; + } + + public MongoDatabase GetMongoDb(string connectionString, string dbName) + { + var mongoServer = MongoServer.Create(connectionString); + var database = mongoServer.GetDatabase(dbName.ToLowerInvariant()); + return database; + } + } +} \ No newline at end of file diff --git a/NzbDrone.Services.Api/NancyExtensions/JsonExtensions.cs b/NzbDrone.Services.Api/NancyExtensions/JsonExtensions.cs new file mode 100644 index 000000000..4855c2a1c --- /dev/null +++ b/NzbDrone.Services.Api/NancyExtensions/JsonExtensions.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Web; +using Nancy; +using Nancy.Responses; +using ServiceStack.Text; + +namespace NzbDrone.Services.Api.NancyExtensions +{ + public static class JsonExtensions + { + public static T FromJson(this Stream body) + { + var reader = new StreamReader(body, true); + return JsonSerializer.DeserializeFromReader(reader); + } + + public static JsonResponse AsResponse(this TModel model, HttpStatusCode statusCode = HttpStatusCode.OK) + { + var jsonResponse = new JsonResponse(model, new ServiceStackSerializer()) { StatusCode = statusCode }; + return jsonResponse; + } + } +} \ No newline at end of file diff --git a/NzbDrone.Services.Api/NancyExtensions/ServiceStackSerializer.cs b/NzbDrone.Services.Api/NancyExtensions/ServiceStackSerializer.cs new file mode 100644 index 000000000..175db50b3 --- /dev/null +++ b/NzbDrone.Services.Api/NancyExtensions/ServiceStackSerializer.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Web; +using Nancy; +using ServiceStack.Text; + +namespace NzbDrone.Services.Api.NancyExtensions +{ + public class ServiceStackSerializer : ISerializer + { + public readonly static ServiceStackSerializer Instance = new ServiceStackSerializer(); + + public bool CanSerialize(string contentType) + { + return true; + } + + public void Serialize(string contentType, TModel model, Stream outputStream) + { + JsonSerializer.SerializeToStream(model, outputStream); + } + + public IEnumerable Extensions { get; private set; } + } +} \ No newline at end of file diff --git a/NzbDrone.Services.Api/NzbDrone.Services.Api.csproj b/NzbDrone.Services.Api/NzbDrone.Services.Api.csproj new file mode 100644 index 000000000..de18bf2c4 --- /dev/null +++ b/NzbDrone.Services.Api/NzbDrone.Services.Api.csproj @@ -0,0 +1,162 @@ + + + + + Debug + AnyCPU + + + 2.0 + {A675DE45-D30A-4CAC-991A-34DA56947DD7} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + NzbDrone.Services.Api + NzbDrone.Services.Api + v4.0 + true + + + + + ..\ + true + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + ..\packages\Autofac.2.6.3.862\lib\NET40\Autofac.dll + + + ..\packages\Autofac.2.6.3.862\lib\NET40\Autofac.Configuration.dll + + + + ..\packages\mongocsharpdriver.1.7\lib\net35\MongoDB.Bson.dll + + + ..\packages\mongocsharpdriver.1.7\lib\net35\MongoDB.Driver.dll + + + ..\packages\Nancy.0.15.3\lib\net40\Nancy.dll + + + ..\packages\Nancy.Bootstrappers.Autofac.0.15.3\lib\net40\Nancy.Bootstrappers.Autofac.dll + + + ..\packages\Nancy.Hosting.Aspnet.0.15.3\lib\net40\Nancy.Hosting.Aspnet.dll + + + ..\packages\NLog.2.0.0.2000\lib\net40\NLog.dll + + + ..\packages\ServiceStack.Text.3.9.33\lib\net35\ServiceStack.Text.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Web.config + + + Web.config + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + true + bin\ + DEBUG;TRACE + full + x86 + prompt + MinimumRecommendedRules.ruleset + + + bin\ + TRACE + true + pdbonly + x86 + prompt + MinimumRecommendedRules.ruleset + + + + + + + + + True + True + 0 + / + http://localhost:14615/ + False + False + + + False + + + + + + + \ No newline at end of file diff --git a/NzbDrone.Services.Api/Properties/AssemblyInfo.cs b/NzbDrone.Services.Api/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..496d784cf --- /dev/null +++ b/NzbDrone.Services.Api/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("NzbDrone.Services.Api")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("NzbDrone.Services.Api")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("616405a2-4ccc-4272-9464-905c69b5a8d3")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/NzbDrone.Services.Api/Web.Debug.config b/NzbDrone.Services.Api/Web.Debug.config new file mode 100644 index 000000000..2e302f9f9 --- /dev/null +++ b/NzbDrone.Services.Api/Web.Debug.config @@ -0,0 +1,30 @@ + + + + + + + + + + \ No newline at end of file diff --git a/NzbDrone.Services.Api/Web.Release.config b/NzbDrone.Services.Api/Web.Release.config new file mode 100644 index 000000000..c35844462 --- /dev/null +++ b/NzbDrone.Services.Api/Web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/NzbDrone.Services.Api/Web.config b/NzbDrone.Services.Api/Web.config new file mode 100644 index 000000000..9166b6a1b --- /dev/null +++ b/NzbDrone.Services.Api/Web.config @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NzbDrone.Services.Api/packages.config b/NzbDrone.Services.Api/packages.config new file mode 100644 index 000000000..1c011ee9b --- /dev/null +++ b/NzbDrone.Services.Api/packages.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/NzbDrone.ncrunchsolution b/NzbDrone.ncrunchsolution index e88d63cdb..13a4b6131 100644 --- a/NzbDrone.ncrunchsolution +++ b/NzbDrone.ncrunchsolution @@ -2,7 +2,6 @@ 1 False true - true UseDynamicAnalysis Disabled Disabled diff --git a/NzbDrone.sln b/NzbDrone.sln index 91afdf1f1..ab85871ce 100644 --- a/NzbDrone.sln +++ b/NzbDrone.sln @@ -53,6 +53,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Api", "NzbDrone.Ap EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Console", "NzbDrone\NzbDrone.Console.csproj", "{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Services.Api", "NzbDrone.Services.Api\NzbDrone.Services.Api.csproj", "{A675DE45-D30A-4CAC-991A-34DA56947DD7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -529,6 +531,31 @@ Global {3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Services|x64.ActiveCfg = Release|x86 {3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Services|x86.ActiveCfg = Release|x86 {3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Services|x86.Build.0 = Release|x86 + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Debug|x64.ActiveCfg = Debug|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Debug|x86.ActiveCfg = Debug|x86 + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Debug|x86.Build.0 = Debug|x86 + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Pilot|Any CPU.ActiveCfg = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Pilot|Any CPU.Build.0 = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Pilot|Mixed Platforms.ActiveCfg = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Pilot|Mixed Platforms.Build.0 = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Pilot|x64.ActiveCfg = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Pilot|x86.ActiveCfg = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Release|Any CPU.Build.0 = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Release|x64.ActiveCfg = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Release|x86.ActiveCfg = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Services|Any CPU.ActiveCfg = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Services|Any CPU.Build.0 = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Services|Mixed Platforms.ActiveCfg = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Services|Mixed Platforms.Build.0 = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Services|x64.ActiveCfg = Release|Any CPU + {A675DE45-D30A-4CAC-991A-34DA56947DD7}.Services|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -546,6 +573,7 @@ Global {700D0B95-95CD-43F3-B6C9-FAA0FC1358D4} = {F9E67978-5CD6-4A5F-827B-4249711C0B02} {63B155D7-AE78-4FEB-88BB-2F025ADD1F15} = {5853FEE1-D6C1-49AB-B1E3-12216491DA69} {12261AE5-BCC4-4DC7-A218-0764B9C30230} = {5853FEE1-D6C1-49AB-B1E3-12216491DA69} + {A675DE45-D30A-4CAC-991A-34DA56947DD7} = {5853FEE1-D6C1-49AB-B1E3-12216491DA69} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EnterpriseLibraryConfigurationToolBinariesPath = packages\Unity.2.1.505.0\lib\NET35;packages\Unity.2.1.505.2\lib\NET35