diff options
79 files changed, 1271 insertions, 1388 deletions
diff --git a/MediaBrowser.Api/EnvironmentService.cs b/MediaBrowser.Api/EnvironmentService.cs index 618eeae5d..d96b69cc4 100644 --- a/MediaBrowser.Api/EnvironmentService.cs +++ b/MediaBrowser.Api/EnvironmentService.cs @@ -2,6 +2,7 @@ using MediaBrowser.Controller.IO; using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; +using MediaBrowser.Networking.HttpServer; using ServiceStack.ServiceHost; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index d3d76f4f2..1513d0d05 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -1,17 +1,18 @@ -using System.Threading; -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; +using MediaBrowser.Networking.HttpServer; using ServiceStack.ServiceHost; +using ServiceStack.Text.Controller; using System; using System.IO; using System.Linq; +using System.Threading; using System.Threading.Tasks; -using ServiceStack.Text.Controller; namespace MediaBrowser.Api.Images { diff --git a/MediaBrowser.Api/Javascript/JavascriptApiClientService.cs b/MediaBrowser.Api/Javascript/JavascriptApiClientService.cs index 8c7499a7c..3081d6cd0 100644 --- a/MediaBrowser.Api/Javascript/JavascriptApiClientService.cs +++ b/MediaBrowser.Api/Javascript/JavascriptApiClientService.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; +using MediaBrowser.Networking.HttpServer; using ServiceStack.ServiceHost; using System; using System.IO; diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 0729987d9..2abb4e914 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -1,10 +1,9 @@ using MediaBrowser.Common.Kernel; -using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; +using MediaBrowser.Networking.HttpServer; using ServiceStack.ServiceHost; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs index 35c658f91..47ea2aa2a 100644 --- a/MediaBrowser.Api/Library/LibraryStructureService.cs +++ b/MediaBrowser.Api/Library/LibraryStructureService.cs @@ -1,6 +1,6 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller; +using MediaBrowser.Controller; using MediaBrowser.Model.Entities; +using MediaBrowser.Networking.HttpServer; using ServiceStack.ServiceHost; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Api/LocalizationService.cs b/MediaBrowser.Api/LocalizationService.cs index 098c9f72a..8c4005d47 100644 --- a/MediaBrowser.Api/LocalizationService.cs +++ b/MediaBrowser.Api/LocalizationService.cs @@ -1,7 +1,7 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Localization; +using MediaBrowser.Controller.Localization; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Globalization; +using MediaBrowser.Networking.HttpServer; using MoreLinq; using ServiceStack.ServiceHost; using System.Collections.Generic; diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 896e1d438..1ebfb357e 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -123,6 +123,10 @@ <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project> <Name>MediaBrowser.Model</Name> </ProjectReference> + <ProjectReference Include="..\MediaBrowser.Networking\MediaBrowser.Networking.csproj"> + <Project>{7c11010e-179a-49b7-bfb2-f1656f5e71ad}</Project> + <Name>MediaBrowser.Networking</Name> + </ProjectReference> </ItemGroup> <ItemGroup> <None Include="packages.config" /> diff --git a/MediaBrowser.Api/PackageService.cs b/MediaBrowser.Api/PackageService.cs index 028242e72..64338e5f0 100644 --- a/MediaBrowser.Api/PackageService.cs +++ b/MediaBrowser.Api/PackageService.cs @@ -1,8 +1,8 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Kernel; -using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Model.Updates; +using MediaBrowser.Networking.HttpServer; using ServiceStack.ServiceHost; using System; using System.Collections.Generic; @@ -142,7 +142,7 @@ namespace MediaBrowser.Api { var kernel = (Kernel)Kernel; - var packages = kernel.InstallationManager.GetAvailablePackages(CancellationToken.None, applicationVersion: kernel.ApplicationVersion).Result; + var packages = kernel.InstallationManager.GetAvailablePackages(CancellationToken.None, applicationVersion: ApplicationHost.ApplicationVersion).Result; var result = packages.FirstOrDefault(p => p.name.Equals(request.Name, StringComparison.OrdinalIgnoreCase)); @@ -158,7 +158,7 @@ namespace MediaBrowser.Api { var kernel = (Kernel)Kernel; - var packages = kernel.InstallationManager.GetAvailablePackages(CancellationToken.None, request.PackageType, kernel.ApplicationVersion).Result; + var packages = kernel.InstallationManager.GetAvailablePackages(CancellationToken.None, request.PackageType, ApplicationHost.ApplicationVersion).Result; return ToOptimizedResult(packages.ToList()); } diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs index 1f906f814..b2e82d4d6 100644 --- a/MediaBrowser.Api/PluginService.cs +++ b/MediaBrowser.Api/PluginService.cs @@ -1,9 +1,9 @@ using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Plugins; using MediaBrowser.Model.Serialization; +using MediaBrowser.Networking.HttpServer; using ServiceStack.ServiceHost; using ServiceStack.Text.Controller; using System; @@ -148,7 +148,7 @@ namespace MediaBrowser.Api public object Get(GetPlugins request) { var result = Kernel.Plugins.OrderBy(p => p.Name).Select(p => p.GetPluginInfo()).ToList(); - + return ToOptimizedResult(result); } diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs index e79ab90da..d1c7f451f 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs @@ -1,14 +1,14 @@ using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Tasks; +using MediaBrowser.Networking.HttpServer; using ServiceStack.ServiceHost; +using ServiceStack.Text.Controller; using System; using System.Collections.Generic; using System.IO; using System.Linq; -using ServiceStack.Text.Controller; namespace MediaBrowser.Api.ScheduledTasks { diff --git a/MediaBrowser.Api/SystemService.cs b/MediaBrowser.Api/SystemService.cs index 7921d024a..cf0be35a2 100644 --- a/MediaBrowser.Api/SystemService.cs +++ b/MediaBrowser.Api/SystemService.cs @@ -1,9 +1,9 @@ using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.System; +using MediaBrowser.Networking.HttpServer; using ServiceStack.ServiceHost; using System; using System.IO; diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs index 0c99b921a..991c87b5f 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs @@ -1,10 +1,9 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller; +using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; +using MediaBrowser.Networking.HttpServer; using ServiceStack.ServiceHost; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 0586b2b5e..2c4fef352 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -1,10 +1,10 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller; +using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Networking.HttpServer; using ServiceStack.ServiceHost; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index 51197affb..bad55d51c 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller; +using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Library; @@ -7,13 +6,14 @@ using MediaBrowser.Model.Connectivity; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Serialization; +using MediaBrowser.Networking.HttpServer; using ServiceStack.ServiceHost; +using ServiceStack.Text.Controller; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; -using ServiceStack.Text.Controller; namespace MediaBrowser.Api.UserLibrary { diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs index d4490d856..47dcbbf4d 100644 --- a/MediaBrowser.Api/UserService.cs +++ b/MediaBrowser.Api/UserService.cs @@ -1,9 +1,9 @@ using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Serialization; +using MediaBrowser.Networking.HttpServer; using ServiceStack.ServiceHost; using ServiceStack.Text.Controller; using System; diff --git a/MediaBrowser.Api/WeatherService.cs b/MediaBrowser.Api/WeatherService.cs index c79c2da28..9c66f2bcf 100644 --- a/MediaBrowser.Api/WeatherService.cs +++ b/MediaBrowser.Api/WeatherService.cs @@ -1,6 +1,6 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller; +using MediaBrowser.Controller; using MediaBrowser.Model.Weather; +using MediaBrowser.Networking.HttpServer; using ServiceStack.ServiceHost; using System.Linq; using System.Threading; diff --git a/MediaBrowser.ApiInteraction.Portable/DataSerializer.cs b/MediaBrowser.ApiInteraction.Portable/DataSerializer.cs deleted file mode 100644 index ad8c38dad..000000000 --- a/MediaBrowser.ApiInteraction.Portable/DataSerializer.cs +++ /dev/null @@ -1,76 +0,0 @@ -using Newtonsoft.Json; -using ProtoBuf; -using ProtoBuf.Meta; -using System; -using System.IO; - -namespace MediaBrowser.ApiInteraction -{ - /// <summary> - /// Class DataSerializer - /// </summary> - public static class DataSerializer - { - /// <summary> - /// Gets or sets the dynamically created serializer. - /// </summary> - /// <value>The dynamic serializer.</value> - public static TypeModel DynamicSerializer { get; set; } - - /// <summary> - /// Deserializes an object - /// </summary> - /// <param name="stream">The stream.</param> - /// <param name="format">The format.</param> - /// <param name="type">The type.</param> - /// <returns>System.Object.</returns> - /// <exception cref="System.NotImplementedException"></exception> - public static object DeserializeFromStream(Stream stream, SerializationFormats format, Type type) - { - if (format == SerializationFormats.Protobuf) - { - if (DynamicSerializer != null) - { - return DynamicSerializer.Deserialize(stream, null, type); - } - return Serializer.NonGeneric.Deserialize(type, stream); - } - if (format == SerializationFormats.Json) - { - using (var streamReader = new StreamReader(stream)) - { - using (var jsonReader = new JsonTextReader(streamReader)) - { - return JsonSerializer.Create(new JsonSerializerSettings()).Deserialize(jsonReader, type); - } - } - } - - throw new NotImplementedException(); - } - - /// <summary> - /// Serializes to json. - /// </summary> - /// <param name="obj">The obj.</param> - /// <returns>System.String.</returns> - public static string SerializeToJsonString(object obj) - { - using (var streamWriter = new StringWriter()) - { - using (var jsonWriter = new JsonTextWriter((streamWriter))) - { - JsonSerializer.Create(new JsonSerializerSettings()).Serialize(jsonWriter, obj); - } - return streamWriter.ToString(); - } - } - - /// <summary> - /// Configures this instance. - /// </summary> - public static void Configure() - { - } - } -} diff --git a/MediaBrowser.ApiInteraction.Portable/MediaBrowser.ApiInteraction.Portable.csproj b/MediaBrowser.ApiInteraction.Portable/MediaBrowser.ApiInteraction.Portable.csproj index 973066307..aaf5a3bd8 100644 --- a/MediaBrowser.ApiInteraction.Portable/MediaBrowser.ApiInteraction.Portable.csproj +++ b/MediaBrowser.ApiInteraction.Portable/MediaBrowser.ApiInteraction.Portable.csproj @@ -38,10 +38,15 @@ <Compile Include="..\MediaBrowser.ApiInteraction\AsyncHttpClient.cs"> <Link>AsyncHttpClient.cs</Link> </Compile> + <Compile Include="..\MediaBrowser.ApiInteraction\NewtonsoftJsonSerializer.cs"> + <Link>NewtonsoftJsonSerializer.cs</Link> + </Compile> + <Compile Include="..\MediaBrowser.ApiInteraction\SerializationFormats.cs"> + <Link>SerializationFormats.cs</Link> + </Compile> <Compile Include="..\SharedVersion.cs"> <Link>Properties\SharedVersion.cs</Link> </Compile> - <Compile Include="DataSerializer.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="..\MediaBrowser.ApiInteraction\BaseApiClient.cs"> <Link>BaseApiClient.cs</Link> @@ -52,9 +57,6 @@ <Compile Include="..\MediaBrowser.ApiInteraction\IAsyncHttpClient.cs"> <Link>IAsyncHttpClient.cs</Link> </Compile> - <Compile Include="..\MediaBrowser.ApiInteraction\SerializationFormats.cs"> - <Link>SerializationFormats.cs</Link> - </Compile> </ItemGroup> <ItemGroup> <Reference Include="Microsoft.Threading.Tasks"> @@ -66,9 +68,6 @@ <Reference Include="Newtonsoft.Json"> <HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\portable-net40+sl4+wp7+win8\Newtonsoft.Json.dll</HintPath> </Reference> - <Reference Include="protobuf-net"> - <HintPath>..\packages\protobuf-net.2.0.0.621\lib\portable-sl4+net40+wp7+windows8\protobuf-net.dll</HintPath> - </Reference> <Reference Include="System.Net.Http"> <HintPath>..\packages\Microsoft.Net.Http.2.1.3-beta\lib\portable-net40+sl4+win8+wp71\System.Net.Http.dll</HintPath> </Reference> diff --git a/MediaBrowser.ApiInteraction.Portable/packages.config b/MediaBrowser.ApiInteraction.Portable/packages.config index c3efe6da4..795bf139c 100644 --- a/MediaBrowser.ApiInteraction.Portable/packages.config +++ b/MediaBrowser.ApiInteraction.Portable/packages.config @@ -5,5 +5,4 @@ <package id="Microsoft.Bcl.Build" version="1.0.0-rc" targetFramework="portable-win+net45+sl40+wp71" /> <package id="Microsoft.Net.Http" version="2.1.3-beta" targetFramework="portable-win+net45+sl40+wp71" /> <package id="Newtonsoft.Json" version="4.5.11" targetFramework="portable-win+net45+sl40+wp71" /> - <package id="protobuf-net" version="2.0.0.621" targetFramework="portable-win+net45+sl40+wp71" /> </packages>
\ No newline at end of file diff --git a/MediaBrowser.ApiInteraction/ApiClient.cs b/MediaBrowser.ApiInteraction/ApiClient.cs index e7d4e6eff..5268c7e1f 100644 --- a/MediaBrowser.ApiInteraction/ApiClient.cs +++ b/MediaBrowser.ApiInteraction/ApiClient.cs @@ -46,6 +46,15 @@ namespace MediaBrowser.ApiInteraction } /// <summary> + /// Initializes a new instance of the <see cref="ApiClient" /> class. + /// </summary> + /// <param name="logger">The logger.</param> + public ApiClient(ILogger logger) + : this(logger, new AsyncHttpClient()) + { + } + + /// <summary> /// Sets the authorization header. /// </summary> /// <param name="header">The header.</param> @@ -67,7 +76,7 @@ namespace MediaBrowser.ApiInteraction throw new ArgumentNullException("url"); } - return HttpClient.GetStreamAsync(url, Logger, CancellationToken.None); + return HttpClient.GetAsync(url, Logger, CancellationToken.None); } /// <summary> @@ -364,7 +373,7 @@ namespace MediaBrowser.ApiInteraction var url = GetApiUrl("Plugins/" + plugin.Id + "/Assembly"); - return HttpClient.GetStreamAsync(url, Logger, CancellationToken.None); + return HttpClient.GetAsync(url, Logger, CancellationToken.None); } /// <summary> @@ -431,7 +440,7 @@ namespace MediaBrowser.ApiInteraction var url = GetApiUrl("Plugins/" + pluginId + "/ConfigurationFile"); - return await HttpClient.GetStreamAsync(url, Logger, CancellationToken.None).ConfigureAwait(false); + return await HttpClient.GetAsync(url, Logger, CancellationToken.None).ConfigureAwait(false); } /// <summary> @@ -963,7 +972,7 @@ namespace MediaBrowser.ApiInteraction const string contentType = "application/x-www-form-urlencoded"; - var postContent = DataSerializer.SerializeToJsonString(obj); + var postContent = SerializeToJson(obj); using (var stream = await HttpClient.PostAsync(url, contentType, postContent, Logger, CancellationToken.None).ConfigureAwait(false)) { @@ -991,7 +1000,7 @@ namespace MediaBrowser.ApiInteraction { url = AddDataFormat(url, serializationFormat); - return HttpClient.GetStreamAsync(url, Logger, CancellationToken.None); + return HttpClient.GetAsync(url, Logger, CancellationToken.None); } diff --git a/MediaBrowser.ApiInteraction/AsyncHttpClient.cs b/MediaBrowser.ApiInteraction/AsyncHttpClient.cs index ec8176d8a..c6701cac0 100644 --- a/MediaBrowser.ApiInteraction/AsyncHttpClient.cs +++ b/MediaBrowser.ApiInteraction/AsyncHttpClient.cs @@ -45,7 +45,7 @@ namespace MediaBrowser.ApiInteraction /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{Stream}.</returns> /// <exception cref="MediaBrowser.Model.Net.HttpException"></exception> - public async Task<Stream> GetStreamAsync(string url, ILogger logger, CancellationToken cancellationToken) + public async Task<Stream> GetAsync(string url, ILogger logger, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); diff --git a/MediaBrowser.ApiInteraction/BaseApiClient.cs b/MediaBrowser.ApiInteraction/BaseApiClient.cs index 242fc2359..4bd4ace50 100644 --- a/MediaBrowser.ApiInteraction/BaseApiClient.cs +++ b/MediaBrowser.ApiInteraction/BaseApiClient.cs @@ -2,6 +2,7 @@ using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Web; using System; using System.Collections.Generic; @@ -22,9 +23,22 @@ namespace MediaBrowser.ApiInteraction protected ILogger Logger { get; private set; } /// <summary> + /// Gets the protobuf serializer. + /// </summary> + /// <value>The protobuf serializer.</value> + public IProtobufSerializer ProtobufSerializer { get; private set; } + + /// <summary> + /// Gets the json serializer. + /// </summary> + /// <value>The json serializer.</value> + public IJsonSerializer JsonSerializer { get; private set; } + + /// <summary> /// Initializes a new instance of the <see cref="BaseApiClient" /> class. /// </summary> /// <param name="logger">The logger.</param> + /// <param name="jsonSerializer">The json serializer.</param> /// <exception cref="System.ArgumentNullException">logger</exception> protected BaseApiClient(ILogger logger) { @@ -33,9 +47,9 @@ namespace MediaBrowser.ApiInteraction throw new ArgumentNullException("logger"); } + JsonSerializer = new NewtonsoftJsonSerializer(); Logger = logger; - - DataSerializer.Configure(); + SerializationFormat = SerializationFormats.Json; } /// <summary> @@ -90,22 +104,11 @@ namespace MediaBrowser.ApiInteraction } } - private SerializationFormats _serializationFormat = SerializationFormats.Protobuf; /// <summary> /// Gets the default data format to request from the server /// </summary> /// <value>The serialization format.</value> - public SerializationFormats SerializationFormat - { - get - { - return _serializationFormat; - } - set - { - _serializationFormat = value; - } - } + public SerializationFormats SerializationFormat { get; set; } /// <summary> /// Resets the authorization header. @@ -790,7 +793,39 @@ namespace MediaBrowser.ApiInteraction protected T DeserializeFromStream<T>(Stream stream) where T : class { - return (T)DataSerializer.DeserializeFromStream(stream, SerializationFormat, typeof(T)); + return (T)DeserializeFromStream(stream, typeof(T), SerializationFormat); + } + + /// <summary> + /// Deserializes from stream. + /// </summary> + /// <param name="stream">The stream.</param> + /// <param name="type">The type.</param> + /// <param name="format">The format.</param> + /// <returns>System.Object.</returns> + /// <exception cref="System.NotImplementedException"></exception> + protected object DeserializeFromStream(Stream stream, Type type, SerializationFormats format) + { + if (format == SerializationFormats.Protobuf) + { + return ProtobufSerializer.DeserializeFromStream(stream, type); + } + if (format == SerializationFormats.Json) + { + return JsonSerializer.DeserializeFromStream(stream, type); + } + + throw new NotImplementedException(); + } + + /// <summary> + /// Serializers to json. + /// </summary> + /// <param name="obj">The obj.</param> + /// <returns>System.String.</returns> + protected string SerializeToJson(object obj) + { + return JsonSerializer.SerializeToString(obj); } /// <summary> diff --git a/MediaBrowser.ApiInteraction/DataSerializer.cs b/MediaBrowser.ApiInteraction/DataSerializer.cs deleted file mode 100644 index cc13d55c8..000000000 --- a/MediaBrowser.ApiInteraction/DataSerializer.cs +++ /dev/null @@ -1,66 +0,0 @@ -using ProtoBuf; -using ProtoBuf.Meta; -using ServiceStack.Text; -using System; -using System.IO; - -namespace MediaBrowser.ApiInteraction -{ - /// <summary> - /// Class DataSerializer - /// </summary> - public static class DataSerializer - { - /// <summary> - /// Gets or sets the dynamically created serializer. - /// </summary> - /// <value>The dynamic serializer.</value> - public static TypeModel DynamicSerializer { get; set; } - - /// <summary> - /// Deserializes an object - /// </summary> - /// <param name="stream">The stream.</param> - /// <param name="format">The format.</param> - /// <param name="type">The type.</param> - /// <returns>System.Object.</returns> - /// <exception cref="System.NotImplementedException"></exception> - public static object DeserializeFromStream(Stream stream, SerializationFormats format, Type type) - { - if (format == SerializationFormats.Protobuf) - { - if (DynamicSerializer != null) - { - return DynamicSerializer.Deserialize(stream, null, type); - } - return Serializer.NonGeneric.Deserialize(type, stream); - } - if (format == SerializationFormats.Json) - { - return JsonSerializer.DeserializeFromStream(type, stream); - } - - throw new NotImplementedException(); - } - - /// <summary> - /// Serializes to json. - /// </summary> - /// <param name="obj">The obj.</param> - /// <returns>System.String.</returns> - public static string SerializeToJsonString(object obj) - { - return JsonSerializer.SerializeToString(obj, obj.GetType()); - } - - /// <summary> - /// Configures this instance. - /// </summary> - public static void Configure() - { - JsConfig.DateHandler = JsonDateHandler.ISO8601; - JsConfig.ExcludeTypeInfo = true; - JsConfig.IncludeNullValues = false; - } - } -} diff --git a/MediaBrowser.ApiInteraction/IAsyncHttpClient.cs b/MediaBrowser.ApiInteraction/IAsyncHttpClient.cs index edd11829a..0837f150f 100644 --- a/MediaBrowser.ApiInteraction/IAsyncHttpClient.cs +++ b/MediaBrowser.ApiInteraction/IAsyncHttpClient.cs @@ -24,7 +24,7 @@ namespace MediaBrowser.ApiInteraction /// <param name="logger">The logger.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{Stream}.</returns> - Task<Stream> GetStreamAsync(string url, ILogger logger, CancellationToken cancellationToken); + Task<Stream> GetAsync(string url, ILogger logger, CancellationToken cancellationToken); /// <summary> /// Deletes the async. diff --git a/MediaBrowser.ApiInteraction/MediaBrowser.ApiInteraction.csproj b/MediaBrowser.ApiInteraction/MediaBrowser.ApiInteraction.csproj index 0d9938891..a4a909192 100644 --- a/MediaBrowser.ApiInteraction/MediaBrowser.ApiInteraction.csproj +++ b/MediaBrowser.ApiInteraction/MediaBrowser.ApiInteraction.csproj @@ -32,19 +32,13 @@ <WarningLevel>4</WarningLevel> </PropertyGroup> <ItemGroup> - <Reference Include="protobuf-net, Version=2.0.0.621, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL"> - <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\protobuf-net.2.0.0.621\lib\net40\protobuf-net.dll</HintPath> - </Reference> - <Reference Include="ServiceStack.Text, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL"> - <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\ServiceStack.Text.3.9.37\lib\net35\ServiceStack.Text.dll</HintPath> + <Reference Include="Newtonsoft.Json"> + <HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath> </Reference> <Reference Include="System" /> <Reference Include="System.Core" /> <Reference Include="System.Net" /> <Reference Include="System.Net.Http" /> - <Reference Include="System.Net.Http.WebRequest" /> <Reference Include="System.Xml.Linq" /> <Reference Include="System.Data.DataSetExtensions" /> <Reference Include="Microsoft.CSharp" /> @@ -58,11 +52,10 @@ <Compile Include="AsyncHttpClient.cs" /> <Compile Include="BaseApiClient.cs" /> <Compile Include="ApiClient.cs" /> - <Compile Include="DataSerializer.cs" /> <Compile Include="IAsyncHttpClient.cs" /> + <Compile Include="NewtonsoftJsonSerializer.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="SerializationFormats.cs" /> - <Compile Include="ServerDiscovery.cs" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj"> diff --git a/MediaBrowser.ApiInteraction/NewtonsoftJsonSerializer.cs b/MediaBrowser.ApiInteraction/NewtonsoftJsonSerializer.cs new file mode 100644 index 000000000..f5b43669e --- /dev/null +++ b/MediaBrowser.ApiInteraction/NewtonsoftJsonSerializer.cs @@ -0,0 +1,141 @@ +using MediaBrowser.Model.Serialization; +using Newtonsoft.Json; +using System; +using System.IO; + +namespace MediaBrowser.ApiInteraction +{ + /// <summary> + /// Class NewtonsoftJsonSerializer + /// </summary> + public class NewtonsoftJsonSerializer : IJsonSerializer + { + /// <summary> + /// Serializes to stream. + /// </summary> + /// <param name="obj">The obj.</param> + /// <param name="stream">The stream.</param> + /// <exception cref="System.NotImplementedException"></exception> + /// <exception cref="System.ArgumentNullException">obj</exception> + public void SerializeToStream(object obj, Stream stream) + { + throw new NotImplementedException(); + } + + /// <summary> + /// Deserializes from stream. + /// </summary> + /// <param name="stream">The stream.</param> + /// <param name="type">The type.</param> + /// <returns>System.Object.</returns> + public object DeserializeFromStream(Stream stream, Type type) + { + using (var streamReader = new StreamReader(stream)) + { + using (var jsonReader = new JsonTextReader(streamReader)) + { + return JsonSerializer.Create(new JsonSerializerSettings()).Deserialize(jsonReader, type); + } + } + } + + /// <summary> + /// Deserializes from stream. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="stream">The stream.</param> + /// <returns>``0.</returns> + public T DeserializeFromStream<T>(Stream stream) + { + return (T)DeserializeFromStream(stream, typeof(T)); + } + + /// <summary> + /// Deserializes from string. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="text">The text.</param> + /// <returns>``0.</returns> + /// <exception cref="System.NotImplementedException"></exception> + public T DeserializeFromString<T>(string text) + { + throw new NotImplementedException(); + } + + /// <summary> + /// Deserializes from string. + /// </summary> + /// <param name="json">The json.</param> + /// <param name="type">The type.</param> + /// <returns>System.Object.</returns> + /// <exception cref="System.NotImplementedException"></exception> + public object DeserializeFromString(string json, Type type) + { + throw new NotImplementedException(); + } + + /// <summary> + /// Serializes to string. + /// </summary> + /// <param name="obj">The obj.</param> + /// <returns>System.String.</returns> + public string SerializeToString(object obj) + { + using (var streamWriter = new StringWriter()) + { + using (var jsonWriter = new JsonTextWriter((streamWriter))) + { + JsonSerializer.Create(new JsonSerializerSettings()).Serialize(jsonWriter, obj); + } + return streamWriter.ToString(); + } + } + + /// <summary> + /// Serializes to bytes. + /// </summary> + /// <param name="obj">The obj.</param> + /// <returns>System.Byte[][].</returns> + /// <exception cref="System.NotImplementedException"></exception> + public byte[] SerializeToBytes(object obj) + { + throw new NotImplementedException(); + } + + /// <summary> + /// Serializes to file. + /// </summary> + /// <param name="obj">The obj.</param> + /// <param name="file">The file.</param> + /// <exception cref="System.NotImplementedException"></exception> + /// <exception cref="System.ArgumentNullException">obj</exception> + public void SerializeToFile(object obj, string file) + { + throw new NotImplementedException(); + } + + /// <summary> + /// Deserializes from file. + /// </summary> + /// <param name="type">The type.</param> + /// <param name="file">The file.</param> + /// <returns>System.Object.</returns> + /// <exception cref="System.NotImplementedException"></exception> + public object DeserializeFromFile(Type type, string file) + { + throw new NotImplementedException(); + } + + /// <summary> + /// Deserializes from file. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="file">The file.</param> + /// <returns>``0.</returns> + /// <exception cref="System.NotImplementedException"></exception> + public T DeserializeFromFile<T>(string file) where T : class + { + throw new NotImplementedException(); + } + } +} diff --git a/MediaBrowser.ApiInteraction/ServerDiscovery.cs b/MediaBrowser.ApiInteraction/ServerDiscovery.cs deleted file mode 100644 index 99a65db5d..000000000 --- a/MediaBrowser.ApiInteraction/ServerDiscovery.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Threading.Tasks; - -namespace MediaBrowser.ApiInteraction -{ - public static class ServerDiscovery - { - /// <summary> - /// Attemps to discover the server within a local network - /// </summary> - public static async Task<IPEndPoint> DiscoverServer() - { - // Create a udp client - var client = new UdpClient(new IPEndPoint(IPAddress.Any, GetRandomUnusedPort())); - - // Construct the message the server is expecting - var bytes = Encoding.UTF8.GetBytes("who is MediaBrowserServer?"); - - // Send it - must be IPAddress.Broadcast, 7359 - var targetEndPoint = new IPEndPoint(IPAddress.Broadcast, 7359); - - // Send it - await client.SendAsync(bytes, bytes.Length, targetEndPoint).ConfigureAwait(false); - - // Get a result back - var result = await client.ReceiveAsync().ConfigureAwait(false); - - if (result.RemoteEndPoint.Port == targetEndPoint.Port) - { - // Convert bytes to text - var text = Encoding.UTF8.GetString(result.Buffer); - - // Expected response : MediaBrowserServer|192.168.1.1:1234 - // If the response is what we're expecting, proceed - if (text.StartsWith("mediabrowserserver", StringComparison.OrdinalIgnoreCase)) - { - text = text.Split('|')[1]; - - var vals = text.Split(':'); - - return new IPEndPoint(IPAddress.Parse(vals[0]), int.Parse(vals[1])); - } - } - - return null; - } - - /// <summary> - /// Gets a random port number that is currently available - /// </summary> - private static int GetRandomUnusedPort() - { - var listener = new TcpListener(IPAddress.Any, 0); - listener.Start(); - var port = ((IPEndPoint)listener.LocalEndpoint).Port; - listener.Stop(); - return port; - } - } -} diff --git a/MediaBrowser.ApiInteraction/packages.config b/MediaBrowser.ApiInteraction/packages.config index 14eb42cac..b82a8b0dd 100644 --- a/MediaBrowser.ApiInteraction/packages.config +++ b/MediaBrowser.ApiInteraction/packages.config @@ -1,5 +1,4 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="protobuf-net" version="2.0.0.621" targetFramework="net45" /> - <package id="ServiceStack.Text" version="3.9.37" targetFramework="net45" /> + <package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs new file mode 100644 index 000000000..c5af5059f --- /dev/null +++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs @@ -0,0 +1,295 @@ +using System.IO; +using System.Linq; +using System.Reflection; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; +using SimpleInjector; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace MediaBrowser.Common.Implementations +{ + public abstract class BaseApplicationHost : IDisposable + { + /// <summary> + /// Gets or sets the logger. + /// </summary> + /// <value>The logger.</value> + public ILogger Logger { get; protected set; } + + /// <summary> + /// The container + /// </summary> + protected readonly Container Container = new Container(); + + /// <summary> + /// Gets assemblies that failed to load + /// </summary> + public List<string> FailedAssemblies { get; protected set; } + + /// <summary> + /// Gets all types within all running assemblies + /// </summary> + /// <value>All types.</value> + public Type[] AllTypes { get; protected set; } + + /// <summary> + /// Gets all concrete types. + /// </summary> + /// <value>All concrete types.</value> + public Type[] AllConcreteTypes { get; protected set; } + + /// <summary> + /// The disposable parts + /// </summary> + protected readonly List<IDisposable> DisposableParts = new List<IDisposable>(); + + /// <summary> + /// The _protobuf serializer initialized + /// </summary> + private bool _protobufSerializerInitialized; + /// <summary> + /// The _protobuf serializer sync lock + /// </summary> + private object _protobufSerializerSyncLock = new object(); + /// <summary> + /// Gets a dynamically compiled generated serializer that can serialize protocontracts without reflection + /// </summary> + private IProtobufSerializer _protobufSerializer; + /// <summary> + /// Gets the protobuf serializer. + /// </summary> + /// <value>The protobuf serializer.</value> + protected IProtobufSerializer ProtobufSerializer + { + get + { + // Lazy load + LazyInitializer.EnsureInitialized(ref _protobufSerializer, ref _protobufSerializerInitialized, ref _protobufSerializerSyncLock, () => Serialization.ProtobufSerializer.Create(AllTypes)); + return _protobufSerializer; + } + private set + { + _protobufSerializer = value; + _protobufSerializerInitialized = value != null; + } + } + + /// <summary> + /// Initializes a new instance of the <see cref="BaseApplicationHost" /> class. + /// </summary> + protected BaseApplicationHost() + { + FailedAssemblies = new List<string>(); + } + + /// <summary> + /// Gets the composable part assemblies. + /// </summary> + /// <returns>IEnumerable{Assembly}.</returns> + protected abstract IEnumerable<Assembly> GetComposablePartAssemblies(); + + /// <summary> + /// Discovers the types. + /// </summary> + protected void DiscoverTypes() + { + FailedAssemblies.Clear(); + + AllTypes = GetComposablePartAssemblies().SelectMany(GetTypes).ToArray(); + + AllConcreteTypes = AllTypes.Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType).ToArray(); + } + + /// <summary> + /// Gets a list of types within an assembly + /// This will handle situations that would normally throw an exception - such as a type within the assembly that depends on some other non-existant reference + /// </summary> + /// <param name="assembly">The assembly.</param> + /// <returns>IEnumerable{Type}.</returns> + /// <exception cref="System.ArgumentNullException">assembly</exception> + protected IEnumerable<Type> GetTypes(Assembly assembly) + { + if (assembly == null) + { + throw new ArgumentNullException("assembly"); + } + + try + { + return assembly.GetTypes(); + } + catch (ReflectionTypeLoadException ex) + { + // If it fails we can still get a list of the Types it was able to resolve + return ex.Types.Where(t => t != null); + } + } + + /// <summary> + /// Creates an instance of type and resolves all constructor dependancies + /// </summary> + /// <param name="type">The type.</param> + /// <returns>System.Object.</returns> + public object CreateInstance(Type type) + { + try + { + return Container.GetInstance(type); + } + catch + { + Logger.Error("Error creating {0}", type.Name); + + throw; + } + } + + /// <summary> + /// Registers the specified obj. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="obj">The obj.</param> + protected void RegisterSingleInstance<T>(T obj) + where T : class + { + Container.RegisterSingle(obj); + } + + /// <summary> + /// Registers the specified func. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="func">The func.</param> + protected void Register<T>(Func<T> func) + where T : class + { + Container.Register(func); + } + + /// <summary> + /// Registers the single instance. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="func">The func.</param> + protected void RegisterSingleInstance<T>(Func<T> func) + where T : class + { + Container.RegisterSingle(func); + } + + /// <summary> + /// Resolves this instance. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <returns>``0.</returns> + public T Resolve<T>() + { + return (T)Container.GetRegistration(typeof(T), true).GetInstance(); + } + + /// <summary> + /// Resolves this instance. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <returns>``0.</returns> + public T TryResolve<T>() + { + var result = Container.GetRegistration(typeof(T), false); + + if (result == null) + { + return default(T); + } + return (T)result.GetInstance(); + } + + /// <summary> + /// Registers the specified service type. + /// </summary> + /// <param name="serviceType">Type of the service.</param> + /// <param name="implementation">Type of the concrete.</param> + protected void Register(Type serviceType, Type implementation) + { + Container.Register(serviceType, implementation); + } + + /// <summary> + /// Loads the assembly. + /// </summary> + /// <param name="file">The file.</param> + /// <returns>Assembly.</returns> + protected Assembly LoadAssembly(string file) + { + try + { + return Assembly.Load(File.ReadAllBytes((file))); + } + catch (Exception ex) + { + FailedAssemblies.Add(file); + Logger.ErrorException("Error loading assembly {0}", ex, file); + return null; + } + } + + /// <summary> + /// Gets the exports. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="manageLiftime">if set to <c>true</c> [manage liftime].</param> + /// <returns>IEnumerable{``0}.</returns> + public IEnumerable<T> GetExports<T>(bool manageLiftime = true) + { + var currentType = typeof(T); + + Logger.Info("Composing instances of " + currentType.Name); + + var parts = AllConcreteTypes.Where(currentType.IsAssignableFrom).Select(CreateInstance).Cast<T>().ToArray(); + + if (manageLiftime) + { + DisposableParts.AddRange(parts.OfType<IDisposable>()); + } + + return parts; + } + + /// <summary> + /// Gets the current application version + /// </summary> + /// <value>The application version.</value> + public Version ApplicationVersion + { + get + { + return GetType().Assembly.GetName().Version; + } + } + + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() + { + Dispose(true); + } + + /// <summary> + /// Releases unmanaged and - optionally - managed resources. + /// </summary> + /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> + protected virtual void Dispose(bool dispose) + { + foreach (var part in DisposableParts) + { + part.Dispose(); + } + + var b = Container.GetCurrentRegistrations(); + + DisposableParts.Clear(); + } + } +} diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index 736a15d42..acd798d73 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -41,6 +41,9 @@ <Reference Include="ServiceStack.Text"> <HintPath>..\packages\ServiceStack.Text.3.9.37\lib\net35\ServiceStack.Text.dll</HintPath> </Reference> + <Reference Include="SimpleInjector"> + <HintPath>..\packages\SimpleInjector.2.0.0-beta5\lib\net40-client\SimpleInjector.dll</HintPath> + </Reference> <Reference Include="System" /> <Reference Include="System.Configuration" /> <Reference Include="System.Core" /> @@ -54,8 +57,10 @@ <Compile Include="..\SharedVersion.cs"> <Link>Properties\SharedVersion.cs</Link> </Compile> + <Compile Include="BaseApplicationHost.cs" /> <Compile Include="BaseApplicationPaths.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="ScheduledTasks\ScheduledTaskWorker.cs" /> <Compile Include="ScheduledTasks\TaskManager.cs" /> <Compile Include="ScheduledTasks\Tasks\DeleteCacheFileTask.cs" /> <Compile Include="ScheduledTasks\Tasks\DeleteLogFileTask.cs" /> diff --git a/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index 09ceaa9ae..7fa30f4ae 100644 --- a/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -1,6 +1,8 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Kernel; +using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Tasks; using System; using System.Collections.Generic; @@ -9,60 +11,58 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -namespace MediaBrowser.Common.ScheduledTasks +namespace MediaBrowser.Common.Implementations.ScheduledTasks { /// <summary> - /// Represents a task that can be executed at a scheduled time + /// Class ScheduledTaskWorker /// </summary> - /// <typeparam name="TKernelType">The type of the T kernel type.</typeparam> - public abstract class BaseScheduledTask<TKernelType> : IScheduledTask - where TKernelType : class, IKernel + public class ScheduledTaskWorker : IScheduledTaskWorker { /// <summary> - /// Gets the kernel. + /// Gets or sets the scheduled task. /// </summary> - /// <value>The kernel.</value> - protected TKernelType Kernel { get; private set; } + /// <value>The scheduled task.</value> + public IScheduledTask ScheduledTask { get; private set; } + + /// <summary> + /// Gets or sets the json serializer. + /// </summary> + /// <value>The json serializer.</value> + private IJsonSerializer JsonSerializer { get; set; } + + /// <summary> + /// Gets or sets the application paths. + /// </summary> + /// <value>The application paths.</value> + private IApplicationPaths ApplicationPaths { get; set; } /// <summary> /// Gets the logger. /// </summary> /// <value>The logger.</value> - protected ILogger Logger { get; private set; } + private ILogger Logger { get; set; } /// <summary> /// Gets the task manager. /// </summary> /// <value>The task manager.</value> - protected ITaskManager TaskManager { get; private set; } + private ITaskManager TaskManager { get; set; } /// <summary> - /// Initializes a new instance of the <see cref="BaseScheduledTask{TKernelType}" /> class. + /// Initializes a new instance of the <see cref="ScheduledTaskWorker" /> class. /// </summary> - /// <param name="kernel">The kernel.</param> + /// <param name="scheduledTask">The scheduled task.</param> + /// <param name="applicationPaths">The application paths.</param> /// <param name="taskManager">The task manager.</param> + /// <param name="jsonSerializer">The json serializer.</param> /// <param name="logger">The logger.</param> - /// <exception cref="System.ArgumentNullException">kernel</exception> - protected BaseScheduledTask(TKernelType kernel, ITaskManager taskManager, ILogger logger) + public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, IJsonSerializer jsonSerializer, ILogger logger) { - if (kernel == null) - { - throw new ArgumentNullException("kernel"); - } - if (taskManager == null) - { - throw new ArgumentNullException("taskManager"); - } - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - - Kernel = kernel; + ScheduledTask = scheduledTask; + ApplicationPaths = applicationPaths; TaskManager = taskManager; + JsonSerializer = jsonSerializer; Logger = logger; - - ReloadTriggerEvents(true); } /// <summary> @@ -89,7 +89,7 @@ namespace MediaBrowser.Common.ScheduledTasks { try { - return TaskManager.GetLastExecutionResult(this); + return JsonSerializer.DeserializeFromFile<TaskResult>(GetHistoryFilePath()); } catch (IOException) { @@ -109,6 +109,33 @@ namespace MediaBrowser.Common.ScheduledTasks } /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + public string Name + { + get { return ScheduledTask.Name; } + } + + /// <summary> + /// Gets the description. + /// </summary> + /// <value>The description.</value> + public string Description + { + get { return ScheduledTask.Description; } + } + + /// <summary> + /// Gets the category. + /// </summary> + /// <value>The category.</value> + public string Category + { + get { return ScheduledTask.Category; } + } + + /// <summary> /// Gets the current cancellation token /// </summary> /// <value>The current cancellation token source.</value> @@ -166,7 +193,7 @@ namespace MediaBrowser.Common.ScheduledTasks { get { - LazyInitializer.EnsureInitialized(ref _triggers, ref _triggersInitialized, ref _triggersSyncLock, () => TaskManager.LoadTriggers(this)); + LazyInitializer.EnsureInitialized(ref _triggers, ref _triggersInitialized, ref _triggersSyncLock, () => LoadTriggers()); return _triggers; } @@ -189,46 +216,11 @@ namespace MediaBrowser.Common.ScheduledTasks ReloadTriggerEvents(false); - TaskManager.SaveTriggers(this, _triggers); + SaveTriggers(_triggers); } } /// <summary> - /// Creates the triggers that define when the task will run - /// </summary> - /// <returns>IEnumerable{BaseTaskTrigger}.</returns> - public abstract IEnumerable<ITaskTrigger> GetDefaultTriggers(); - - /// <summary> - /// Returns the task to be executed - /// </summary> - /// <param name="cancellationToken">The cancellation token.</param> - /// <param name="progress">The progress.</param> - /// <returns>Task.</returns> - protected abstract Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress); - - /// <summary> - /// Gets the name of the task - /// </summary> - /// <value>The name.</value> - public abstract string Name { get; } - - /// <summary> - /// Gets the description. - /// </summary> - /// <value>The description.</value> - public abstract string Description { get; } - - /// <summary> - /// Gets the category. - /// </summary> - /// <value>The category.</value> - public virtual string Category - { - get { return "Application"; } - } - - /// <summary> /// The _id /// </summary> private Guid? _id; @@ -243,7 +235,7 @@ namespace MediaBrowser.Common.ScheduledTasks { if (!_id.HasValue) { - _id = GetType().FullName.GetMD5(); + _id = ScheduledTask.GetType().FullName.GetMD5(); } return _id.Value; @@ -279,10 +271,10 @@ namespace MediaBrowser.Common.ScheduledTasks trigger.Stop(); - TaskManager.QueueScheduledTask(this); + TaskManager.QueueScheduledTask(ScheduledTask); + + await Task.Delay(1000).ConfigureAwait(false); - await Task.Delay(1000).ConfigureAwait(false); - trigger.Start(false); } @@ -310,11 +302,11 @@ namespace MediaBrowser.Common.ScheduledTasks TaskCompletionStatus status; CurrentExecutionStartTime = DateTime.UtcNow; - Kernel.TcpManager.SendWebSocketMessage("ScheduledTaskBeginExecute", Name); + //Kernel.TcpManager.SendWebSocketMessage("ScheduledTaskBeginExecute", Name); try { - await Task.Run(async () => await ExecuteInternal(CurrentCancellationTokenSource.Token, progress).ConfigureAwait(false)).ConfigureAwait(false); + await System.Threading.Tasks.Task.Run(async () => await ScheduledTask.Execute(CurrentCancellationTokenSource.Token, progress).ConfigureAwait(false)).ConfigureAwait(false); status = TaskCompletionStatus.Completed; } @@ -332,14 +324,14 @@ namespace MediaBrowser.Common.ScheduledTasks var startTime = CurrentExecutionStartTime; var endTime = DateTime.UtcNow; - Kernel.TcpManager.SendWebSocketMessage("ScheduledTaskEndExecute", LastExecutionResult); + //Kernel.TcpManager.SendWebSocketMessage("ScheduledTaskEndExecute", LastExecutionResult); progress.ProgressChanged -= progress_ProgressChanged; CurrentCancellationTokenSource.Dispose(); CurrentCancellationTokenSource = null; CurrentProgress = null; - TaskManager.OnTaskCompleted(this, startTime, endTime, status); + OnTaskCompleted(startTime, endTime, status); } /// <summary> @@ -379,6 +371,128 @@ namespace MediaBrowser.Common.ScheduledTasks } /// <summary> + /// The _scheduled tasks configuration directory + /// </summary> + private string _scheduledTasksConfigurationDirectory; + /// <summary> + /// Gets the scheduled tasks configuration directory. + /// </summary> + /// <value>The scheduled tasks configuration directory.</value> + private string ScheduledTasksConfigurationDirectory + { + get + { + if (_scheduledTasksConfigurationDirectory == null) + { + _scheduledTasksConfigurationDirectory = Path.Combine(ApplicationPaths.ConfigurationDirectoryPath, "ScheduledTasks"); + + if (!Directory.Exists(_scheduledTasksConfigurationDirectory)) + { + Directory.CreateDirectory(_scheduledTasksConfigurationDirectory); + } + } + return _scheduledTasksConfigurationDirectory; + } + } + + /// <summary> + /// The _scheduled tasks data directory + /// </summary> + private string _scheduledTasksDataDirectory; + /// <summary> + /// Gets the scheduled tasks data directory. + /// </summary> + /// <value>The scheduled tasks data directory.</value> + private string ScheduledTasksDataDirectory + { + get + { + if (_scheduledTasksDataDirectory == null) + { + _scheduledTasksDataDirectory = Path.Combine(ApplicationPaths.DataPath, "ScheduledTasks"); + + if (!Directory.Exists(_scheduledTasksDataDirectory)) + { + Directory.CreateDirectory(_scheduledTasksDataDirectory); + } + } + return _scheduledTasksDataDirectory; + } + } + + /// <summary> + /// Gets the history file path. + /// </summary> + /// <value>The history file path.</value> + private string GetHistoryFilePath() + { + return Path.Combine(ScheduledTasksDataDirectory, Id + ".js"); + } + + /// <summary> + /// Gets the configuration file path. + /// </summary> + /// <returns>System.String.</returns> + private string GetConfigurationFilePath() + { + return Path.Combine(ScheduledTasksConfigurationDirectory, Id + ".js"); + } + + /// <summary> + /// Loads the triggers. + /// </summary> + /// <returns>IEnumerable{BaseTaskTrigger}.</returns> + private IEnumerable<ITaskTrigger> LoadTriggers() + { + try + { + return JsonSerializer.DeserializeFromFile<IEnumerable<TaskTriggerInfo>>(GetConfigurationFilePath()) + .Select(ScheduledTaskHelpers.GetTrigger) + .ToList(); + } + catch (IOException) + { + // File doesn't exist. No biggie. Return defaults. + return ScheduledTask.GetDefaultTriggers(); + } + } + + /// <summary> + /// Saves the triggers. + /// </summary> + /// <param name="triggers">The triggers.</param> + private void SaveTriggers(IEnumerable<ITaskTrigger> triggers) + { + JsonSerializer.SerializeToFile(triggers.Select(ScheduledTaskHelpers.GetTriggerInfo), GetConfigurationFilePath()); + } + + /// <summary> + /// Called when [task completed]. + /// </summary> + /// <param name="startTime">The start time.</param> + /// <param name="endTime">The end time.</param> + /// <param name="status">The status.</param> + private void OnTaskCompleted(DateTime startTime, DateTime endTime, TaskCompletionStatus status) + { + var elapsedTime = endTime - startTime; + + Logger.Info("{0} {1} after {2} minute(s) and {3} seconds", Name, status, Math.Truncate(elapsedTime.TotalMinutes), elapsedTime.Seconds); + + var result = new TaskResult + { + StartTimeUtc = startTime, + EndTimeUtc = endTime, + Status = status, + Name = Name, + Id = Id + }; + + JsonSerializer.SerializeToFile(result, GetHistoryFilePath()); + + LastExecutionResult = result; + } + + /// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> public void Dispose() @@ -399,7 +513,7 @@ namespace MediaBrowser.Common.ScheduledTasks if (State == TaskState.Running) { - TaskManager.OnTaskCompleted(this, CurrentExecutionStartTime, DateTime.UtcNow, TaskCompletionStatus.Aborted); + OnTaskCompleted(CurrentExecutionStartTime, DateTime.UtcNow, TaskCompletionStatus.Aborted); } if (CurrentCancellationTokenSource != null) diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs index c6eca29d1..4b61492d6 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs @@ -5,7 +5,6 @@ using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Tasks; using System; using System.Collections.Generic; -using System.IO; using System.Linq; namespace MediaBrowser.Common.Implementations.ScheduledTasks @@ -19,7 +18,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// Gets the list of Scheduled Tasks /// </summary> /// <value>The scheduled tasks.</value> - public IScheduledTask[] ScheduledTasks { get; private set; } + public IScheduledTaskWorker[] ScheduledTasks { get; private set; } /// <summary> /// The _task queue @@ -27,19 +26,22 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks private readonly List<Type> _taskQueue = new List<Type>(); /// <summary> - /// The _logger + /// Gets or sets the json serializer. /// </summary> - private readonly ILogger _logger; + /// <value>The json serializer.</value> + private IJsonSerializer JsonSerializer { get; set; } /// <summary> - /// The _application paths + /// Gets or sets the application paths. /// </summary> - private readonly IApplicationPaths _applicationPaths; + /// <value>The application paths.</value> + private IApplicationPaths ApplicationPaths { get; set; } /// <summary> - /// The _json serializer + /// Gets the logger. /// </summary> - private readonly IJsonSerializer _jsonSerializer; + /// <value>The logger.</value> + private ILogger Logger { get; set; } /// <summary> /// Initializes a new instance of the <see cref="TaskManager" /> class. @@ -50,24 +52,11 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// <exception cref="System.ArgumentException">kernel</exception> public TaskManager(IApplicationPaths applicationPaths, IJsonSerializer jsonSerializer, ILogger logger) { - if (applicationPaths == null) - { - throw new ArgumentException("applicationPaths"); - } - if (jsonSerializer == null) - { - throw new ArgumentException("jsonSerializer"); - } - if (logger == null) - { - throw new ArgumentException("logger"); - } + ApplicationPaths = applicationPaths; + JsonSerializer = jsonSerializer; + Logger = logger; - _applicationPaths = applicationPaths; - _jsonSerializer = jsonSerializer; - _logger = logger; - - ScheduledTasks = new IScheduledTask[] {}; + ScheduledTasks = new IScheduledTaskWorker[] { }; } /// <summary> @@ -77,7 +66,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks public void CancelIfRunningAndQueue<T>() where T : IScheduledTask { - ScheduledTasks.OfType<T>().First().CancelIfRunning(); + ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T)).CancelIfRunning(); QueueScheduledTask<T>(); } @@ -88,7 +77,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks public void QueueScheduledTask<T>() where T : IScheduledTask { - var scheduledTask = ScheduledTasks.OfType<T>().First(); + var scheduledTask = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T)); QueueScheduledTask(scheduledTask); } @@ -99,27 +88,36 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// <param name="task">The task.</param> public void QueueScheduledTask(IScheduledTask task) { - var type = task.GetType(); + var scheduledTask = ScheduledTasks.First(t => t.ScheduledTask.GetType() == task.GetType()); - var scheduledTask = ScheduledTasks.First(t => t.GetType() == type); + QueueScheduledTask(scheduledTask); + } + + /// <summary> + /// Queues the scheduled task. + /// </summary> + /// <param name="task">The task.</param> + private void QueueScheduledTask(IScheduledTaskWorker task) + { + var type = task.GetType(); lock (_taskQueue) { // If it's idle just execute immediately - if (scheduledTask.State == TaskState.Idle) + if (task.State == TaskState.Idle) { - scheduledTask.Execute(); + task.Execute(); return; } if (!_taskQueue.Contains(type)) { - _logger.Info("Queueing task {0}", type.Name); + Logger.Info("Queueing task {0}", type.Name); _taskQueue.Add(type); } else { - _logger.Info("Task already queued: {0}", type.Name); + Logger.Info("Task already queued: {0}", type.Name); } } } @@ -157,148 +155,12 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks { var myTasks = ScheduledTasks.ToList(); - myTasks.AddRange(tasks); + myTasks.AddRange(tasks.Select(t => new ScheduledTaskWorker(t, ApplicationPaths, this, JsonSerializer, Logger))); ScheduledTasks = myTasks.ToArray(); } /// <summary> - /// The _scheduled tasks configuration directory - /// </summary> - private string _scheduledTasksConfigurationDirectory; - /// <summary> - /// Gets the scheduled tasks configuration directory. - /// </summary> - /// <value>The scheduled tasks configuration directory.</value> - private string ScheduledTasksConfigurationDirectory - { - get - { - if (_scheduledTasksConfigurationDirectory == null) - { - _scheduledTasksConfigurationDirectory = Path.Combine(_applicationPaths.ConfigurationDirectoryPath, "ScheduledTasks"); - - if (!Directory.Exists(_scheduledTasksConfigurationDirectory)) - { - Directory.CreateDirectory(_scheduledTasksConfigurationDirectory); - } - } - return _scheduledTasksConfigurationDirectory; - } - } - - /// <summary> - /// The _scheduled tasks data directory - /// </summary> - private string _scheduledTasksDataDirectory; - /// <summary> - /// Gets the scheduled tasks data directory. - /// </summary> - /// <value>The scheduled tasks data directory.</value> - private string ScheduledTasksDataDirectory - { - get - { - if (_scheduledTasksDataDirectory == null) - { - _scheduledTasksDataDirectory = Path.Combine(_applicationPaths.DataPath, "ScheduledTasks"); - - if (!Directory.Exists(_scheduledTasksDataDirectory)) - { - Directory.CreateDirectory(_scheduledTasksDataDirectory); - } - } - return _scheduledTasksDataDirectory; - } - } - - /// <summary> - /// Gets the history file path. - /// </summary> - /// <value>The history file path.</value> - private string GetHistoryFilePath(IScheduledTask task) - { - return Path.Combine(ScheduledTasksDataDirectory, task.Id + ".js"); - } - - /// <summary> - /// Gets the configuration file path. - /// </summary> - /// <param name="task">The task.</param> - /// <returns>System.String.</returns> - private string GetConfigurationFilePath(IScheduledTask task) - { - return Path.Combine(ScheduledTasksConfigurationDirectory, task.Id + ".js"); - } - - /// <summary> - /// Called when [task completed]. - /// </summary> - /// <param name="task">The task.</param> - /// <param name="startTime">The start time.</param> - /// <param name="endTime">The end time.</param> - /// <param name="status">The status.</param> - public void OnTaskCompleted(IScheduledTask task, DateTime startTime, DateTime endTime, TaskCompletionStatus status) - { - var elapsedTime = endTime - startTime; - - _logger.Info("{0} {1} after {2} minute(s) and {3} seconds", task.Name, status, Math.Truncate(elapsedTime.TotalMinutes), elapsedTime.Seconds); - - var result = new TaskResult - { - StartTimeUtc = startTime, - EndTimeUtc = endTime, - Status = status, - Name = task.Name, - Id = task.Id - }; - - _jsonSerializer.SerializeToFile(result, GetHistoryFilePath(task)); - - //task.LastExecutionResult = result; - } - - /// <summary> - /// Gets the last execution result. - /// </summary> - /// <param name="task">The task.</param> - /// <returns>TaskResult.</returns> - public TaskResult GetLastExecutionResult(IScheduledTask task) - { - return _jsonSerializer.DeserializeFromFile<TaskResult>(GetHistoryFilePath(task)); - } - - /// <summary> - /// Loads the triggers. - /// </summary> - /// <param name="task">The task.</param> - /// <returns>IEnumerable{BaseTaskTrigger}.</returns> - public IEnumerable<ITaskTrigger> LoadTriggers(IScheduledTask task) - { - try - { - return _jsonSerializer.DeserializeFromFile<IEnumerable<TaskTriggerInfo>>(GetConfigurationFilePath(task)) - .Select(ScheduledTaskHelpers.GetTrigger) - .ToList(); - } - catch (IOException) - { - // File doesn't exist. No biggie. Return defaults. - return task.GetDefaultTriggers(); - } - } - - /// <summary> - /// Saves the triggers. - /// </summary> - /// <param name="task">The task.</param> - /// <param name="triggers">The triggers.</param> - public void SaveTriggers(IScheduledTask task, IEnumerable<ITaskTrigger> triggers) - { - _jsonSerializer.SerializeToFile(triggers.Select(ScheduledTaskHelpers.GetTriggerInfo), GetConfigurationFilePath(task)); - } - - /// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> public void Dispose() diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs index 2ef056658..a9c82c357 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs @@ -13,24 +13,35 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// <summary> /// Deletes old cache files /// </summary> - public class DeleteCacheFileTask : BaseScheduledTask<IKernel> + public class DeleteCacheFileTask : IScheduledTask { /// <summary> + /// Gets or sets the kernel. + /// </summary> + /// <value>The kernel.</value> + private IKernel Kernel { get; set; } + /// <summary> + /// Gets or sets the logger. + /// </summary> + /// <value>The logger.</value> + private ILogger Logger { get; set; } + + /// <summary> /// Initializes a new instance of the <see cref="DeleteCacheFileTask" /> class. /// </summary> /// <param name="kernel">The kernel.</param> - /// <param name="taskManager">The task manager.</param> /// <param name="logger">The logger.</param> - public DeleteCacheFileTask(IKernel kernel, ITaskManager taskManager, ILogger logger) - : base(kernel, taskManager, logger) + public DeleteCacheFileTask(IKernel kernel, ILogger logger) { + Kernel = kernel; + Logger = logger; } /// <summary> /// Creates the triggers that define when the task will run /// </summary> /// <returns>IEnumerable{BaseTaskTrigger}.</returns> - public override IEnumerable<ITaskTrigger> GetDefaultTriggers() + public IEnumerable<ITaskTrigger> GetDefaultTriggers() { var trigger = new DailyTrigger { TimeOfDay = TimeSpan.FromHours(2) }; //2am @@ -43,7 +54,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// <param name="cancellationToken">The cancellation token.</param> /// <param name="progress">The progress.</param> /// <returns>Task.</returns> - protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress) + public Task Execute(CancellationToken cancellationToken, IProgress<double> progress) { return Task.Run(() => { @@ -90,7 +101,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// Gets the name of the task /// </summary> /// <value>The name.</value> - public override string Name + public string Name { get { return "Cache file cleanup"; } } @@ -99,7 +110,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// Gets the description. /// </summary> /// <value>The description.</value> - public override string Description + public string Description { get { return "Deletes cache files no longer needed by the system"; } } @@ -108,7 +119,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// Gets the category. /// </summary> /// <value>The category.</value> - public override string Category + public string Category { get { diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs index dd00a7148..a7d8a68a0 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs @@ -13,24 +13,35 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// <summary> /// Deletes old log files /// </summary> - public class DeleteLogFileTask : BaseScheduledTask<IKernel> + public class DeleteLogFileTask : IScheduledTask { /// <summary> + /// Gets or sets the kernel. + /// </summary> + /// <value>The kernel.</value> + private IKernel Kernel { get; set; } + /// <summary> + /// Gets or sets the logger. + /// </summary> + /// <value>The logger.</value> + private ILogger Logger { get; set; } + + /// <summary> /// Initializes a new instance of the <see cref="DeleteLogFileTask" /> class. /// </summary> /// <param name="kernel">The kernel.</param> - /// <param name="taskManager">The task manager.</param> /// <param name="logger">The logger.</param> - public DeleteLogFileTask(IKernel kernel, ITaskManager taskManager, ILogger logger) - : base(kernel, taskManager, logger) + public DeleteLogFileTask(IKernel kernel, ILogger logger) { + Kernel = kernel; + Logger = logger; } /// <summary> /// Creates the triggers that define when the task will run /// </summary> /// <returns>IEnumerable{BaseTaskTrigger}.</returns> - public override IEnumerable<ITaskTrigger> GetDefaultTriggers() + public IEnumerable<ITaskTrigger> GetDefaultTriggers() { var trigger = new DailyTrigger { TimeOfDay = TimeSpan.FromHours(2) }; //2am @@ -43,7 +54,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// <param name="cancellationToken">The cancellation token.</param> /// <param name="progress">The progress.</param> /// <returns>Task.</returns> - protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress) + public Task Execute(CancellationToken cancellationToken, IProgress<double> progress) { return Task.Run(() => { @@ -78,7 +89,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// Gets the name of the task /// </summary> /// <value>The name.</value> - public override string Name + public string Name { get { return "Log file cleanup"; } } @@ -87,7 +98,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// Gets the description. /// </summary> /// <value>The description.</value> - public override string Description + public string Description { get { return string.Format("Deletes log files that are more than {0} days old.", Kernel.Configuration.LogFileRetentionDays); } } @@ -96,7 +107,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// Gets the category. /// </summary> /// <value>The category.</value> - public override string Category + public string Category { get { diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs index 79c633c76..ac06f111a 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs @@ -11,24 +11,35 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// <summary> /// Class ReloadLoggerFileTask /// </summary> - public class ReloadLoggerFileTask : BaseScheduledTask<IKernel> + public class ReloadLoggerFileTask : IScheduledTask { /// <summary> + /// Gets or sets the kernel. + /// </summary> + /// <value>The kernel.</value> + private IKernel Kernel { get; set; } + /// <summary> + /// Gets or sets the logger. + /// </summary> + /// <value>The logger.</value> + private ILogger Logger { get; set; } + + /// <summary> /// Initializes a new instance of the <see cref="ReloadLoggerFileTask" /> class. /// </summary> /// <param name="kernel">The kernel.</param> - /// <param name="taskManager">The task manager.</param> /// <param name="logger">The logger.</param> - public ReloadLoggerFileTask(IKernel kernel, ITaskManager taskManager, ILogger logger) - : base(kernel, taskManager, logger) + public ReloadLoggerFileTask(IKernel kernel, ILogger logger) { + Kernel = kernel; + Logger = logger; } /// <summary> /// Gets the default triggers. /// </summary> /// <returns>IEnumerable{BaseTaskTrigger}.</returns> - public override IEnumerable<ITaskTrigger> GetDefaultTriggers() + public IEnumerable<ITaskTrigger> GetDefaultTriggers() { var trigger = new DailyTrigger { TimeOfDay = TimeSpan.FromHours(0) }; //12am @@ -41,7 +52,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// <param name="cancellationToken">The cancellation token.</param> /// <param name="progress">The progress.</param> /// <returns>Task.</returns> - protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress) + public Task Execute(CancellationToken cancellationToken, IProgress<double> progress) { cancellationToken.ThrowIfCancellationRequested(); @@ -54,7 +65,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// Gets the name. /// </summary> /// <value>The name.</value> - public override string Name + public string Name { get { return "Start new log file"; } } @@ -63,9 +74,18 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// Gets the description. /// </summary> /// <value>The description.</value> - public override string Description + public string Description { get { return "Moves logging to a new file to help reduce log file sizes."; } } + + /// <summary> + /// Gets the category. + /// </summary> + /// <value>The category.</value> + public string Category + { + get { return "Application"; } + } } } diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/SystemUpdateTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/SystemUpdateTask.cs index a101ad3dd..18fcdbbda 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/SystemUpdateTask.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/SystemUpdateTask.cs @@ -11,7 +11,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// <summary> /// Plugin Update Task /// </summary> - public class SystemUpdateTask : BaseScheduledTask<IKernel> + public class SystemUpdateTask : IScheduledTask { /// <summary> /// The _app host @@ -19,23 +19,34 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks private readonly IApplicationHost _appHost; /// <summary> + /// Gets or sets the kernel. + /// </summary> + /// <value>The kernel.</value> + private IKernel Kernel { get; set; } + /// <summary> + /// Gets or sets the logger. + /// </summary> + /// <value>The logger.</value> + private ILogger Logger { get; set; } + + /// <summary> /// Initializes a new instance of the <see cref="SystemUpdateTask" /> class. /// </summary> /// <param name="appHost">The app host.</param> - /// <param name="taskManager">The task manager.</param> /// <param name="kernel">The kernel.</param> /// <param name="logger">The logger.</param> - public SystemUpdateTask(IApplicationHost appHost, ITaskManager taskManager, IKernel kernel, ILogger logger) - : base(kernel, taskManager, logger) + public SystemUpdateTask(IApplicationHost appHost, IKernel kernel, ILogger logger) { _appHost = appHost; + Kernel = kernel; + Logger = logger; } /// <summary> /// Creates the triggers that define when the task will run /// </summary> /// <returns>IEnumerable{BaseTaskTrigger}.</returns> - public override IEnumerable<ITaskTrigger> GetDefaultTriggers() + public IEnumerable<ITaskTrigger> GetDefaultTriggers() { return new ITaskTrigger[] { @@ -52,7 +63,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// <param name="cancellationToken">The cancellation token.</param> /// <param name="progress">The progress.</param> /// <returns>Task.</returns> - protected override async Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress) + public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress) { if (!_appHost.CanSelfUpdate) return; @@ -105,7 +116,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// Gets the name of the task /// </summary> /// <value>The name.</value> - public override string Name + public string Name { get { return "Check for application updates"; } } @@ -114,9 +125,18 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// Gets the description. /// </summary> /// <value>The description.</value> - public override string Description + public string Description { get { return "Downloads and installs application updates."; } } + + /// <summary> + /// Gets the category. + /// </summary> + /// <value>The category.</value> + public string Category + { + get { return "Application"; } + } } } diff --git a/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs index bc8935a86..4a6b9255c 100644 --- a/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs +++ b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs @@ -17,12 +17,10 @@ namespace MediaBrowser.Common.Implementations.Serialization /// <summary> /// Serializes to stream. /// </summary> - /// <typeparam name="T"></typeparam> /// <param name="obj">The obj.</param> /// <param name="stream">The stream.</param> /// <exception cref="System.ArgumentNullException">obj</exception> - public void SerializeToStream<T>(T obj, Stream stream) - where T : class + public void SerializeToStream(object obj, Stream stream) { if (obj == null) { @@ -40,12 +38,10 @@ namespace MediaBrowser.Common.Implementations.Serialization /// <summary> /// Serializes to file. /// </summary> - /// <typeparam name="T"></typeparam> /// <param name="obj">The obj.</param> /// <param name="file">The file.</param> /// <exception cref="System.ArgumentNullException">obj</exception> - public void SerializeToFile<T>(T obj, string file) - where T : class + public void SerializeToFile(object obj, string file) { if (obj == null) { @@ -200,12 +196,10 @@ namespace MediaBrowser.Common.Implementations.Serialization /// <summary> /// Serializes to string. /// </summary> - /// <typeparam name="T"></typeparam> /// <param name="obj">The obj.</param> /// <returns>System.String.</returns> /// <exception cref="System.ArgumentNullException">obj</exception> - public string SerializeToString<T>(T obj) - where T : class + public string SerializeToString(object obj) { if (obj == null) { @@ -218,12 +212,10 @@ namespace MediaBrowser.Common.Implementations.Serialization /// <summary> /// Serializes to bytes. /// </summary> - /// <typeparam name="T"></typeparam> /// <param name="obj">The obj.</param> /// <returns>System.Byte[][].</returns> /// <exception cref="System.ArgumentNullException">obj</exception> - public byte[] SerializeToBytes<T>(T obj) - where T : class + public byte[] SerializeToBytes(object obj) { if (obj == null) { diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config index 14eb42cac..63fd0052f 100644 --- a/MediaBrowser.Common.Implementations/packages.config +++ b/MediaBrowser.Common.Implementations/packages.config @@ -2,4 +2,5 @@ <packages> <package id="protobuf-net" version="2.0.0.621" targetFramework="net45" /> <package id="ServiceStack.Text" version="3.9.37" targetFramework="net45" /> + <package id="SimpleInjector" version="2.0.0-beta5" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/MediaBrowser.Common/Kernel/BaseKernel.cs b/MediaBrowser.Common/Kernel/BaseKernel.cs index eb5381e20..5b8da5d09 100644 --- a/MediaBrowser.Common/Kernel/BaseKernel.cs +++ b/MediaBrowser.Common/Kernel/BaseKernel.cs @@ -40,9 +40,6 @@ namespace MediaBrowser.Common.Kernel internal void OnConfigurationUpdated() { EventHelper.QueueEventIfNotNull(ConfigurationUpdated, this, EventArgs.Empty, Logger); - - // Notify connected clients - TcpManager.SendWebSocketMessage("ConfigurationUpdated", Configuration); } #endregion @@ -141,12 +138,6 @@ namespace MediaBrowser.Common.Kernel } /// <summary> - /// Gets a value indicating whether this instance is first run. - /// </summary> - /// <value><c>true</c> if this instance is first run; otherwise, <c>false</c>.</value> - public bool IsFirstRun { get; private set; } - - /// <summary> /// Gets or sets a value indicating whether this instance has changes that require the entire application to restart. /// </summary> /// <value><c>true</c> if this instance has pending application restart; otherwise, <c>false</c>.</value> @@ -177,12 +168,6 @@ namespace MediaBrowser.Common.Kernel public TcpManager TcpManager { get; private set; } /// <summary> - /// Gets the rest services. - /// </summary> - /// <value>The rest services.</value> - public IEnumerable<IRestfulService> RestServices { get; private set; } - - /// <summary> /// Gets the UDP server port number. /// This can't be configurable because then the user would have to configure their client to discover the server. /// </summary> @@ -280,19 +265,7 @@ namespace MediaBrowser.Common.Kernel /// Initializes the Kernel /// </summary> /// <returns>Task.</returns> - public Task Init() - { - IsFirstRun = !File.Exists(ApplicationPaths.SystemConfigurationFilePath); - - // Performs initializations that can be reloaded at anytime - return Reload(); - } - - /// <summary> - /// Performs initializations that can be reloaded at anytime - /// </summary> - /// <returns>Task.</returns> - public async Task Reload() + public async Task Init() { OnReloadBeginning(); @@ -312,8 +285,6 @@ namespace MediaBrowser.Common.Kernel // Set these to null so that they can be lazy loaded again Configuration = null; - Logger.Info("Version {0} initializing", ApplicationVersion); - await OnConfigurationLoaded().ConfigureAwait(false); FindParts(); @@ -348,7 +319,6 @@ namespace MediaBrowser.Common.Kernel /// </summary> protected virtual void FindParts() { - RestServices = ApplicationHost.GetExports<IRestfulService>(); WebSocketListeners = ApplicationHost.GetExports<IWebSocketListener>(); Plugins = ApplicationHost.GetExports<IPlugin>(); } @@ -426,18 +396,6 @@ namespace MediaBrowser.Common.Kernel } /// <summary> - /// Gets the current application version - /// </summary> - /// <value>The application version.</value> - public Version ApplicationVersion - { - get - { - return GetType().Assembly.GetName().Version; - } - } - - /// <summary> /// Performs the pending restart. /// </summary> /// <returns>Task.</returns> @@ -445,7 +403,9 @@ namespace MediaBrowser.Common.Kernel { if (HasPendingRestart) { - RestartApplication(); + Logger.Info("Restarting the application"); + + ApplicationHost.Restart(); } else { @@ -454,16 +414,6 @@ namespace MediaBrowser.Common.Kernel } /// <summary> - /// Restarts the application. - /// </summary> - protected void RestartApplication() - { - Logger.Info("Restarting the application"); - - ApplicationHost.Restart(); - } - - /// <summary> /// Gets the system status. /// </summary> /// <returns>SystemInfo.</returns> @@ -472,7 +422,7 @@ namespace MediaBrowser.Common.Kernel return new SystemInfo { HasPendingRestart = HasPendingRestart, - Version = ApplicationVersion.ToString(), + Version = ApplicationHost.ApplicationVersion.ToString(), IsNetworkDeployed = ApplicationHost.CanSelfUpdate, WebSocketPortNumber = TcpManager.WebSocketPortNumber, SupportsNativeWebSocket = TcpManager.SupportsNativeWebSocket, diff --git a/MediaBrowser.Common/Kernel/IApplicationHost.cs b/MediaBrowser.Common/Kernel/IApplicationHost.cs index 4b564581b..af9b039bc 100644 --- a/MediaBrowser.Common/Kernel/IApplicationHost.cs +++ b/MediaBrowser.Common/Kernel/IApplicationHost.cs @@ -22,6 +22,12 @@ namespace MediaBrowser.Common.Kernel void ReloadLogger(); /// <summary> + /// Gets the application version. + /// </summary> + /// <value>The application version.</value> + Version ApplicationVersion { get; } + + /// <summary> /// Gets the log file path. /// </summary> /// <value>The log file path.</value> @@ -34,10 +40,16 @@ namespace MediaBrowser.Common.Kernel bool CanSelfUpdate { get; } /// <summary> + /// Gets a value indicating whether this instance is first run. + /// </summary> + /// <value><c>true</c> if this instance is first run; otherwise, <c>false</c>.</value> + bool IsFirstRun { get; } + + /// <summary> /// Gets the failed assemblies. /// </summary> /// <value>The failed assemblies.</value> - IEnumerable<string> FailedAssemblies { get; } + List<string> FailedAssemblies { get; } /// <summary> /// Gets all concrete types. @@ -73,34 +85,6 @@ namespace MediaBrowser.Common.Kernel object CreateInstance(Type type); /// <summary> - /// Registers a service that other classes can use as a dependancy. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <param name="obj">The obj.</param> - void RegisterSingleInstance<T>(T obj) where T : class; - - /// <summary> - /// Registers the single instance. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <param name="func">The func.</param> - void RegisterSingleInstance<T>(Func<T> func) where T : class; - - /// <summary> - /// Registers the specified func. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <param name="func">The func.</param> - void Register<T>(Func<T> func) where T : class; - - /// <summary> - /// Registers the specified service type. - /// </summary> - /// <param name="serviceType">Type of the service.</param> - /// <param name="implementation">Type of the implementation.</param> - void Register(Type serviceType, Type implementation); - - /// <summary> /// Resolves this instance. /// </summary> /// <typeparam name="T"></typeparam> diff --git a/MediaBrowser.Common/Kernel/IKernel.cs b/MediaBrowser.Common/Kernel/IKernel.cs index fb629a24d..06c2e7b64 100644 --- a/MediaBrowser.Common/Kernel/IKernel.cs +++ b/MediaBrowser.Common/Kernel/IKernel.cs @@ -38,12 +38,6 @@ namespace MediaBrowser.Common.Kernel Task Init(); /// <summary> - /// Reloads this instance. - /// </summary> - /// <returns>Task.</returns> - Task Reload(); - - /// <summary> /// Gets or sets a value indicating whether this instance has pending kernel reload. /// </summary> /// <value><c>true</c> if this instance has pending kernel reload; otherwise, <c>false</c>.</value> @@ -107,12 +101,6 @@ namespace MediaBrowser.Common.Kernel string HttpServerUrlPrefix { get; } /// <summary> - /// Gets a value indicating whether this instance is first run. - /// </summary> - /// <value><c>true</c> if this instance is first run; otherwise, <c>false</c>.</value> - bool IsFirstRun { get; } - - /// <summary> /// Gets the TCP manager. /// </summary> /// <value>The TCP manager.</value> @@ -140,12 +128,6 @@ namespace MediaBrowser.Common.Kernel event EventHandler<EventArgs> ConfigurationUpdated; /// <summary> - /// Gets the rest services. - /// </summary> - /// <value>The rest services.</value> - IEnumerable<IRestfulService> RestServices { get; } - - /// <summary> /// Notifies the pending restart. /// </summary> void NotifyPendingRestart(); diff --git a/MediaBrowser.Common/Kernel/TcpManager.cs b/MediaBrowser.Common/Kernel/TcpManager.cs index 1c76b42f9..2dfed501a 100644 --- a/MediaBrowser.Common/Kernel/TcpManager.cs +++ b/MediaBrowser.Common/Kernel/TcpManager.cs @@ -39,7 +39,7 @@ namespace MediaBrowser.Common.Kernel /// </summary> /// <value>The json serializer.</value> private readonly IJsonSerializer _jsonSerializer; - + /// <summary> /// This subscribes to HttpListener requests and finds the appropriate BaseHandler to process it /// </summary> @@ -133,7 +133,7 @@ namespace MediaBrowser.Common.Kernel _applicationHost = applicationHost; _networkManager = networkManager; - if (kernel.IsFirstRun) + if (applicationHost.IsFirstRun) { RegisterServerWithAdministratorAccess(); } @@ -215,7 +215,7 @@ namespace MediaBrowser.Common.Kernel /// <param name="e">The <see cref="WebSocketConnectEventArgs" /> instance containing the event data.</param> void HttpServer_WebSocketConnected(object sender, WebSocketConnectEventArgs e) { - var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, ProcessWebSocketMessageReceived, _jsonSerializer, _logger); + var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger) { OnReceive = ProcessWebSocketMessageReceived }; _webSocketConnections.Add(connection); } diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index bc3678a5e..333c20beb 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -95,8 +95,6 @@ <Compile Include="Kernel\IApplicationHost.cs" /> <Compile Include="Kernel\IKernel.cs" /> <Compile Include="Kernel\TcpManager.cs" /> - <Compile Include="Net\BaseRestService.cs" /> - <Compile Include="Net\Handlers\BaseActionHandler.cs" /> <Compile Include="Net\Handlers\IHttpServerHandler.cs" /> <Compile Include="Net\Handlers\StaticFileHandler.cs" /> <Compile Include="Net\IHttpClient.cs" /> @@ -122,6 +120,8 @@ <DesignTime>True</DesignTime> <DependentUpon>Resources.resx</DependentUpon> </Compile> + <Compile Include="ScheduledTasks\IScheduledTask.cs" /> + <Compile Include="ScheduledTasks\IScheduledTaskWorker.cs" /> <Compile Include="ScheduledTasks\ITaskManager.cs" /> <Compile Include="ScheduledTasks\ITaskTrigger.cs" /> <Compile Include="ScheduledTasks\ScheduledTaskHelpers.cs" /> @@ -130,13 +130,10 @@ <Compile Include="Kernel\BaseKernel.cs" /> <Compile Include="Kernel\KernelContext.cs" /> <Compile Include="Net\Handlers\BaseHandler.cs" /> - <Compile Include="Net\Handlers\BaseSerializationHandler.cs" /> <Compile Include="Plugins\BasePlugin.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> - <Compile Include="ScheduledTasks\BaseScheduledTask.cs" /> <Compile Include="ScheduledTasks\DailyTrigger.cs" /> <Compile Include="ScheduledTasks\IntervalTrigger.cs" /> - <Compile Include="ScheduledTasks\IScheduledTask.cs" /> <Compile Include="ScheduledTasks\WeeklyTrigger.cs" /> </ItemGroup> <ItemGroup> diff --git a/MediaBrowser.Common/Net/Handlers/BaseActionHandler.cs b/MediaBrowser.Common/Net/Handlers/BaseActionHandler.cs deleted file mode 100644 index 72df88519..000000000 --- a/MediaBrowser.Common/Net/Handlers/BaseActionHandler.cs +++ /dev/null @@ -1,31 +0,0 @@ -using MediaBrowser.Common.Kernel; -using MediaBrowser.Model.Entities; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Net.Handlers -{ - /// <summary> - /// Class BaseActionHandler - /// </summary> - /// <typeparam name="TKernelType">The type of the T kernel type.</typeparam> - public abstract class BaseActionHandler<TKernelType> : BaseSerializationHandler<TKernelType, EmptyRequestResult> - where TKernelType : IKernel - { - /// <summary> - /// Gets the object to serialize. - /// </summary> - /// <returns>Task{EmptyRequestResult}.</returns> - protected override async Task<EmptyRequestResult> GetObjectToSerialize() - { - await ExecuteAction(); - - return new EmptyRequestResult(); - } - - /// <summary> - /// Performs the action. - /// </summary> - /// <returns>Task.</returns> - protected abstract Task ExecuteAction(); - } -} diff --git a/MediaBrowser.Common/Net/Handlers/BaseSerializationHandler.cs b/MediaBrowser.Common/Net/Handlers/BaseSerializationHandler.cs deleted file mode 100644 index a00152d78..000000000 --- a/MediaBrowser.Common/Net/Handlers/BaseSerializationHandler.cs +++ /dev/null @@ -1,133 +0,0 @@ -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Kernel; -using System; -using System.IO; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Net.Handlers -{ - /// <summary> - /// Class BaseSerializationHandler - /// </summary> - /// <typeparam name="TKernelType">The type of the T kernel type.</typeparam> - /// <typeparam name="T"></typeparam> - public abstract class BaseSerializationHandler<TKernelType, T> : BaseHandler<TKernelType> - where TKernelType : IKernel - where T : class - { - /// <summary> - /// Gets the serialization format. - /// </summary> - /// <value>The serialization format.</value> - public SerializationFormat SerializationFormat - { - get - { - var format = QueryString["dataformat"]; - - if (string.IsNullOrEmpty(format)) - { - return SerializationFormat.Json; - } - - return (SerializationFormat)Enum.Parse(typeof(SerializationFormat), format, true); - } - } - - /// <summary> - /// Gets the type of the content. - /// </summary> - /// <value>The type of the content.</value> - protected string ContentType - { - get - { - switch (SerializationFormat) - { - case SerializationFormat.Protobuf: - return "application/x-protobuf"; - default: - return MimeTypes.JsonMimeType; - } - } - } - - /// <summary> - /// Gets the response info. - /// </summary> - /// <returns>Task{ResponseInfo}.</returns> - protected override Task<ResponseInfo> GetResponseInfo() - { - return Task.FromResult(new ResponseInfo - { - ContentType = ContentType - }); - } - - /// <summary> - /// Called when [processing request]. - /// </summary> - /// <param name="responseInfo">The response info.</param> - /// <returns>Task.</returns> - protected override async Task OnProcessingRequest(ResponseInfo responseInfo) - { - _objectToSerialize = await GetObjectToSerialize().ConfigureAwait(false); - - if (_objectToSerialize == null) - { - throw new ResourceNotFoundException(); - } - - await base.OnProcessingRequest(responseInfo).ConfigureAwait(false); - } - - /// <summary> - /// The _object to serialize - /// </summary> - private T _objectToSerialize; - - /// <summary> - /// Gets the object to serialize. - /// </summary> - /// <returns>Task{`0}.</returns> - protected abstract Task<T> GetObjectToSerialize(); - - /// <summary> - /// Writes the response to output stream. - /// </summary> - /// <param name="stream">The stream.</param> - /// <param name="responseInfo">The response info.</param> - /// <param name="contentLength">Length of the content.</param> - /// <returns>Task.</returns> - protected override Task WriteResponseToOutputStream(Stream stream, ResponseInfo responseInfo, long? contentLength) - { - return Task.Run(() => - { - //switch (SerializationFormat) - //{ - // case SerializationFormat.Protobuf: - // Kernel.ProtobufSerializer.SerializeToStream(_objectToSerialize, stream); - // break; - // default: - // JsonSerializer.SerializeToStream(_objectToSerialize, stream); - // break; - //} - }); - } - } - - /// <summary> - /// Enum SerializationFormat - /// </summary> - public enum SerializationFormat - { - /// <summary> - /// The json - /// </summary> - Json, - /// <summary> - /// The protobuf - /// </summary> - Protobuf - } -} diff --git a/MediaBrowser.Common/Net/IHttpClient.cs b/MediaBrowser.Common/Net/IHttpClient.cs index ef0dd69b7..d02f08572 100644 --- a/MediaBrowser.Common/Net/IHttpClient.cs +++ b/MediaBrowser.Common/Net/IHttpClient.cs @@ -6,6 +6,9 @@ using System.Threading.Tasks; namespace MediaBrowser.Common.Net { + /// <summary> + /// Interface IHttpClient + /// </summary> public interface IHttpClient : IDisposable { /// <summary> @@ -52,10 +55,5 @@ namespace MediaBrowser.Common.Net /// <returns>Task{MemoryStream}.</returns> /// <exception cref="MediaBrowser.Model.Net.HttpException"></exception> Task<MemoryStream> GetMemoryStream(string url, SemaphoreSlim resourcePool, CancellationToken cancellationToken); - - /// <summary> - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// </summary> - void Dispose(); } }
\ No newline at end of file diff --git a/MediaBrowser.Common/Net/IHttpServer.cs b/MediaBrowser.Common/Net/IHttpServer.cs index a640fb262..45da18e1b 100644 --- a/MediaBrowser.Common/Net/IHttpServer.cs +++ b/MediaBrowser.Common/Net/IHttpServer.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace MediaBrowser.Common.Net { @@ -40,5 +41,10 @@ namespace MediaBrowser.Common.Net /// Occurs when [web socket connected]. /// </summary> event EventHandler<WebSocketConnectEventArgs> WebSocketConnected; + + /// <summary> + /// Inits this instance. + /// </summary> + void Init(IEnumerable<IRestfulService> services); } }
\ No newline at end of file diff --git a/MediaBrowser.Common/Net/IRestfulService.cs b/MediaBrowser.Common/Net/IRestfulService.cs index 7fc6bb61e..36055cd8a 100644 --- a/MediaBrowser.Common/Net/IRestfulService.cs +++ b/MediaBrowser.Common/Net/IRestfulService.cs @@ -1,5 +1,4 @@ using ServiceStack.ServiceHost; -using ServiceStack.WebHost.Endpoints; using System; namespace MediaBrowser.Common.Net @@ -9,6 +8,5 @@ namespace MediaBrowser.Common.Net /// </summary> public interface IRestfulService : IService, IRequiresRequestContext, IDisposable { - void Configure(IAppHost appHost); } } diff --git a/MediaBrowser.Common/Net/WebSocketConnection.cs b/MediaBrowser.Common/Net/WebSocketConnection.cs index 36d649e3b..1ad0e8f06 100644 --- a/MediaBrowser.Common/Net/WebSocketConnection.cs +++ b/MediaBrowser.Common/Net/WebSocketConnection.cs @@ -41,17 +41,22 @@ namespace MediaBrowser.Common.Net /// The _json serializer /// </summary> private readonly IJsonSerializer _jsonSerializer; - + + /// <summary> + /// Gets or sets the receive action. + /// </summary> + /// <value>The receive action.</value> + public Action<WebSocketMessageInfo> OnReceive { get; set; } + /// <summary> /// Initializes a new instance of the <see cref="WebSocketConnection" /> class. /// </summary> /// <param name="socket">The socket.</param> /// <param name="remoteEndPoint">The remote end point.</param> - /// <param name="receiveAction">The receive action.</param> /// <param name="jsonSerializer">The json serializer.</param> /// <param name="logger">The logger.</param> /// <exception cref="System.ArgumentNullException">socket</exception> - public WebSocketConnection(IWebSocket socket, string remoteEndPoint, Action<WebSocketMessageInfo> receiveAction, IJsonSerializer jsonSerializer, ILogger logger) + public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger) { if (socket == null) { @@ -61,10 +66,6 @@ namespace MediaBrowser.Common.Net { throw new ArgumentNullException("remoteEndPoint"); } - if (receiveAction == null) - { - throw new ArgumentNullException("receiveAction"); - } if (jsonSerializer == null) { throw new ArgumentNullException("jsonSerializer"); @@ -76,7 +77,7 @@ namespace MediaBrowser.Common.Net _jsonSerializer = jsonSerializer; _socket = socket; - _socket.OnReceiveDelegate = info => OnReceive(info, receiveAction); + _socket.OnReceiveDelegate = OnReceiveInternal; RemoteEndPoint = remoteEndPoint; _logger = logger; } @@ -85,21 +86,24 @@ namespace MediaBrowser.Common.Net /// Called when [receive]. /// </summary> /// <param name="bytes">The bytes.</param> - /// <param name="callback">The callback.</param> - private void OnReceive(byte[] bytes, Action<WebSocketMessageInfo> callback) + private void OnReceiveInternal(byte[] bytes) { + if (OnReceive == null) + { + return; + } try { WebSocketMessageInfo info; using (var memoryStream = new MemoryStream(bytes)) { - info = _jsonSerializer.DeserializeFromStream<WebSocketMessageInfo>(memoryStream); + info = (WebSocketMessageInfo)_jsonSerializer.DeserializeFromStream(memoryStream, typeof(WebSocketMessageInfo)); } info.Connection = this; - callback(info); + OnReceive(info); } catch (Exception ex) { diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs index dad3867fc..72c83a5ce 100644 --- a/MediaBrowser.Common/Plugins/BasePlugin.cs +++ b/MediaBrowser.Common/Plugins/BasePlugin.cs @@ -1,12 +1,12 @@ using MediaBrowser.Common.Kernel; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Plugins; +using MediaBrowser.Model.Serialization; using System; using System.IO; using System.Reflection; using System.Runtime.InteropServices; using System.Threading; -using MediaBrowser.Model.Serialization; namespace MediaBrowser.Common.Plugins { @@ -393,9 +393,6 @@ namespace MediaBrowser.Common.Plugins { XmlSerializer.SerializeToFile(Configuration, ConfigurationFilePath); } - - // Notify connected UI's - Kernel.TcpManager.SendWebSocketMessage("PluginConfigurationUpdated-" + Name, Configuration); } /// <summary> diff --git a/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs b/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs index 6f3a3857f..351e96c7d 100644 --- a/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs +++ b/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs @@ -1,40 +1,16 @@ -using MediaBrowser.Model.Tasks; -using System; +using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Common.ScheduledTasks { /// <summary> - /// Interface IScheduledTask + /// Interface IScheduledTaskWorker /// </summary> - public interface IScheduledTask : IDisposable + public interface IScheduledTask { /// <summary> - /// Gets the triggers. - /// </summary> - /// <value>The triggers.</value> - IEnumerable<ITaskTrigger> Triggers { get; set; } - - /// <summary> - /// Gets the last execution result. - /// </summary> - /// <value>The last execution result.</value> - TaskResult LastExecutionResult { get; } - - /// <summary> - /// Gets the state. - /// </summary> - /// <value>The state.</value> - TaskState State { get; } - - /// <summary> - /// Gets the current progress. - /// </summary> - /// <value>The current progress.</value> - double? CurrentProgress { get; } - - /// <summary> /// Gets the name of the task /// </summary> /// <value>The name.</value> @@ -53,28 +29,12 @@ namespace MediaBrowser.Common.ScheduledTasks string Category { get; } /// <summary> - /// Gets the unique id. - /// </summary> - /// <value>The unique id.</value> - Guid Id { get; } - - /// <summary> /// Executes the task /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="progress">The progress.</param> /// <returns>Task.</returns> - /// <exception cref="System.InvalidOperationException">Cannot execute a Task that is already running</exception> - Task Execute(); - - /// <summary> - /// Stops the task if it is currently executing - /// </summary> - /// <exception cref="System.InvalidOperationException">Cannot cancel a Task unless it is in the Running state.</exception> - void Cancel(); - - /// <summary> - /// Cancels if running. - /// </summary> - void CancelIfRunning(); + Task Execute(CancellationToken cancellationToken, IProgress<double> progress); /// <summary> /// Gets the default triggers. @@ -82,4 +42,4 @@ namespace MediaBrowser.Common.ScheduledTasks /// <returns>IEnumerable{BaseTaskTrigger}.</returns> IEnumerable<ITaskTrigger> GetDefaultTriggers(); } -}
\ No newline at end of file +} diff --git a/MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs b/MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs new file mode 100644 index 000000000..31cb4bcb8 --- /dev/null +++ b/MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs @@ -0,0 +1,86 @@ +using MediaBrowser.Model.Tasks; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace MediaBrowser.Common.ScheduledTasks +{ + /// <summary> + /// Interface IScheduledTaskWorker + /// </summary> + public interface IScheduledTaskWorker : IDisposable + { + /// <summary> + /// Gets or sets the scheduled task. + /// </summary> + /// <value>The scheduled task.</value> + IScheduledTask ScheduledTask { get; } + + /// <summary> + /// Gets the last execution result. + /// </summary> + /// <value>The last execution result.</value> + TaskResult LastExecutionResult { get; } + + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + string Name { get; } + + /// <summary> + /// Gets the description. + /// </summary> + /// <value>The description.</value> + string Description { get; } + + /// <summary> + /// Gets the category. + /// </summary> + /// <value>The category.</value> + string Category { get; } + + /// <summary> + /// Gets the state. + /// </summary> + /// <value>The state.</value> + TaskState State { get; } + + /// <summary> + /// Gets the current progress. + /// </summary> + /// <value>The current progress.</value> + double? CurrentProgress { get; } + + /// <summary> + /// Gets the triggers that define when the task will run + /// </summary> + /// <value>The triggers.</value> + /// <exception cref="System.ArgumentNullException">value</exception> + IEnumerable<ITaskTrigger> Triggers { get; set; } + + /// <summary> + /// Gets the unique id. + /// </summary> + /// <value>The unique id.</value> + Guid Id { get; } + + /// <summary> + /// Executes the task + /// </summary> + /// <returns>Task.</returns> + /// <exception cref="System.InvalidOperationException">Cannot execute a Task that is already running</exception> + Task Execute(); + + /// <summary> + /// Stops the task if it is currently executing + /// </summary> + /// <exception cref="System.InvalidOperationException">Cannot cancel a Task unless it is in the Running state.</exception> + void Cancel(); + + /// <summary> + /// Cancels if running. + /// </summary> + void CancelIfRunning(); + } +}
\ No newline at end of file diff --git a/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs b/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs index 42d7020e6..d06f1f194 100644 --- a/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs +++ b/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Model.Tasks; -using System; +using System; using System.Collections.Generic; namespace MediaBrowser.Common.ScheduledTasks @@ -10,7 +9,7 @@ namespace MediaBrowser.Common.ScheduledTasks /// Gets the list of Scheduled Tasks /// </summary> /// <value>The scheduled tasks.</value> - IScheduledTask[] ScheduledTasks { get; } + IScheduledTaskWorker[] ScheduledTasks { get; } /// <summary> /// Cancels if running and queue. @@ -37,35 +36,5 @@ namespace MediaBrowser.Common.ScheduledTasks /// </summary> /// <param name="tasks">The tasks.</param> void AddTasks(IEnumerable<IScheduledTask> tasks); - - /// <summary> - /// Called when [task completed]. - /// </summary> - /// <param name="task">The task.</param> - /// <param name="startTime">The start time.</param> - /// <param name="endTime">The end time.</param> - /// <param name="status">The status.</param> - void OnTaskCompleted(IScheduledTask task, DateTime startTime, DateTime endTime, TaskCompletionStatus status); - - /// <summary> - /// Gets the last execution result. - /// </summary> - /// <param name="task">The task.</param> - /// <returns>TaskResult.</returns> - TaskResult GetLastExecutionResult(IScheduledTask task); - - /// <summary> - /// Loads the triggers. - /// </summary> - /// <param name="task">The task.</param> - /// <returns>IEnumerable{BaseTaskTrigger}.</returns> - IEnumerable<ITaskTrigger> LoadTriggers(IScheduledTask task); - - /// <summary> - /// Saves the triggers. - /// </summary> - /// <param name="task">The task.</param> - /// <param name="triggers">The triggers.</param> - void SaveTriggers(IScheduledTask task, IEnumerable<ITaskTrigger> triggers); } }
\ No newline at end of file diff --git a/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs b/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs index 2c3d21a4b..ebfc94591 100644 --- a/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs +++ b/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Common.ScheduledTasks /// </summary> /// <param name="task">The task.</param> /// <returns>TaskInfo.</returns> - public static TaskInfo GetTaskInfo(IScheduledTask task) + public static TaskInfo GetTaskInfo(IScheduledTaskWorker task) { return new TaskInfo { diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 1e901055e..ff2bcb213 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -132,7 +132,6 @@ <Compile Include="Persistence\IRepository.cs" /> <Compile Include="Persistence\IUserDataRepository.cs" /> <Compile Include="Persistence\IUserRepository.cs" /> - <Compile Include="Persistence\TypeMapper.cs" /> <Compile Include="Playback\IIntroProvider.cs" /> <Compile Include="Plugins\IPluginConfigurationPage.cs" /> <Compile Include="Plugins\PluginSecurityManager.cs" /> @@ -179,10 +178,7 @@ <Compile Include="Resolvers\TV\SeriesResolver.cs" /> <Compile Include="Resolvers\TV\TVUtils.cs" /> <Compile Include="Library\ResourcePool.cs" /> - <Compile Include="ScheduledTasks\ChapterImagesTask.cs" /> - <Compile Include="ScheduledTasks\ImageCleanupTask.cs" /> <Compile Include="ScheduledTasks\PeopleValidationTask.cs" /> - <Compile Include="ScheduledTasks\PluginUpdateTask.cs" /> <Compile Include="ScheduledTasks\RefreshMediaLibraryTask.cs" /> <Compile Include="Library\ItemResolveArgs.cs" /> <Compile Include="IO\DirectoryWatchers.cs" /> diff --git a/MediaBrowser.Controller/Plugins/PluginSecurityManager.cs b/MediaBrowser.Controller/Plugins/PluginSecurityManager.cs index a08eb457d..db3f20ee3 100644 --- a/MediaBrowser.Controller/Plugins/PluginSecurityManager.cs +++ b/MediaBrowser.Controller/Plugins/PluginSecurityManager.cs @@ -1,4 +1,5 @@ -using Mediabrowser.Model.Entities; +using MediaBrowser.Model.Serialization; +using Mediabrowser.Model.Entities; using Mediabrowser.PluginSecurity; using MediaBrowser.Common.Kernel; using MediaBrowser.Common.Net; @@ -39,10 +40,8 @@ namespace MediaBrowser.Controller.Plugins } } - /// <summary> - /// The _network manager - /// </summary> - private INetworkManager _networkManager; + private IHttpClient _httpClient; + private IJsonSerializer _jsonSerializer; /// <summary> /// The _kernel @@ -53,21 +52,22 @@ namespace MediaBrowser.Controller.Plugins /// Initializes a new instance of the <see cref="PluginSecurityManager" /> class. /// </summary> /// <param name="kernel">The kernel.</param> - /// <param name="networkManager">The network manager.</param> - public PluginSecurityManager(IKernel kernel, INetworkManager networkManager) + public PluginSecurityManager(IKernel kernel, IHttpClient httpClient, IJsonSerializer jsonSerializer, IApplicationPaths appPaths) { if (kernel == null) { throw new ArgumentNullException("kernel"); } - if (networkManager == null) + if (httpClient == null) { - throw new ArgumentNullException("networkManager"); + throw new ArgumentNullException("httpClient"); } _kernel = kernel; - _networkManager = networkManager; + _httpClient = httpClient; + _jsonSerializer = jsonSerializer; + MBRegistration.Init(appPaths); } /// <summary> @@ -78,7 +78,7 @@ namespace MediaBrowser.Controller.Plugins /// <returns>Task{MBRegistrationRecord}.</returns> public async Task<MBRegistrationRecord> GetRegistrationStatus(string feature, string mb2Equivalent = null) { - return await MBRegistration.GetRegistrationStatus(feature, mb2Equivalent).ConfigureAwait(false); + return await MBRegistration.GetRegistrationStatus(_httpClient, _jsonSerializer, feature, mb2Equivalent).ConfigureAwait(false); } /// <summary> diff --git a/MediaBrowser.Controller/ScheduledTasks/PeopleValidationTask.cs b/MediaBrowser.Controller/ScheduledTasks/PeopleValidationTask.cs index 595de684d..4448b7439 100644 --- a/MediaBrowser.Controller/ScheduledTasks/PeopleValidationTask.cs +++ b/MediaBrowser.Controller/ScheduledTasks/PeopleValidationTask.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.ScheduledTasks; -using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; using System.Threading; @@ -10,23 +9,24 @@ namespace MediaBrowser.Controller.ScheduledTasks /// <summary> /// Class PeopleValidationTask /// </summary> - public class PeopleValidationTask : BaseScheduledTask<Kernel> + public class PeopleValidationTask : IScheduledTask { + private readonly Kernel _kernel; + /// <summary> /// Initializes a new instance of the <see cref="PeopleValidationTask" /> class. /// </summary> /// <param name="kernel">The kernel.</param> - /// <param name="logger"></param> - public PeopleValidationTask(Kernel kernel, ITaskManager taskManager, ILogger logger) - : base(kernel, taskManager, logger) + public PeopleValidationTask(Kernel kernel) { + _kernel = kernel; } /// <summary> /// Creates the triggers that define when the task will run /// </summary> /// <returns>IEnumerable{BaseTaskTrigger}.</returns> - public override IEnumerable<ITaskTrigger> GetDefaultTriggers() + public IEnumerable<ITaskTrigger> GetDefaultTriggers() { return new ITaskTrigger[] { @@ -42,16 +42,16 @@ namespace MediaBrowser.Controller.ScheduledTasks /// <param name="cancellationToken">The cancellation token.</param> /// <param name="progress">The progress.</param> /// <returns>Task.</returns> - protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress) + public Task Execute(CancellationToken cancellationToken, IProgress<double> progress) { - return Kernel.LibraryManager.ValidatePeople(cancellationToken, progress); + return _kernel.LibraryManager.ValidatePeople(cancellationToken, progress); } /// <summary> /// Gets the name of the task /// </summary> /// <value>The name.</value> - public override string Name + public string Name { get { return "Refresh people"; } } @@ -60,7 +60,7 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the description. /// </summary> /// <value>The description.</value> - public override string Description + public string Description { get { return "Updates metadata for actors, artists and directors in your media library."; } } @@ -69,7 +69,7 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the category. /// </summary> /// <value>The category.</value> - public override string Category + public string Category { get { diff --git a/MediaBrowser.Controller/ScheduledTasks/RefreshMediaLibraryTask.cs b/MediaBrowser.Controller/ScheduledTasks/RefreshMediaLibraryTask.cs index 104b432f4..c5e36afb8 100644 --- a/MediaBrowser.Controller/ScheduledTasks/RefreshMediaLibraryTask.cs +++ b/MediaBrowser.Controller/ScheduledTasks/RefreshMediaLibraryTask.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.ScheduledTasks; -using MediaBrowser.Model.Logging; using MediaBrowser.Model.Tasks; using System; using System.Collections.Generic; @@ -11,23 +10,27 @@ namespace MediaBrowser.Controller.ScheduledTasks /// <summary> /// Class RefreshMediaLibraryTask /// </summary> - public class RefreshMediaLibraryTask : BaseScheduledTask<Kernel> + public class RefreshMediaLibraryTask : IScheduledTask { /// <summary> + /// The _kernel + /// </summary> + private readonly Kernel _kernel; + + /// <summary> /// Initializes a new instance of the <see cref="RefreshMediaLibraryTask" /> class. /// </summary> /// <param name="kernel">The kernel.</param> - /// <param name="logger"></param> - public RefreshMediaLibraryTask(Kernel kernel, ITaskManager taskManager, ILogger logger) - : base(kernel, taskManager, logger) + public RefreshMediaLibraryTask(Kernel kernel) { + _kernel = kernel; } /// <summary> /// Gets the default triggers. /// </summary> /// <returns>IEnumerable{BaseTaskTrigger}.</returns> - public override IEnumerable<ITaskTrigger> GetDefaultTriggers() + public IEnumerable<ITaskTrigger> GetDefaultTriggers() { return new ITaskTrigger[] { @@ -45,20 +48,20 @@ namespace MediaBrowser.Controller.ScheduledTasks /// <param name="cancellationToken">The cancellation token.</param> /// <param name="progress">The progress.</param> /// <returns>Task.</returns> - protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress) + public Task Execute(CancellationToken cancellationToken, IProgress<double> progress) { cancellationToken.ThrowIfCancellationRequested(); progress.Report(0); - return Kernel.LibraryManager.ValidateMediaLibrary(progress, cancellationToken); + return _kernel.LibraryManager.ValidateMediaLibrary(progress, cancellationToken); } /// <summary> /// Gets the name. /// </summary> /// <value>The name.</value> - public override string Name + public string Name { get { return "Scan media library"; } } @@ -67,7 +70,7 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the description. /// </summary> /// <value>The description.</value> - public override string Description + public string Description { get { return "Scans your media library and refreshes metatata based on configuration."; } } @@ -76,7 +79,7 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the category. /// </summary> /// <value>The category.</value> - public override string Category + public string Category { get { diff --git a/MediaBrowser.Controller/Updates/InstallationManager.cs b/MediaBrowser.Controller/Updates/InstallationManager.cs index 15d626b2f..8751bd427 100644 --- a/MediaBrowser.Controller/Updates/InstallationManager.cs +++ b/MediaBrowser.Controller/Updates/InstallationManager.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Events; +using MediaBrowser.Common.Kernel; using MediaBrowser.Common.Net; using MediaBrowser.Common.Plugins; using MediaBrowser.Common.Progress; @@ -120,6 +121,12 @@ namespace MediaBrowser.Controller.Updates protected IHttpClient HttpClient { get; private set; } /// <summary> + /// Gets the application host. + /// </summary> + /// <value>The application host.</value> + protected IApplicationHost ApplicationHost { get; private set; } + + /// <summary> /// Initializes a new instance of the <see cref="InstallationManager" /> class. /// </summary> /// <param name="kernel">The kernel.</param> @@ -128,8 +135,9 @@ namespace MediaBrowser.Controller.Updates /// <param name="networkManager">The network manager.</param> /// <param name="jsonSerializer">The json serializer.</param> /// <param name="logger">The logger.</param> + /// <param name="appHost">The app host.</param> /// <exception cref="System.ArgumentNullException">zipClient</exception> - public InstallationManager(Kernel kernel, IHttpClient httpClient, IZipClient zipClient, INetworkManager networkManager, IJsonSerializer jsonSerializer, ILogger logger) + public InstallationManager(Kernel kernel, IHttpClient httpClient, IZipClient zipClient, INetworkManager networkManager, IJsonSerializer jsonSerializer, ILogger logger, IApplicationHost appHost) : base(kernel) { if (zipClient == null) @@ -155,6 +163,7 @@ namespace MediaBrowser.Controller.Updates JsonSerializer = jsonSerializer; HttpClient = httpClient; + ApplicationHost = appHost; _networkManager = networkManager; _logger = logger; ZipClient = zipClient; @@ -276,7 +285,7 @@ namespace MediaBrowser.Controller.Updates return package.versions .OrderByDescending(v => v.version) - .FirstOrDefault(v => v.classification <= classification && IsPackageVersionUpToDate(v, Kernel.ApplicationVersion)); + .FirstOrDefault(v => v.classification <= classification && IsPackageVersionUpToDate(v, ApplicationHost.ApplicationVersion)); } /// <summary> diff --git a/MediaBrowser.Model/Serialization/IJsonSerializer.cs b/MediaBrowser.Model/Serialization/IJsonSerializer.cs index 056389d2e..77a14c1e5 100644 --- a/MediaBrowser.Model/Serialization/IJsonSerializer.cs +++ b/MediaBrowser.Model/Serialization/IJsonSerializer.cs @@ -8,22 +8,18 @@ namespace MediaBrowser.Model.Serialization /// <summary> /// Serializes to stream. /// </summary> - /// <typeparam name="T"></typeparam> /// <param name="obj">The obj.</param> /// <param name="stream">The stream.</param> /// <exception cref="System.ArgumentNullException">obj</exception> - void SerializeToStream<T>(T obj, Stream stream) - where T : class; + void SerializeToStream(object obj, Stream stream); /// <summary> /// Serializes to file. /// </summary> - /// <typeparam name="T"></typeparam> /// <param name="obj">The obj.</param> /// <param name="file">The file.</param> /// <exception cref="System.ArgumentNullException">obj</exception> - void SerializeToFile<T>(T obj, string file) - where T : class; + void SerializeToFile(object obj, string file); /// <summary> /// Deserializes from file. @@ -83,21 +79,17 @@ namespace MediaBrowser.Model.Serialization /// <summary> /// Serializes to string. /// </summary> - /// <typeparam name="T"></typeparam> /// <param name="obj">The obj.</param> /// <returns>System.String.</returns> /// <exception cref="System.ArgumentNullException">obj</exception> - string SerializeToString<T>(T obj) - where T : class; + string SerializeToString(object obj); /// <summary> /// Serializes to bytes. /// </summary> - /// <typeparam name="T"></typeparam> /// <param name="obj">The obj.</param> /// <returns>System.Byte[][].</returns> /// <exception cref="System.ArgumentNullException">obj</exception> - byte[] SerializeToBytes<T>(T obj) - where T : class; + byte[] SerializeToBytes(object obj); } }
\ No newline at end of file diff --git a/MediaBrowser.Common/Net/BaseRestService.cs b/MediaBrowser.Networking/HttpServer/BaseRestService.cs index a7e95fca2..d499f0781 100644 --- a/MediaBrowser.Common/Net/BaseRestService.cs +++ b/MediaBrowser.Networking/HttpServer/BaseRestService.cs @@ -1,6 +1,7 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Common.Kernel; +using MediaBrowser.Common.Net; using MediaBrowser.Model.Logging; using ServiceStack.Common; using ServiceStack.Common.Web; @@ -13,8 +14,10 @@ using System.IO; using System.Linq; using System.Net; using System.Threading.Tasks; +using MimeTypes = MediaBrowser.Common.Net.MimeTypes; +using StreamWriter = MediaBrowser.Common.Net.StreamWriter; -namespace MediaBrowser.Common.Net +namespace MediaBrowser.Networking.HttpServer { /// <summary> /// Class BaseRestService @@ -46,14 +49,6 @@ namespace MediaBrowser.Common.Net } /// <summary> - /// Adds the routes. - /// </summary> - /// <param name="appHost">The app host.</param> - public virtual void Configure(IAppHost appHost) - { - } - - /// <summary> /// To the optimized result. /// </summary> /// <typeparam name="T"></typeparam> diff --git a/MediaBrowser.Networking/HttpServer/HttpServer.cs b/MediaBrowser.Networking/HttpServer/HttpServer.cs index b6250527d..08a6b3561 100644 --- a/MediaBrowser.Networking/HttpServer/HttpServer.cs +++ b/MediaBrowser.Networking/HttpServer/HttpServer.cs @@ -1,4 +1,3 @@ -using System.Net.WebSockets; using Funq; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Kernel; @@ -16,10 +15,12 @@ using ServiceStack.WebHost.Endpoints; using ServiceStack.WebHost.Endpoints.Extensions; using ServiceStack.WebHost.Endpoints.Support; using System; +using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Net; +using System.Net.WebSockets; using System.Reactive.Linq; using System.Reflection; using System.Text; @@ -44,10 +45,9 @@ namespace MediaBrowser.Networking.HttpServer public string UrlPrefix { get; private set; } /// <summary> - /// Gets or sets the kernel. + /// The _rest services /// </summary> - /// <value>The kernel.</value> - private IKernel Kernel { get; set; } + private readonly List<IRestfulService> _restServices = new List<IRestfulService>(); /// <summary> /// Gets or sets the application host. @@ -88,19 +88,14 @@ namespace MediaBrowser.Networking.HttpServer /// Initializes a new instance of the <see cref="HttpServer" /> class. /// </summary> /// <param name="applicationHost">The application host.</param> - /// <param name="kernel">The kernel.</param> /// <param name="protobufSerializer">The protobuf serializer.</param> /// <param name="logger">The logger.</param> /// <param name="serverName">Name of the server.</param> /// <param name="defaultRedirectpath">The default redirectpath.</param> /// <exception cref="System.ArgumentNullException">urlPrefix</exception> - public HttpServer(IApplicationHost applicationHost, IKernel kernel, IProtobufSerializer protobufSerializer, ILogger logger, string serverName, string defaultRedirectpath) + public HttpServer(IApplicationHost applicationHost, IProtobufSerializer protobufSerializer, ILogger logger, string serverName, string defaultRedirectpath) : base() { - if (kernel == null) - { - throw new ArgumentNullException("kernel"); - } if (protobufSerializer == null) { throw new ArgumentNullException("protobufSerializer"); @@ -130,13 +125,6 @@ namespace MediaBrowser.Networking.HttpServer EndpointHostConfig.Instance.ServiceStackHandlerFactoryPath = null; EndpointHostConfig.Instance.MetadataRedirectPath = "metadata"; - - Kernel = kernel; - - EndpointHost.ConfigureHost(this, ServerName, CreateServiceManager()); - ContentTypeFilters.Register(ContentType.ProtoBuf, (reqCtx, res, stream) => ProtobufSerializer.SerializeToStream(res, stream), (type, stream) => ProtobufSerializer.DeserializeFromStream(stream, type)); - - Init(); } /// <summary> @@ -161,11 +149,6 @@ namespace MediaBrowser.Networking.HttpServer container.Adapter = new ContainerAdapter(ApplicationHost); - foreach (var service in Kernel.RestServices) - { - service.Configure(this); - } - Plugins.Add(new SwaggerFeature()); Plugins.Add(new CorsFeature()); @@ -450,7 +433,7 @@ namespace MediaBrowser.Networking.HttpServer /// <returns>ServiceManager.</returns> protected override ServiceManager CreateServiceManager(params Assembly[] assembliesWithServices) { - var types = Kernel.RestServices.Select(r => r.GetType()).ToArray(); + var types = _restServices.Select(r => r.GetType()).ToArray(); return new ServiceManager(new Container(), new ServiceController(() => types)); } @@ -511,6 +494,20 @@ namespace MediaBrowser.Networking.HttpServer /// </summary> /// <value><c>true</c> if [enable HTTP request logging]; otherwise, <c>false</c>.</value> public bool EnableHttpRequestLogging { get; set; } + + /// <summary> + /// Adds the rest handlers. + /// </summary> + /// <param name="services">The services.</param> + public void Init(IEnumerable<IRestfulService> services) + { + _restServices.AddRange(services); + + EndpointHost.ConfigureHost(this, ServerName, CreateServiceManager()); + ContentTypeFilters.Register(ContentType.ProtoBuf, (reqCtx, res, stream) => ProtobufSerializer.SerializeToStream(res, stream), (type, stream) => ProtobufSerializer.DeserializeFromStream(stream, type)); + + Init(); + } } /// <summary> diff --git a/MediaBrowser.Networking/HttpServer/ServerFactory.cs b/MediaBrowser.Networking/HttpServer/ServerFactory.cs index e853a6ec2..716fd450a 100644 --- a/MediaBrowser.Networking/HttpServer/ServerFactory.cs +++ b/MediaBrowser.Networking/HttpServer/ServerFactory.cs @@ -14,15 +14,14 @@ namespace MediaBrowser.Networking.HttpServer /// Creates the server. /// </summary> /// <param name="applicationHost">The application host.</param> - /// <param name="kernel">The kernel.</param> /// <param name="protobufSerializer">The protobuf serializer.</param> /// <param name="logger">The logger.</param> /// <param name="serverName">Name of the server.</param> /// <param name="defaultRedirectpath">The default redirectpath.</param> /// <returns>IHttpServer.</returns> - public static IHttpServer CreateServer(IApplicationHost applicationHost, IKernel kernel, IProtobufSerializer protobufSerializer, ILogger logger, string serverName, string defaultRedirectpath) + public static IHttpServer CreateServer(IApplicationHost applicationHost, IProtobufSerializer protobufSerializer, ILogger logger, string serverName, string defaultRedirectpath) { - return new HttpServer(applicationHost, kernel, protobufSerializer, logger, serverName, defaultRedirectpath); + return new HttpServer(applicationHost, protobufSerializer, logger, serverName, defaultRedirectpath); } } } diff --git a/MediaBrowser.Networking/MediaBrowser.Networking.csproj b/MediaBrowser.Networking/MediaBrowser.Networking.csproj index 7bb3fc930..3ef7832df 100644 --- a/MediaBrowser.Networking/MediaBrowser.Networking.csproj +++ b/MediaBrowser.Networking/MediaBrowser.Networking.csproj @@ -107,6 +107,7 @@ <Link>Properties\SharedVersion.cs</Link> </Compile> <Compile Include="HttpManager\HttpManager.cs" /> + <Compile Include="HttpServer\BaseRestService.cs" /> <Compile Include="Udp\UdpServer.cs" /> <Compile Include="WebSocket\AlchemyServer.cs" /> <Compile Include="WebSocket\AlchemyWebSocket.cs" /> diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 416a7d746..ec29ca4d3 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -51,6 +51,10 @@ <Link>Properties\SharedVersion.cs</Link> </Compile> <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Reflection\TypeMapper.cs" /> + <Compile Include="ScheduledTasks\Tasks\ChapterImagesTask.cs" /> + <Compile Include="ScheduledTasks\Tasks\ImageCleanupTask.cs" /> + <Compile Include="ScheduledTasks\Tasks\PluginUpdateTask.cs" /> <Compile Include="ServerApplicationPaths.cs" /> <Compile Include="Sqlite\SQLiteDisplayPreferencesRepository.cs" /> <Compile Include="Sqlite\SQLiteExtensions.cs" /> diff --git a/MediaBrowser.Controller/Persistence/TypeMapper.cs b/MediaBrowser.Server.Implementations/Reflection/TypeMapper.cs index 2b9ec9e5e..5f411a002 100644 --- a/MediaBrowser.Controller/Persistence/TypeMapper.cs +++ b/MediaBrowser.Server.Implementations/Reflection/TypeMapper.cs @@ -2,7 +2,7 @@ using System.Collections.Concurrent; using System.Linq; -namespace MediaBrowser.Controller.Persistence +namespace MediaBrowser.Server.Implementations.Reflection { /// <summary> /// Class TypeMapper diff --git a/MediaBrowser.Controller/ScheduledTasks/ChapterImagesTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs index 536033719..d3854f9d7 100644 --- a/MediaBrowser.Controller/ScheduledTasks/ChapterImagesTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Logging; using System; @@ -7,28 +8,38 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -namespace MediaBrowser.Controller.ScheduledTasks +namespace MediaBrowser.Server.Implementations.ScheduledTasks.Tasks { /// <summary> /// Class ChapterImagesTask /// </summary> - class ChapterImagesTask : BaseScheduledTask<Kernel> + class ChapterImagesTask : IScheduledTask { /// <summary> + /// The _kernel + /// </summary> + private readonly Kernel _kernel; + /// <summary> + /// The _logger + /// </summary> + private readonly ILogger _logger; + + /// <summary> /// Initializes a new instance of the <see cref="ChapterImagesTask" /> class. /// </summary> /// <param name="kernel">The kernel.</param> - /// <param name="logger"></param> - public ChapterImagesTask(Kernel kernel, ITaskManager taskManager, ILogger logger) - : base(kernel, taskManager, logger) + /// <param name="logger">The logger.</param> + public ChapterImagesTask(Kernel kernel, ILogger logger) { + _kernel = kernel; + _logger = logger; } /// <summary> /// Creates the triggers that define when the task will run /// </summary> /// <returns>IEnumerable{BaseTaskTrigger}.</returns> - public override IEnumerable<ITaskTrigger> GetDefaultTriggers() + public IEnumerable<ITaskTrigger> GetDefaultTriggers() { return new ITaskTrigger[] { @@ -42,9 +53,9 @@ namespace MediaBrowser.Controller.ScheduledTasks /// <param name="cancellationToken">The cancellation token.</param> /// <param name="progress">The progress.</param> /// <returns>Task.</returns> - protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress) + public Task Execute(CancellationToken cancellationToken, IProgress<double> progress) { - var videos = Kernel.RootFolder.RecursiveChildren.OfType<Video>().Where(v => v.Chapters != null).ToList(); + var videos = _kernel.RootFolder.RecursiveChildren.OfType<Video>().Where(v => v.Chapters != null).ToList(); var numComplete = 0; @@ -52,7 +63,7 @@ namespace MediaBrowser.Controller.ScheduledTasks { try { - await Kernel.FFMpegManager.PopulateChapterImages(v, cancellationToken, true, true); + await _kernel.FFMpegManager.PopulateChapterImages(v, cancellationToken, true, true); } catch (OperationCanceledException) { @@ -60,7 +71,7 @@ namespace MediaBrowser.Controller.ScheduledTasks } catch (Exception ex) { - Logger.ErrorException("Error creating chapter images for {0}", ex, v.Name); + _logger.ErrorException("Error creating chapter images for {0}", ex, v.Name); } finally { @@ -82,7 +93,7 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the name of the task /// </summary> /// <value>The name.</value> - public override string Name + public string Name { get { return "Create video chapter thumbnails"; } } @@ -91,7 +102,7 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the description. /// </summary> /// <value>The description.</value> - public override string Description + public string Description { get { return "Creates thumbnails for videos that have chapters."; } } @@ -100,7 +111,7 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the category. /// </summary> /// <value>The category.</value> - public override string Category + public string Category { get { diff --git a/MediaBrowser.Controller/ScheduledTasks/ImageCleanupTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/ImageCleanupTask.cs index 7e0094a67..57f69e2e3 100644 --- a/MediaBrowser.Controller/ScheduledTasks/ImageCleanupTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/ImageCleanupTask.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Model.Logging; @@ -9,29 +10,38 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -namespace MediaBrowser.Controller.ScheduledTasks +namespace MediaBrowser.Server.Implementations.ScheduledTasks.Tasks { /// <summary> /// Class ImageCleanupTask /// </summary> - public class ImageCleanupTask : BaseScheduledTask<Kernel> + public class ImageCleanupTask : IScheduledTask { /// <summary> + /// The _kernel + /// </summary> + private readonly Kernel _kernel; + /// <summary> + /// The _logger + /// </summary> + private readonly ILogger _logger; + + /// <summary> /// Initializes a new instance of the <see cref="ImageCleanupTask" /> class. /// </summary> /// <param name="kernel">The kernel.</param> - /// <param name="taskManager">The task manager.</param> /// <param name="logger">The logger.</param> - public ImageCleanupTask(Kernel kernel, ITaskManager taskManager, ILogger logger) - : base(kernel, taskManager, logger) + public ImageCleanupTask(Kernel kernel, ILogger logger) { + _kernel = kernel; + _logger = logger; } /// <summary> /// Creates the triggers that define when the task will run /// </summary> /// <returns>IEnumerable{BaseTaskTrigger}.</returns> - public override IEnumerable<ITaskTrigger> GetDefaultTriggers() + public IEnumerable<ITaskTrigger> GetDefaultTriggers() { return new ITaskTrigger[] { @@ -45,19 +55,19 @@ namespace MediaBrowser.Controller.ScheduledTasks /// <param name="cancellationToken">The cancellation token.</param> /// <param name="progress">The progress.</param> /// <returns>Task.</returns> - protected override async Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress) + public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress) { await EnsureChapterImages(cancellationToken).ConfigureAwait(false); // First gather all image files - var files = GetFiles(Kernel.FFMpegManager.AudioImagesDataPath) - .Concat(GetFiles(Kernel.FFMpegManager.VideoImagesDataPath)) - .Concat(GetFiles(Kernel.ProviderManager.ImagesDataPath)) + var files = GetFiles(_kernel.FFMpegManager.AudioImagesDataPath) + .Concat(GetFiles(_kernel.FFMpegManager.VideoImagesDataPath)) + .Concat(GetFiles(_kernel.ProviderManager.ImagesDataPath)) .ToList(); // Now gather all items - var items = Kernel.RootFolder.RecursiveChildren.ToList(); - items.Add(Kernel.RootFolder); + var items = _kernel.RootFolder.RecursiveChildren.ToList(); + items.Add(_kernel.RootFolder); // Determine all possible image paths var pathsInUse = items.SelectMany(GetPathsInUse) @@ -80,7 +90,7 @@ namespace MediaBrowser.Controller.ScheduledTasks } catch (IOException ex) { - Logger.ErrorException("Error deleting {0}", ex, file); + _logger.ErrorException("Error deleting {0}", ex, file); } } @@ -105,11 +115,11 @@ namespace MediaBrowser.Controller.ScheduledTasks /// <returns>Task.</returns> private Task EnsureChapterImages(CancellationToken cancellationToken) { - var videos = Kernel.RootFolder.RecursiveChildren.OfType<Video>().Where(v => v.Chapters != null).ToList(); + var videos = _kernel.RootFolder.RecursiveChildren.OfType<Video>().Where(v => v.Chapters != null).ToList(); var tasks = videos.Select(v => Task.Run(async () => { - await Kernel.FFMpegManager.PopulateChapterImages(v, cancellationToken, false, true); + await _kernel.FFMpegManager.PopulateChapterImages(v, cancellationToken, false, true); })); return Task.WhenAll(tasks); @@ -181,7 +191,7 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the name of the task /// </summary> /// <value>The name.</value> - public override string Name + public string Name { get { return "Images cleanup"; } } @@ -190,7 +200,7 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the description. /// </summary> /// <value>The description.</value> - public override string Description + public string Description { get { return "Deletes downloaded and extracted images that are no longer being used."; } } @@ -199,7 +209,7 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the category. /// </summary> /// <value>The category.</value> - public override string Category + public string Category { get { diff --git a/MediaBrowser.Controller/ScheduledTasks/PluginUpdateTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs index 7a1007f1b..01a045853 100644 --- a/MediaBrowser.Controller/ScheduledTasks/PluginUpdateTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs @@ -13,23 +13,33 @@ namespace MediaBrowser.Controller.ScheduledTasks /// <summary> /// Plugin Update Task /// </summary> - public class PluginUpdateTask : BaseScheduledTask<Kernel> + public class PluginUpdateTask : IScheduledTask { /// <summary> + /// The _kernel + /// </summary> + private readonly Kernel _kernel; + /// <summary> + /// The _logger + /// </summary> + private readonly ILogger _logger; + + /// <summary> /// Initializes a new instance of the <see cref="PluginUpdateTask" /> class. /// </summary> /// <param name="kernel">The kernel.</param> - /// <param name="logger"></param> - public PluginUpdateTask(Kernel kernel, ITaskManager taskManager, ILogger logger) - : base(kernel, taskManager, logger) + /// <param name="logger">The logger.</param> + public PluginUpdateTask(Kernel kernel, ILogger logger) { + _kernel = kernel; + _logger = logger; } /// <summary> /// Creates the triggers that define when the task will run /// </summary> /// <returns>IEnumerable{BaseTaskTrigger}.</returns> - public override IEnumerable<ITaskTrigger> GetDefaultTriggers() + public IEnumerable<ITaskTrigger> GetDefaultTriggers() { return new ITaskTrigger[] { @@ -46,11 +56,11 @@ namespace MediaBrowser.Controller.ScheduledTasks /// <param name="cancellationToken">The cancellation token.</param> /// <param name="progress">The progress.</param> /// <returns>Task.</returns> - protected override async Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress) + public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress) { progress.Report(0); - var packagesToInstall = (await Kernel.InstallationManager.GetAvailablePluginUpdates(true, cancellationToken).ConfigureAwait(false)).ToList(); + var packagesToInstall = (await _kernel.InstallationManager.GetAvailablePluginUpdates(true, cancellationToken).ConfigureAwait(false)).ToList(); progress.Report(10); @@ -63,7 +73,7 @@ namespace MediaBrowser.Controller.ScheduledTasks try { - await Kernel.InstallationManager.InstallPackage(i, new Progress<double> { }, cancellationToken).ConfigureAwait(false); + await _kernel.InstallationManager.InstallPackage(i, new Progress<double> { }, cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { @@ -75,11 +85,11 @@ namespace MediaBrowser.Controller.ScheduledTasks } catch (HttpException ex) { - Logger.ErrorException("Error downloading {0}", ex, i.name); + _logger.ErrorException("Error downloading {0}", ex, i.name); } catch (IOException ex) { - Logger.ErrorException("Error updating {0}", ex, i.name); + _logger.ErrorException("Error updating {0}", ex, i.name); } // Update progress @@ -104,7 +114,7 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the name of the task /// </summary> /// <value>The name.</value> - public override string Name + public string Name { get { return "Check for plugin updates"; } } @@ -113,9 +123,14 @@ namespace MediaBrowser.Controller.ScheduledTasks /// Gets the description. /// </summary> /// <value>The description.</value> - public override string Description + public string Description { get { return "Downloads and installs updates for plugins that are configured to update automatically."; } } + + public string Category + { + get { return "Application"; } + } } }
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Sqlite/SQLiteItemRepository.cs b/MediaBrowser.Server.Implementations/Sqlite/SQLiteItemRepository.cs index 034cd2188..24de081f9 100644 --- a/MediaBrowser.Server.Implementations/Sqlite/SQLiteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Sqlite/SQLiteItemRepository.cs @@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; +using MediaBrowser.Server.Implementations.Reflection; using System; using System.Collections.Generic; using System.Data; diff --git a/MediaBrowser.ServerApplication/App.xaml.cs b/MediaBrowser.ServerApplication/App.xaml.cs index 5808120ad..f6f70b382 100644 --- a/MediaBrowser.ServerApplication/App.xaml.cs +++ b/MediaBrowser.ServerApplication/App.xaml.cs @@ -1,8 +1,6 @@ using MediaBrowser.ClickOnce; -using MediaBrowser.Common.Implementations.Serialization; using MediaBrowser.Common.Kernel; using MediaBrowser.Controller; -using MediaBrowser.Logging.Nlog; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Uninstall; using Microsoft.Win32; @@ -30,7 +28,7 @@ namespace MediaBrowser.ServerApplication [STAThread] public static void Main() { - var application = new App(new NLogger("App")); + var application = new App(); application.Run(); } @@ -74,10 +72,8 @@ namespace MediaBrowser.ServerApplication /// Initializes a new instance of the <see cref="App" /> class. /// </summary> /// <param name="logger">The logger.</param> - public App(ILogger logger) + public App() { - Logger = logger; - InitializeComponent(); } @@ -174,13 +170,16 @@ namespace MediaBrowser.ServerApplication /// </summary> protected async void LoadKernel() { - CompositionRoot = new ApplicationHost(Logger); + CompositionRoot = new ApplicationHost(); + Logger = CompositionRoot.Logger; Kernel = CompositionRoot.Kernel; try { - new MainWindow(new JsonSerializer(), Logger).Show(); + var win = (MainWindow)CompositionRoot.CreateInstance(typeof(MainWindow)); + + win.Show(); var now = DateTime.UtcNow; diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index 5a98e7d93..e862a394e 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -1,5 +1,6 @@ using BDInfo; using MediaBrowser.ClickOnce; +using MediaBrowser.Common.Implementations; using MediaBrowser.Common.Implementations.ScheduledTasks; using MediaBrowser.Common.Implementations.Serialization; using MediaBrowser.Common.IO; @@ -10,7 +11,6 @@ using MediaBrowser.Controller; using MediaBrowser.IsoMounter; using MediaBrowser.Logging.Nlog; using MediaBrowser.Model.IO; -using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.System; @@ -22,7 +22,6 @@ using MediaBrowser.Networking.Udp; using MediaBrowser.Networking.WebSocket; using MediaBrowser.Server.Implementations; using MediaBrowser.ServerApplication.Implementations; -using SimpleInjector; using System; using System.Collections.Generic; using System.Diagnostics; @@ -37,56 +36,19 @@ namespace MediaBrowser.ServerApplication /// <summary> /// Class CompositionRoot /// </summary> - public class ApplicationHost : IApplicationHost, IDisposable + public class ApplicationHost : BaseApplicationHost, IApplicationHost { /// <summary> - /// Gets or sets the logger. - /// </summary> - /// <value>The logger.</value> - private ILogger Logger { get; set; } - - /// <summary> /// Gets or sets the log file path. /// </summary> /// <value>The log file path.</value> public string LogFilePath { get; private set; } /// <summary> - /// The container - /// </summary> - private readonly Container _container = new Container(); - - /// <summary> /// Gets or sets the kernel. /// </summary> /// <value>The kernel.</value> - public Kernel Kernel { get; private set; } - - private readonly List<string> _failedAssemblies = new List<string>(); - /// <summary> - /// Gets assemblies that failed to load - /// </summary> - public IEnumerable<string> FailedAssemblies - { - get { return _failedAssemblies; } - } - - /// <summary> - /// Gets all types within all running assemblies - /// </summary> - /// <value>All types.</value> - public Type[] AllTypes { get; private set; } - - /// <summary> - /// Gets all concrete types. - /// </summary> - /// <value>All concrete types.</value> - public Type[] AllConcreteTypes { get; private set; } - - /// <summary> - /// The disposable parts - /// </summary> - private readonly List<IDisposable> _disposableParts = new List<IDisposable>(); + internal Kernel Kernel { get; private set; } /// <summary> /// The json serializer @@ -107,20 +69,40 @@ namespace MediaBrowser.ServerApplication /// The _task manager /// </summary> private readonly ITaskManager _taskManager; - + + /// <summary> + /// The _task manager + /// </summary> + private readonly IHttpServer _httpServer; + + /// <summary> + /// Gets a value indicating whether this instance is first run. + /// </summary> + /// <value><c>true</c> if this instance is first run; otherwise, <c>false</c>.</value> + public bool IsFirstRun { get; private set; } + /// <summary> /// Initializes a new instance of the <see cref="ApplicationHost" /> class. /// </summary> /// <param name="logger">The logger.</param> - public ApplicationHost(ILogger logger) + public ApplicationHost() + : base() { - Logger = logger; + IsFirstRun = !File.Exists(_applicationPaths.SystemConfigurationFilePath); + + Logger = new NLogger("App"); + + DiscoverTypes(); _taskManager = new TaskManager(_applicationPaths, _jsonSerializer, Logger); Kernel = new Kernel(this, _applicationPaths, _xmlSerializer, _taskManager, Logger); ReloadLogger(); + Logger.Info("Version {0} initializing", ApplicationVersion); + + _httpServer = ServerFactory.CreateServer(this, ProtobufSerializer, Logger, "Media Browser", "index.html"); + RegisterResources(); FindParts(); @@ -129,42 +111,28 @@ namespace MediaBrowser.ServerApplication /// <summary> /// Registers resources that classes will depend on /// </summary> - internal void RegisterResources() + private void RegisterResources() { - DiscoverTypes(); - RegisterSingleInstance<IKernel>(Kernel); RegisterSingleInstance(Kernel); - + RegisterSingleInstance<IApplicationHost>(this); RegisterSingleInstance(Logger); RegisterSingleInstance(_applicationPaths); RegisterSingleInstance<IApplicationPaths>(_applicationPaths); RegisterSingleInstance(_taskManager); - RegisterSingleInstance<IIsoManager>(() => new PismoIsoManager(Logger)); - RegisterSingleInstance<IBlurayExaminer>(() => new BdInfoExaminer()); - RegisterSingleInstance<IHttpClient>(() => new HttpManager(_applicationPaths, Logger)); - RegisterSingleInstance<INetworkManager>(() => new NetworkManager()); - RegisterSingleInstance<IZipClient>(() => new DotNetZipClient()); + RegisterSingleInstance<IIsoManager>(new PismoIsoManager(Logger)); + RegisterSingleInstance<IBlurayExaminer>(new BdInfoExaminer()); + RegisterSingleInstance<IHttpClient>(new HttpManager(_applicationPaths, Logger)); + RegisterSingleInstance<INetworkManager>(new NetworkManager()); + RegisterSingleInstance<IZipClient>(new DotNetZipClient()); RegisterSingleInstance<IWebSocketServer>(() => new AlchemyServer(Logger)); RegisterSingleInstance(_jsonSerializer); RegisterSingleInstance(_xmlSerializer); - RegisterSingleInstance<IProtobufSerializer>(() => ProtobufSerializer); - Register(typeof(IUdpServer), typeof(UdpServer)); - RegisterSingleInstance(() => ServerFactory.CreateServer(this, Kernel, ProtobufSerializer, Logger, "Media Browser", "index.html")); - } - - /// <summary> - /// Discovers the types. - /// </summary> - private void DiscoverTypes() - { - _failedAssemblies.Clear(); - - AllTypes = GetComposablePartAssemblies().SelectMany(GetTypes).ToArray(); - - AllConcreteTypes = AllTypes.Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType).ToArray(); + RegisterSingleInstance(ProtobufSerializer); + RegisterSingleInstance<IUdpServer>(new UdpServer()); + RegisterSingleInstance(_httpServer); } /// <summary> @@ -173,150 +141,8 @@ namespace MediaBrowser.ServerApplication private void FindParts() { _taskManager.AddTasks(GetExports<IScheduledTask>(false)); - } - - /// <summary> - /// Gets a list of types within an assembly - /// This will handle situations that would normally throw an exception - such as a type within the assembly that depends on some other non-existant reference - /// </summary> - /// <param name="assembly">The assembly.</param> - /// <returns>IEnumerable{Type}.</returns> - /// <exception cref="System.ArgumentNullException">assembly</exception> - private IEnumerable<Type> GetTypes(Assembly assembly) - { - if (assembly == null) - { - throw new ArgumentNullException("assembly"); - } - - try - { - return assembly.GetTypes(); - } - catch (ReflectionTypeLoadException ex) - { - // If it fails we can still get a list of the Types it was able to resolve - return ex.Types.Where(t => t != null); - } - } - - /// <summary> - /// The _protobuf serializer initialized - /// </summary> - private bool _protobufSerializerInitialized; - /// <summary> - /// The _protobuf serializer sync lock - /// </summary> - private object _protobufSerializerSyncLock = new object(); - /// <summary> - /// Gets a dynamically compiled generated serializer that can serialize protocontracts without reflection - /// </summary> - private ProtobufSerializer _protobufSerializer; - /// <summary> - /// Gets the protobuf serializer. - /// </summary> - /// <value>The protobuf serializer.</value> - public ProtobufSerializer ProtobufSerializer - { - get - { - // Lazy load - LazyInitializer.EnsureInitialized(ref _protobufSerializer, ref _protobufSerializerInitialized, ref _protobufSerializerSyncLock, () => ProtobufSerializer.Create(AllTypes)); - return _protobufSerializer; - } - private set - { - _protobufSerializer = value; - _protobufSerializerInitialized = value != null; - } - } - - /// <summary> - /// Creates an instance of type and resolves all constructor dependancies - /// </summary> - /// <param name="type">The type.</param> - /// <returns>System.Object.</returns> - public object CreateInstance(Type type) - { - try - { - return _container.GetInstance(type); - } - catch - { - Logger.Error("Error creating {0}", type.Name); - throw; - } - } - - /// <summary> - /// Registers the specified obj. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <param name="obj">The obj.</param> - public void RegisterSingleInstance<T>(T obj) - where T : class - { - _container.RegisterSingle(obj); - } - - /// <summary> - /// Registers the specified func. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <param name="func">The func.</param> - public void Register<T>(Func<T> func) - where T : class - { - _container.Register(func); - } - - /// <summary> - /// Registers the single instance. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <param name="func">The func.</param> - public void RegisterSingleInstance<T>(Func<T> func) - where T : class - { - _container.RegisterSingle(func); - } - - /// <summary> - /// Resolves this instance. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <returns>``0.</returns> - public T Resolve<T>() - { - return (T)_container.GetRegistration(typeof(T), true).GetInstance(); - } - - /// <summary> - /// Resolves this instance. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <returns>``0.</returns> - public T TryResolve<T>() - { - var result = _container.GetRegistration(typeof(T), false); - - if (result == null) - { - return default(T); - } - return (T)result.GetInstance(); - } - - /// <summary> - /// Registers the specified service type. - /// </summary> - /// <param name="serviceType">Type of the service.</param> - /// <param name="implementation">Type of the concrete.</param> - public void Register(Type serviceType, Type implementation) - { - _container.Register(serviceType, implementation); + _httpServer.Init(GetExports<IRestfulService>(false)); } /// <summary> @@ -374,12 +200,12 @@ namespace MediaBrowser.ServerApplication /// Gets the composable part assemblies. /// </summary> /// <returns>IEnumerable{Assembly}.</returns> - private IEnumerable<Assembly> GetComposablePartAssemblies() + protected override IEnumerable<Assembly> GetComposablePartAssemblies() { // Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that // This will prevent the .dll file from getting locked, and allow us to replace it when needed foreach (var pluginAssembly in Directory - .EnumerateFiles(Kernel.ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly) + .EnumerateFiles(_applicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly) .Select(LoadAssembly).Where(a => a != null)) { yield return pluginAssembly; @@ -410,73 +236,9 @@ namespace MediaBrowser.ServerApplication // Server implementations yield return typeof(ServerApplicationPaths).Assembly; - + // Include composable parts in the running assembly yield return GetType().Assembly; } - - /// <summary> - /// Loads the assembly. - /// </summary> - /// <param name="file">The file.</param> - /// <returns>Assembly.</returns> - private Assembly LoadAssembly(string file) - { - try - { - return Assembly.Load(File.ReadAllBytes((file))); - } - catch (Exception ex) - { - _failedAssemblies.Add(file); - Logger.ErrorException("Error loading assembly {0}", ex, file); - return null; - } - } - - /// <summary> - /// Gets the exports. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <param name="allTypes">All types.</param> - /// <param name="manageLiftime">if set to <c>true</c> [manage liftime].</param> - /// <returns>IEnumerable{``0}.</returns> - public IEnumerable<T> GetExports<T>(bool manageLiftime = true) - { - var currentType = typeof(T); - - Logger.Info("Composing instances of " + currentType.Name); - - var parts = AllConcreteTypes.Where(currentType.IsAssignableFrom).Select(CreateInstance).Cast<T>().ToArray(); - - if (manageLiftime) - { - _disposableParts.AddRange(parts.OfType<IDisposable>()); - } - - return parts; - } - - /// <summary> - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// </summary> - public void Dispose() - { - Dispose(true); - } - - /// <summary> - /// Releases unmanaged and - optionally - managed resources. - /// </summary> - /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> - protected virtual void Dispose(bool dispose) - { - foreach (var part in _disposableParts) - { - part.Dispose(); - } - - _disposableParts.Clear(); - } } } diff --git a/MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs b/MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs index 59961a941..cb5c62ff0 100644 --- a/MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs +++ b/MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller; +using MediaBrowser.Common.Kernel; +using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; @@ -38,13 +39,13 @@ namespace MediaBrowser.ServerApplication /// <summary> /// Initializes a new instance of the <see cref="LibraryExplorer" /> class. /// </summary> - public LibraryExplorer(IJsonSerializer jsonSerializer, ILogger logger) + public LibraryExplorer(IJsonSerializer jsonSerializer, ILogger logger, IApplicationHost appHost) { _logger = logger; _jsonSerializer = jsonSerializer; InitializeComponent(); - lblVersion.Content = "Version: " + Kernel.Instance.ApplicationVersion; + lblVersion.Content = "Version: " + appHost.ApplicationVersion; foreach (var user in Kernel.Instance.Users) ddlProfile.Items.Add(user); ddlProfile.Items.Insert(0,new User {Name = "Physical"}); diff --git a/MediaBrowser.ServerApplication/MainWindow.xaml.cs b/MediaBrowser.ServerApplication/MainWindow.xaml.cs index 332bb1daa..fc0f0efc9 100644 --- a/MediaBrowser.ServerApplication/MainWindow.xaml.cs +++ b/MediaBrowser.ServerApplication/MainWindow.xaml.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller; +using MediaBrowser.Common.Kernel; +using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; @@ -50,11 +51,18 @@ namespace MediaBrowser.ServerApplication private readonly ILogger _logger; /// <summary> + /// The _app host + /// </summary> + private readonly IApplicationHost _appHost; + + /// <summary> /// Initializes a new instance of the <see cref="MainWindow" /> class. /// </summary> + /// <param name="jsonSerializer">The json serializer.</param> /// <param name="logger">The logger.</param> + /// <param name="appHost">The app host.</param> /// <exception cref="System.ArgumentNullException">logger</exception> - public MainWindow(IJsonSerializer jsonSerializer, ILogger logger) + public MainWindow(IJsonSerializer jsonSerializer, ILogger logger, IApplicationHost appHost) { if (jsonSerializer == null) { @@ -67,6 +75,7 @@ namespace MediaBrowser.ServerApplication _jsonSerializer = jsonSerializer; _logger = logger; + _appHost = appHost; InitializeComponent(); @@ -236,7 +245,7 @@ namespace MediaBrowser.ServerApplication Kernel.Instance.LibraryManager.LibraryChanged -= Instance_LibraryChanged; Kernel.Instance.LibraryManager.LibraryChanged += Instance_LibraryChanged; - if (Kernel.Instance.IsFirstRun) + if (_appHost.IsFirstRun) { LaunchStartupWizard(); } @@ -293,7 +302,7 @@ namespace MediaBrowser.ServerApplication /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> private void cmOpenExplorer_click(object sender, RoutedEventArgs e) { - (new LibraryExplorer(_jsonSerializer, _logger)).Show(); + (new LibraryExplorer(_jsonSerializer, _logger, _appHost)).Show(); } /// <summary> diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index c843242c3..50cb0be6c 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -128,6 +128,18 @@ <SpecificVersion>False</SpecificVersion> <HintPath>..\ThirdParty\UPnP\Libs\Platinum.Managed.dll</HintPath> </Reference> + <Reference Include="ServiceStack.Common, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Common.dll</HintPath> + </Reference> + <Reference Include="ServiceStack.Interfaces, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Interfaces.dll</HintPath> + </Reference> + <Reference Include="ServiceStack.Text, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\packages\ServiceStack.Text.3.9.37\lib\net35\ServiceStack.Text.dll</HintPath> + </Reference> <Reference Include="SimpleInjector, Version=2.0.0.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>..\packages\SimpleInjector.2.0.0-beta5\lib\net40-client\SimpleInjector.dll</HintPath> diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index e1beae6da..71e2844fc 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -3,6 +3,8 @@ <package id="DotNetZip" version="1.9.1.8" targetFramework="net45" /> <package id="Hardcodet.Wpf.TaskbarNotification" version="1.0.4.0" targetFramework="net45" /> <package id="NLog" version="2.0.0.2000" targetFramework="net45" /> + <package id="ServiceStack.Common" version="3.9.37" targetFramework="net45" /> + <package id="ServiceStack.Text" version="3.9.37" targetFramework="net45" /> <package id="SimpleInjector" version="2.0.0-beta5" targetFramework="net45" /> <package id="System.Data.SQLite" version="1.0.84.0" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index b321cc8d9..94cc37b31 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -6,8 +6,8 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Tasks; +using MediaBrowser.Networking.HttpServer; using ServiceStack.ServiceHost; -using ServiceStack.WebHost.Endpoints; using System; using System.Collections.Generic; using System.ComponentModel.Composition; @@ -49,6 +49,7 @@ namespace MediaBrowser.WebDashboard.Api /// <summary> /// Class GetDashboardResource /// </summary> + [Route("/dashboard/{name*}", "GET")] public class GetDashboardResource { /// <summary> @@ -91,17 +92,6 @@ namespace MediaBrowser.WebDashboard.Api { _taskManager = taskManager; } - - /// <summary> - /// Adds the routes. - /// </summary> - /// <param name="appHost">The app host.</param> - public override void Configure(IAppHost appHost) - { - base.Configure(appHost); - - appHost.Routes.Add<GetDashboardResource>("/dashboard/{name*}", "GET"); - } /// <summary> /// Gets the specified request. @@ -136,7 +126,7 @@ namespace MediaBrowser.WebDashboard.Api .Select(ScheduledTaskHelpers.GetTaskInfo) .ToArray(), - ApplicationUpdateTaskId = taskManager.ScheduledTasks.First(t => t.GetType().Name.Equals("SystemUpdateTask", StringComparison.OrdinalIgnoreCase)).Id, + ApplicationUpdateTaskId = taskManager.ScheduledTasks.First(t => t.ScheduledTask.GetType().Name.Equals("SystemUpdateTask", StringComparison.OrdinalIgnoreCase)).Id, ActiveConnections = connections, @@ -370,7 +360,7 @@ namespace MediaBrowser.WebDashboard.Api var files = new[] { - "http://code.jquery.com/mobile/1.3.0-rc.1/jquery.mobile-1.3.0-rc.1.min.css", + "http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.css", "thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.css", "css/site.css" + versionString }; @@ -391,7 +381,7 @@ namespace MediaBrowser.WebDashboard.Api var files = new[] { "http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js", - "http://code.jquery.com/mobile/1.3.0-rc.1/jquery.mobile-1.3.0-rc.1.min.js", + "http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.js", "../jsapiclient.js" + versionString, "scripts/all.js" + versionString }; diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 85efe04f1..a65a2afeb 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -99,6 +99,10 @@ <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
<Name>MediaBrowser.Model</Name>
</ProjectReference>
+ <ProjectReference Include="..\MediaBrowser.Networking\MediaBrowser.Networking.csproj">
+ <Project>{7c11010e-179a-49b7-bfb2-f1656f5e71ad}</Project>
+ <Name>MediaBrowser.Networking</Name>
+ </ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Html\index.html" />
diff --git a/Nuget/MediaBrowser.ApiClient.nuspec b/Nuget/MediaBrowser.ApiClient.nuspec index 38f51a5cb..3d6ec3a31 100644 --- a/Nuget/MediaBrowser.ApiClient.nuspec +++ b/Nuget/MediaBrowser.ApiClient.nuspec @@ -11,14 +11,12 @@ <copyright>Copyright © Media Browser 2013</copyright> <dependencies> <group targetFramework=".NETFramework4.5"> - <dependency id="ServiceStack.Text" version="3.9.37" /> - <dependency id="protobuf-net" version="2.0.0.621" /> + <dependency id="Newtonsoft.Json" version="4.5.11" /> </group> <group targetFramework=".NETPortable0.0-net45+sl4+wp71+win8"> <dependency id="Newtonsoft.Json" version="4.5.11" /> <dependency id="Microsoft.Bcl.Async" version="1.0.14-rc" /> <dependency id="Microsoft.Net.Http" version="2.1.3-beta" /> - <dependency id="protobuf-net" version="2.0.0.621" /> </group> </dependencies> </metadata> |
